mirror of
https://github.com/getgrav/grav.git
synced 2026-07-08 18:01:45 +02:00
Added Utils::detectXssFromArray() and Utils::detectXss() methods
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
1. [](#new)
|
||||
* Added `Deprecated` tab to DebugBar to catch future incompatibilities with later Grav versions
|
||||
* Added deprecation notices for features which will be removed in Grav 2.0
|
||||
* Added `Utils::detectXssFromArray()` and `Utils::detectXss()` methods
|
||||
1. [](#bugfix)
|
||||
* Allow `$page->slug()` to be called before `$page->init()` without breaking the page
|
||||
* Fix for `Page::translatedLanguages()` to use routes always [#2163](https://github.com/getgrav/grav/issues/2163)
|
||||
|
||||
@@ -253,6 +253,90 @@ abstract class Utils
|
||||
return $date_formats;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $array Array such as $_POST or $_GET
|
||||
* @param string $prefix Prefix for returned values.
|
||||
* @return array Returns flatten list of potentially dangerous input values, such as 'data.content'.
|
||||
*/
|
||||
public static function detectXssFromArray(array $array, $prefix = '')
|
||||
{
|
||||
$list = [];
|
||||
|
||||
foreach ($array as $key => $value) {
|
||||
if (\is_array($value)) {
|
||||
$list[] = static::detectXssFromArray($value, $prefix . $key . '.');
|
||||
}
|
||||
if (static::detectXss($value)) {
|
||||
$list[] = [$prefix . $key];
|
||||
}
|
||||
}
|
||||
|
||||
return array_merge(...$list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if string potentially has a XSS attack. This simple function does not catch all XSS and it is likely to
|
||||
* return false positives because of it tags all potentially dangerous HTML tags and attributes without looking into
|
||||
* their content.
|
||||
*
|
||||
* @param string $string The string to run XSS detection logic on
|
||||
* @return boolean True if the given `$string` may contain XSS, false otherwise.
|
||||
*
|
||||
* Copies the code from: https://github.com/symphonycms/xssfilter/blob/master/extension.driver.php#L138
|
||||
*/
|
||||
public static function detectXss($string)
|
||||
{
|
||||
// Skip any null or non string values
|
||||
if (null === $string || !\is_string($string) || empty($string)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Keep a copy of the original string before cleaning up
|
||||
$orig = $string;
|
||||
|
||||
// URL decode
|
||||
$string = urldecode($string);
|
||||
|
||||
// Convert Hexadecimals
|
||||
$string = (string)preg_replace_callback('!(&#|\\\)[xX]([0-9a-fA-F]+);?!u', function($m) {
|
||||
return \chr(hexdec($m[2]));
|
||||
}, $string);
|
||||
|
||||
// Clean up entities
|
||||
$string = preg_replace('!(�+[0-9]+)!u','$1;', $string);
|
||||
|
||||
// Decode entities
|
||||
$string = html_entity_decode($string, ENT_NOQUOTES, 'UTF-8');
|
||||
|
||||
// Strip whitespace characters
|
||||
$string = preg_replace('!\s!u','', $string);
|
||||
|
||||
// Set the patterns we'll test against
|
||||
$patterns = [
|
||||
// Match any attribute starting with "on" or xmlns
|
||||
'#(<[^>]+[\x00-\x20\"\'\/])(on|xmlns)[^>]*>?#iUu',
|
||||
|
||||
// Match javascript:, livescript:, vbscript:, mocha:, feed: and data: protocols
|
||||
'!((java|live|vb)script|mocha|feed|data):(\w)*!iUu',
|
||||
|
||||
// Match -moz-bindings
|
||||
'#-moz-binding[\x00-\x20]*:#u',
|
||||
|
||||
// Match style attributes
|
||||
'#(<[^>]+[\x00-\x20\"\'\/])style=[^>]*>?#iUu',
|
||||
|
||||
// Match potentially dangerous tags
|
||||
'#</*(applet|meta|xml|blink|link|style|script|embed|object|iframe|frame|frameset|ilayer|layer|bgsound|title|base)[^>]*>?#ui'
|
||||
];
|
||||
|
||||
foreach ($patterns as $pattern) {
|
||||
// Test both the original string and clean string
|
||||
if (preg_match($pattern, $string) || preg_match($pattern, $orig)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Truncate text by number of characters but can cut off words.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user