Allow (sanitized) style elements in HTML messages

release-0.6
thomascube 16 years ago
parent 9bed2d86d5
commit 1c499ae930

@ -597,7 +597,8 @@ function rcmail_mod_css_styles($source, $container_id, $base_url = '')
$last_pos = 0;
// ignore the whole block if evil styles are detected
if (stristr($source, 'expression') || stristr($source, 'behavior'))
$stripped = preg_replace('/[^a-z\(:]/', '', rcmail_xss_entitiy_decode($source));
if (preg_match('/expression|behavior|url\(|import/', $stripped))
return '';
// cut out all contents between { and }
@ -632,6 +633,22 @@ function rcmail_mod_css_styles($source, $container_id, $base_url = '')
}
/**
* Decode escaped entities used by known XSS exploits.
* See http://downloads.securityfocus.com/vulnerabilities/exploits/26800.eml for examples
*
* @param string CSS content to decode
* @return string Decoded string
*/
function rcmail_xss_entitiy_decode($content)
{
$out = html_entity_decode(html_entity_decode($content));
$out = preg_replace('/\\\00([a-z0-9]{2})/ie', "chr(hexdec('\\1'))", $out);
$out = preg_replace('#/\*.+\*/#Um', '', $out);
return $out;
}
/**
* Compose a valid attribute string for HTML tags
*

@ -602,15 +602,14 @@ function rcmail_print_body($part, $p = array())
$wash_opts['html_elements'] = array('html','head','title','body');
}
/* CSS styles need to be sanitized!
// allow CSS styles, will be sanitized by rcmail_washtml_callback()
if ($p['safe']) {
$wash_opts['html_elements'][] = 'style';
$wash_opts['html_attribs'] = array('type');
}
*/
$washer = new washtml($wash_opts);
$washer->add_callback('form', 'rcmail_washtml_callback');
$washer->add_callback('style', 'rcmail_washtml_callback');
$body = $washer->wash($html);
$REMOTE_OBJECTS = $washer->extlinks;
@ -698,6 +697,16 @@ function rcmail_washtml_callback($tagname, $attrib, $content)
$out = html::div('form', $content);
break;
case 'style':
// decode all escaped entities and reduce to ascii strings
$stripped = preg_replace('/[^a-zA-Z\(:]/', '', rcmail_xss_entitiy_decode($source));
// now check for evli strings like expression, behavior or url()
if (!preg_match('/expression|behavior|url\(|import/', $css)) {
$out = html::tag('style', array('type' => 'text/css'), $content);
break;
}
default:
$out = '';
}

Loading…
Cancel
Save