Better CSS url() validation
| | |
| | | CHANGELOG Roundcube Webmail |
| | | =========================== |
| | | |
| | | - Make Roundcube render the Email Standards Project Acid Test correctly |
| | | - Deprecate $DB, $USER, $IMAP global variables, Use $RCMAIL instead |
| | | - Add option to set default font for HTML message (#1484137) |
| | | - Fix issues with big memory allocation of IMAP results |
| | |
| | | // ignore the whole block if evil styles are detected |
| | | $source = rcmail_xss_entity_decode($source); |
| | | $stripped = preg_replace('/[^a-z\(:;]/i', '', $source); |
| | | $evilexpr = 'expression|behavior' . (!$allow_remote ? '|url\(|import[^a]' : ''); |
| | | if (preg_match("/$evilexpr/i", $stripped) // don't accept No-Gos |
| | | || (strpos($stripped, 'url(') && !preg_match('!url\s*\([ "\'](https?:)//[a-z0-9/._+-]+["\' ]\)!Ui', $source))) // only allow clean urls |
| | | $evilexpr = 'expression|behavior|javascript:|import[^a]' . (!$allow_remote ? '|url\(' : ''); |
| | | if (preg_match("/$evilexpr/i", $stripped)) |
| | | return '/* evil! */'; |
| | | |
| | | // cut out all contents between { and } |
| | | while (($pos = strpos($source, '{', $last_pos)) && ($pos2 = strpos($source, '}', $pos))) |
| | | { |
| | | $key = $replacements->add(substr($source, $pos+1, $pos2-($pos+1))); |
| | | while (($pos = strpos($source, '{', $last_pos)) && ($pos2 = strpos($source, '}', $pos))) { |
| | | $styles = substr($source, $pos+1, $pos2-($pos+1)); |
| | | |
| | | // check every line of a style block... |
| | | if ($allow_remote) { |
| | | $a_styles = preg_split('/;[\r\n]*/', $styles, -1, PREG_SPLIT_NO_EMPTY); |
| | | foreach ($a_styles as $line) { |
| | | $stripped = preg_replace('/[^a-z\(:;]/i', '', $line); |
| | | // ... and only allow strict url() values |
| | | if (stripos($stripped, 'url(') && !preg_match('!url\s*\([ "\'](https?:)//[a-z0-9/._+-]+["\' ]\)!Uims', $line)) { |
| | | $a_styles = array('/* evil! */'); |
| | | break; |
| | | } |
| | | } |
| | | $styles = join(";\n", $a_styles); |
| | | } |
| | | |
| | | $key = $replacements->add($styles); |
| | | $source = substr($source, 0, $pos+1) . $replacements->get_replacement($key) . substr($source, $pos2, strlen($source)-$pos2); |
| | | $last_pos = $pos+2; |
| | | } |
| | |
| | | $stripped = preg_replace('/[^a-zA-Z\(:;]/', '', rcmail_xss_entity_decode($content)); |
| | | |
| | | // now check for evil strings like expression, behavior or url() |
| | | if (!preg_match('/expression|behavior/i', $stripped)) { |
| | | if (!$washtml->get_config('allow_remote') && preg_match('/url\(|import[^a]/i', $stripped)) |
| | | if (!preg_match('/expression|behavior|javascript:|import[^a]/i', $stripped)) { |
| | | if (!$washtml->get_config('allow_remote') && stripos($stripped, 'url(')) |
| | | $washtml->extlinks = true; |
| | | else |
| | | $out = html::tag('style', array('type' => 'text/css'), $content); |