From aa055c931a68547763f7bb89425a08e8ceecb749 Mon Sep 17 00:00:00 2001 From: thomascube Date: Thu, 22 Jan 2009 14:47:23 +0000 Subject: Get rid of vulnerable preg_replace eval and create_function (#1485686) + correctly handle base and link tags in html messages --- program/steps/mail/func.inc | 54 +++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 26 deletions(-) (limited to 'program/steps/mail/func.inc') diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc index 3a5e13f5a..aad60f677 100644 --- a/program/steps/mail/func.inc +++ b/program/steps/mail/func.inc @@ -671,6 +671,9 @@ function rcmail_print_body($part, $p = array()) $html = ''. $html; $html = substr_replace($html, '', intval(stripos($html, '')+6), 0); } + + // turn relative into absolute urls + $html = rcmail_resolve_base($html); // clean HTML with washhtml by Frederic Motte $wash_opts = array( @@ -685,6 +688,9 @@ function rcmail_print_body($part, $p = array()) if (!$p['inline_html']) { $wash_opts['html_elements'] = array('html','head','title','body'); } + if ($p['safe']) { + $wash_opts['html_elements'][] = 'link'; + } $washer = new washtml($wash_opts); $washer->add_callback('form', 'rcmail_washtml_callback'); @@ -710,22 +716,15 @@ function rcmail_print_body($part, $p = array()) /**** assert plaintext ****/ // make links and email-addresses clickable - $convert_patterns = $convert_replaces = $replace_strings = array(); + $replacements = new rcube_string_replacer; $url_chars = 'a-z0-9_\-\+\*\$\/&%=@#:;'; $url_chars_within = '\?\.~,!'; - - $convert_patterns[] = "/([\w]+):\/\/([a-z0-9\-\.]+[a-z]{2,4}([$url_chars$url_chars_within]*[$url_chars])?)/ie"; - $convert_replaces[] = "rcmail_str_replacement('\\1://\\2', \$replace_strings)"; - - $convert_patterns[] = "/([^\/:]|\s)(www\.)([a-z0-9\-]{2,}[a-z]{2,4}([$url_chars$url_chars_within]*[$url_chars])?)/ie"; - $convert_replaces[] = "rcmail_str_replacement('\\1\\2\\3', \$replace_strings)"; - - $convert_patterns[] = '/([a-z0-9][a-z0-9\-\.\+\_]*@[a-z0-9]([a-z0-9\-][.]?)*[a-z0-9]\\.[a-z]{2,5})/ie'; - $convert_replaces[] = "rcmail_str_replacement('\\1', \$replace_strings)"; // search for patterns like links and e-mail addresses - $body = preg_replace($convert_patterns, $convert_replaces, $body); + $body = preg_replace_callback("/([\w]+):\/\/([a-z0-9\-\.]+[a-z]{2,4}([$url_chars$url_chars_within]*[$url_chars])?)/i", array($replacements, 'link_callback'), $body); + $body = preg_replace_callback("/([^\/:]|\s)(www\.)([a-z0-9\-]{2,}[a-z]{2,4}([$url_chars$url_chars_within]*[$url_chars])?)/i", array($replacements, 'link_callback'), $body); + $body = preg_replace_callback('/([a-z0-9][a-z0-9\-\.\+\_]*@[a-z0-9]([a-z0-9\-][.]?)*[a-z0-9]\\.[a-z]{2,5})/i', array($replacements, 'mailto_callback'), $body); // split body into single lines $a_lines = preg_split('/\r?\n/', $body); @@ -754,7 +753,7 @@ function rcmail_print_body($part, $p = array()) } // insert the links for urls and mailtos - $body = preg_replace("/##string_replacement\{([0-9]+)\}##/e", "\$replace_strings[\\1]", join("\n", $a_lines)); + $body = $replacements->resolve(join("\n", $a_lines)); return html::tag('pre', array(), $body); } @@ -956,41 +955,44 @@ function rcmail_message_body($attrib) } +/** + * Convert all relative URLs according to a in HTML + */ +function rcmail_resolve_base($body) +{ + // check for + if (preg_match('!()/Ui', array($replacer, 'callback'), $body); + $body = preg_replace_callback('/(url\s*\()(["\']?)([\.\/]+[^"\'\)\s]+)(\2)\)/Ui', array($replacer, 'callback'), $body); + } + + return $body; +} /** * modify a HTML message that it can be displayed inside a HTML page */ function rcmail_html4inline($body, $container_id) { - $base_url = ""; $last_style_pos = 0; $body_lc = strtolower($body); - // check for - if (preg_match(($base_reg = '/()/i'), $body, $base_regs)) - $base_url = $base_regs[2]; - // find STYLE tags while (($pos = strpos($body_lc, '', $pos))) { $pos = strpos($body_lc, '>', $pos)+1; // replace all css definitions with #container [def] - $styles = rcmail_mod_css_styles(substr($body, $pos, $pos2-$pos), $container_id, $base_url); + $styles = rcmail_mod_css_styles(substr($body, $pos, $pos2-$pos), $container_id); $body = substr($body, 0, $pos) . $styles . substr($body, $pos2); $body_lc = strtolower($body); $last_style_pos = $pos2; } - // resolve - if ($base_url) - { - $body = preg_replace('/(src|background|href)=(["\']?)([\.\/]+[^"\'\s]+)(\2|\s|>)/Uie', "'\\1=\"'.make_absolute_url('\\3', '$base_url').'\"'", $body); - $body = preg_replace('/(url\s*\()(["\']?)([\.\/]+[^"\'\)\s]+)(\2)\)/Uie', "'\\1\''.make_absolute_url('\\3', '$base_url').'\')'", $body); - $body = preg_replace($base_reg, '', $body); - } - // modify HTML links to open a new window if clicked $body = preg_replace('/<(a|link)\s+([^>]+)>/Uie', "rcmail_alter_html_link('\\1','\\2', '$container_id');", $body); -- cgit v1.2.3