Simplify XSS safe pattern: check for e() anywhere in expression
Instead of checking for specific patterns like nl2br(e($var)),
now checks if e(), htmlspecialchars(), or htmlentities() appears
anywhere in the expression.
This covers more use cases:
- {!! e($var) !!}
- {!! nl2br(e($var)) !!}
- {!! wordwrap(e($var), 80) !!}
- {!! str_replace('x', 'y', e($var)) !!}
Still flags expressions with escape-breaking functions:
- {!! html_entity_decode(e($var)) !!} -> flagged
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -493,13 +493,25 @@ class XssRule extends BaseRule
|
||||
'/^\s*action\s*\(/', // action() helper
|
||||
'/^\s*mix\s*\(/', // mix() helper (Laravel Mix)
|
||||
'/^\s*vite\s*\(/', // vite() helper (Vite)
|
||||
// nl2br with e() - common safe pattern for displaying user text with line breaks
|
||||
// e() escapes HTML first, then nl2br() adds <br> tags
|
||||
'/^\s*nl2br\s*\(\s*e\s*\(/', // nl2br(e($var))
|
||||
'/^\s*nl2br\s*\(\s*htmlspecialchars\s*\(/', // nl2br(htmlspecialchars($var))
|
||||
'/^\s*nl2br\s*\(\s*htmlentities\s*\(/', // nl2br(htmlentities($var))
|
||||
];
|
||||
|
||||
// Check if expression contains escape functions (e, htmlspecialchars, htmlentities)
|
||||
// If escaped and no escape-breaking functions, it's safe
|
||||
if (preg_match('/\b(e|htmlspecialchars|htmlentities)\s*\(/', $expression)) {
|
||||
// Make sure no escape-breaking functions are used
|
||||
$escapeBreakers = ['html_entity_decode', 'htmlspecialchars_decode', 'urldecode', 'rawurldecode'];
|
||||
$hasEscapeBreaker = false;
|
||||
foreach ($escapeBreakers as $breaker) {
|
||||
if (stripos($expression, $breaker) !== false) {
|
||||
$hasEscapeBreaker = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$hasEscapeBreaker) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($safePatterns as $pattern) {
|
||||
if (preg_match($pattern, $expression)) {
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user