Reduce XSS false positives for safe URL helpers and model IDs
Skip XSS detection for: - Safe URL helpers: route(), url(), asset(), secure_asset(), secure_url(), static_url(), action(), mix(), vite() - Null coalesce with safe helpers: $var ?? url(...) - Model ID patterns: $model->id (typically safe integers) These patterns are unlikely to be user-controllable and create noise that obscures real vulnerabilities. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -257,8 +257,22 @@ class XssRule extends BaseRule
|
||||
$attrName = strtolower($urlMatches[1][$i][0]);
|
||||
$expression = trim($match[0]);
|
||||
|
||||
// Skip if it's clearly a route or URL helper
|
||||
if (preg_match('/^\s*(route|url|asset|secure_asset|action)\s*\(/', $expression)) {
|
||||
// Skip if it's clearly a safe URL helper (route, url, asset, etc.)
|
||||
// These generate URLs from application config, not user input
|
||||
if (preg_match('/^\s*(route|url|asset|secure_asset|secure_url|static_url|action|mix|vite)\s*\(/', $expression)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip if expression uses null coalesce with safe helpers
|
||||
if (preg_match('/\?\?\s*(route|url|asset|secure_asset|secure_url|static_url|action|mix|vite)\s*\(/', $expression)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip if expression only contains model ID access patterns (e.g., $model->id)
|
||||
// These are typically safe integers from the database
|
||||
if (preg_match('/^[\s\w\$\-\>\.\'\"\/\(\),]+$/', $expression) &&
|
||||
preg_match('/\$\w+->id\b/', $expression) &&
|
||||
!preg_match('/\$_(GET|POST|REQUEST|COOKIE|SERVER)/', $expression)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -285,11 +299,32 @@ class XssRule extends BaseRule
|
||||
$eventMatches = [1 => array_merge($eventMatchesDouble[1], $eventMatchesSingle[1])];
|
||||
|
||||
foreach ($eventMatches[1] as $match) {
|
||||
$expression = trim($match[0]);
|
||||
|
||||
// Skip if it's clearly a safe URL helper (route, url, asset, etc.)
|
||||
// These generate URLs from application config, not user input
|
||||
if (preg_match('/^\s*(route|url|asset|secure_asset|secure_url|static_url|action|mix|vite)\s*\(/', $expression)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip if expression uses null coalesce with safe helpers
|
||||
if (preg_match('/\?\?\s*(route|url|asset|secure_asset|secure_url|static_url|action|mix|vite)\s*\(/', $expression)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip if expression only contains model ID access patterns (e.g., $model->id)
|
||||
// These are typically safe integers from the database
|
||||
if (preg_match('/^[\s\w\$\-\>\.\'\"\/\(\),]+$/', $expression) &&
|
||||
preg_match('/\$\w+->id\b/', $expression) &&
|
||||
!preg_match('/\$_(GET|POST|REQUEST|COOKIE|SERVER)/', $expression)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$line = $this->getLineFromOffset($content, $match[1]);
|
||||
$vulnerabilities[] = $this->createVulnerability(
|
||||
'XSS',
|
||||
Vulnerability::SEVERITY_HIGH,
|
||||
$this->msg('xss.event_handler', ['expr' => trim($match[0])]),
|
||||
$this->msg('xss.event_handler', ['expr' => $expression]),
|
||||
$filePath,
|
||||
$line,
|
||||
null,
|
||||
|
||||
Reference in New Issue
Block a user