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*action\s*\(/', // action() helper
|
||||||
'/^\s*mix\s*\(/', // mix() helper (Laravel Mix)
|
'/^\s*mix\s*\(/', // mix() helper (Laravel Mix)
|
||||||
'/^\s*vite\s*\(/', // vite() helper (Vite)
|
'/^\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) {
|
foreach ($safePatterns as $pattern) {
|
||||||
if (preg_match($pattern, $expression)) {
|
if (preg_match($pattern, $expression)) {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user