diff options
Diffstat (limited to 'system/core/Security.php')
-rw-r--r-- | system/core/Security.php | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/system/core/Security.php b/system/core/Security.php index 49e5ab411..cbff38b30 100644 --- a/system/core/Security.php +++ b/system/core/Security.php @@ -433,6 +433,12 @@ class CI_Security { * We used to do some version comparisons and use of stripos for PHP5, * but it is dog slow compared to these simplified non-capturing * preg_match(), especially if the pattern exists in the string + * + * Note: It was reported that not only space characters, but all in + * the following pattern can be parsed as separators between a tag name + * and its attributes: [\d\s"\'`;,\/\=\(\x00\x0B\x09\x0C] + * ... however, remove_invisible_characters() above already strips the + * hex-encoded ones, so we'll skip them below. */ do { @@ -440,12 +446,12 @@ class CI_Security { if (preg_match('/<a/i', $str)) { - $str = preg_replace_callback('#<a\s+([^>]*?)(?:>|$)#si', array($this, '_js_link_removal'), $str); + $str = preg_replace_callback('#<a[\s\d"\'`;/=,\(]+([^>]*?)(?:>|$)#si', array($this, '_js_link_removal'), $str); } if (preg_match('/<img/i', $str)) { - $str = preg_replace_callback('#<img\s+([^>]*?)(?:\s?/?>|$)#si', array($this, '_js_img_removal'), $str); + $str = preg_replace_callback('#<img[\s\d"\'`;/=,\(]+([^>]*?)(?:\s?/?>|$)#si', array($this, '_js_img_removal'), $str); } if (preg_match('/script|xss/i', $str)) @@ -469,7 +475,7 @@ class CI_Security { * So this: <blink> * Becomes: <blink> */ - $naughty = 'alert|applet|audio|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|button|select|isindex|layer|link|meta|keygen|object|plaintext|style|script|textarea|title|video|svg|xml|xss'; + $naughty = 'alert|applet|audio|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|button|select|isindex|layer|link|meta|keygen|object|plaintext|style|script|textarea|title|math|video|svg|xml|xss'; $str = preg_replace_callback('#<(/*\s*)('.$naughty.')([^><]*)([><]*)#is', array($this, '_sanitize_naughty_html'), $str); /* @@ -661,8 +667,7 @@ class CI_Security { */ protected function _remove_evil_attributes($str, $is_image) { - // Formaction, style, and xmlns - $evil_attributes = array('style', 'xmlns', 'formaction', 'form', 'xlink:href'); + $evil_attributes = array('on\w*', 'style', 'xmlns', 'formaction', 'form', 'xlink:href'); if ($is_image === TRUE) { @@ -678,7 +683,7 @@ class CI_Security { $attribs = array(); // find occurrences of illegal attribute strings with quotes (042 and 047 are octal quotes) - preg_match_all('/('.implode('|', $evil_attributes).')\s*=\s*(\042|\047)([^\\2]*?)(\\2)/is', $str, $matches, PREG_SET_ORDER); + preg_match_all('/(?<!\w)('.implode('|', $evil_attributes).')\s*=\s*(\042|\047)([^\\2]*?)(\\2)/is', $str, $matches, PREG_SET_ORDER); foreach ($matches as $attr) { @@ -686,7 +691,7 @@ class CI_Security { } // find occurrences of illegal attribute strings without quotes - preg_match_all('/('.implode('|', $evil_attributes).')\s*=\s*([^\s>]*)/is', $str, $matches, PREG_SET_ORDER); + preg_match_all('/(?<!\w)('.implode('|', $evil_attributes).')\s*=\s*([^\s>]*)/is', $str, $matches, PREG_SET_ORDER); foreach ($matches as $attr) { |