Fix bug where some escape sequences in html styles could bypass security checks

pull/6465/head
Aleksander Machniak 7 years ago
parent 13b35e3c0e
commit d9eed3625b

@ -2,7 +2,8 @@ CHANGELOG Roundcube Webmail
=========================== ===========================
- Fix PHP Warning: Use of undefined constant IDNA_DEFAULT on systems without php-intl (#6244) - Fix PHP Warning: Use of undefined constant IDNA_DEFAULT on systems without php-intl (#6244)
- Fix bug where some parts of quota information could be ignored (#6280) - Fix bug where some parts of quota information could have been ignored (#6280)
- Fix bug where some escape sequences in html styles could bypass security checks
RELEASE 1.3.6 RELEASE 1.3.6
------------- -------------

@ -500,7 +500,8 @@ class rcube_utils
$out = html_entity_decode(html_entity_decode($content)); $out = html_entity_decode(html_entity_decode($content));
$out = trim(preg_replace('/(^<!--|-->$)/', '', trim($out))); $out = trim(preg_replace('/(^<!--|-->$)/', '', trim($out)));
$out = preg_replace_callback('/\\\([0-9a-f]{2,4})\s*/i', $callback, $out); $out = preg_replace_callback('/\\\([0-9a-f]{2,6})\s*/i', $callback, $out);
$out = preg_replace('/\\\([^0-9a-f])/i', '\\1', $out);
$out = preg_replace('#/\*.*\*/#Ums', '', $out); $out = preg_replace('#/\*.*\*/#Ums', '', $out);
$out = strip_tags($out); $out = strip_tags($out);

@ -242,8 +242,11 @@ class rcube_washtml
// Remove unwanted white-space characters so regular expressions below work better // Remove unwanted white-space characters so regular expressions below work better
$style = preg_replace('/[\n\r\s\t]+/', ' ', $style); $style = preg_replace('/[\n\r\s\t]+/', ' ', $style);
// Decode insecure character sequences
$style = rcube_utils::xss_entity_decode($style);
foreach (explode(';', $style) as $declaration) { foreach (explode(';', $style) as $declaration) {
if (preg_match('/^\s*([a-z\-]+)\s*:\s*(.*)\s*$/i', $declaration, $match)) { if (preg_match('/^\s*([a-z\\\-]+)\s*:\s*(.*)\s*$/i', $declaration, $match)) {
$cssid = $match[1]; $cssid = $match[1];
$str = $match[2]; $str = $match[2];
$value = ''; $value = '';

@ -203,12 +203,15 @@ class Framework_Utils extends PHPUnit_Framework_TestCase
$mod = rcube_utils::mod_css_styles("left:exp/* */ression( alert(&#039;xss3&#039;) )", 'rcmbody'); $mod = rcube_utils::mod_css_styles("left:exp/* */ression( alert(&#039;xss3&#039;) )", 'rcmbody');
$this->assertEquals("/* evil! */", $mod, "Don't allow encoding quirks"); $this->assertEquals("/* evil! */", $mod, "Don't allow encoding quirks");
$mod = rcube_utils::mod_css_styles("background:\\0075\\0072\\006c( javascript:alert(&#039;xss&#039;) )", 'rcmbody'); $mod = rcube_utils::mod_css_styles("background:\\0075\\0072\\00006c( javascript:alert(&#039;xss&#039;) )", 'rcmbody');
$this->assertEquals("/* evil! */", $mod, "Don't allow encoding quirks (2)"); $this->assertEquals("/* evil! */", $mod, "Don't allow encoding quirks (2)");
$mod = rcube_utils::mod_css_styles("background: \\75 \\72 \\6C ('/images/img.png')", 'rcmbody'); $mod = rcube_utils::mod_css_styles("background: \\75 \\72 \\6C ('/images/img.png')", 'rcmbody');
$this->assertEquals("/* evil! */", $mod, "Don't allow encoding quirks (3)"); $this->assertEquals("/* evil! */", $mod, "Don't allow encoding quirks (3)");
$mod = rcube_utils::mod_css_styles("background: u\\r\\l('/images/img.png')", 'rcmbody');
$this->assertEquals("/* evil! */", $mod, "Don't allow encoding quirks (4)");
// position: fixed (#5264) // position: fixed (#5264)
$mod = rcube_utils::mod_css_styles(".test { position: fixed; }", 'rcmbody'); $mod = rcube_utils::mod_css_styles(".test { position: fixed; }", 'rcmbody');
$this->assertEquals("#rcmbody .test { position: absolute; }", $mod, "Replace position:fixed with position:absolute (0)"); $this->assertEquals("#rcmbody .test { position: absolute; }", $mod, "Replace position:fixed with position:absolute (0)");
@ -234,6 +237,9 @@ class Framework_Utils extends PHPUnit_Framework_TestCase
$mod = rcube_utils::xss_entity_decode('#foo:after{content:"\003Cimg/src=x onerror=alert(2)>";}'); $mod = rcube_utils::xss_entity_decode('#foo:after{content:"\003Cimg/src=x onerror=alert(2)>";}');
$this->assertNotContains('<img', $mod, "Strip (encoded) tags from content property"); $this->assertNotContains('<img', $mod, "Strip (encoded) tags from content property");
$mod = rcube_utils::xss_entity_decode("background: u\\r\\00006c('/images/img.png')");
$this->assertContains("url(", $mod, "Escape sequences resolving");
// #5747 // #5747
$mod = rcube_utils::xss_entity_decode('<!-- #foo { content:css; } -->'); $mod = rcube_utils::xss_entity_decode('<!-- #foo { content:css; } -->');
$this->assertContains('#foo', $mod, "Strip HTML comments from content, but not the content"); $this->assertContains('#foo', $mod, "Strip HTML comments from content, but not the content");

@ -215,7 +215,7 @@ class MailFunc extends PHPUnit_Framework_TestCase
$body = rcmail_print_body($html, $this->get_html_part(), array('safe' => false, 'plain' => false)); $body = rcmail_print_body($html, $this->get_html_part(), array('safe' => false, 'plain' => false));
$this->assertNotContains('onerror=alert(1)//">test', $body); $this->assertNotContains('onerror=alert(1)//">test', $body);
$this->assertContains('<a style="x: &gt;&lt;img src=x onerror=alert(1)//"', $body); $this->assertContains('<a style="x: &gt;"', $body);
} }
/** /**

Loading…
Cancel
Save