Hi, attached is patch to fix this issue. Cheers Nico
-- Nico Golde - http://www.ngolde.de - n...@jabber.ccc.de - GPG: 0x73647CFF For security reasons, all text in this mail is double-rot13 encrypted.
diff -u mahara-1.1.2/debian/changelog mahara-1.1.2/debian/changelog --- mahara-1.1.2/debian/changelog +++ mahara-1.1.2/debian/changelog @@ -1,3 +1,12 @@ +mahara (1.1.2-1.1) unstable; urgency=high + + * Non-maintainer upload by the Security Team. + * Update to latest html2text.php copy of roundcube to prevent + arbitrary code execution caused be the /e modifier of + preg_replace (CVE-2008-5619; Closes: #524778). + + -- Nico Golde <n...@debian.org> Mon, 20 Apr 2009 21:23:16 +0200 + mahara (1.1.2-1) unstable; urgency=high * New Upstream Version only in patch2: unchanged: --- mahara-1.1.2.orig/htdocs/lib/html2text/class.html2text.php +++ mahara-1.1.2/htdocs/lib/html2text/class.html2text.php @@ -149,26 +149,18 @@ '/<script[^>]*>.*?<\/script>/i', // <script>s -- which strip_tags supposedly has problems with '/<style[^>]*>.*?<\/style>/i', // <style>s -- which strip_tags supposedly has problems with //'/<!-- .* -->/', // Comments -- which strip_tags might have problem a with - '/<h[123][^>]*>(.*?)<\/h[123]>/ie', // H1 - H3 - '/<h[456][^>]*>(.*?)<\/h[456]>/ie', // H4 - H6 '/<p[^>]*>/i', // <P> '/<br[^>]*>/i', // <br> - '/<b[^>]*>(.*?)<\/b>/i', // <b> - '/<strong[^>]*>(.*?)<\/strong>/i', // <strong> '/<i[^>]*>(.*?)<\/i>/i', // <i> '/<em[^>]*>(.*?)<\/em>/i', // <em> '/(<ul[^>]*>|<\/ul>)/i', // <ul> and </ul> '/(<ol[^>]*>|<\/ol>)/i', // <ol> and </ol> '/<li[^>]*>(.*?)<\/li>/i', // <li> and </li> '/<li[^>]*>/i', // <li> - '/<a [^>]*href="([^"]+)"[^>]*>(.*?)<\/a>/ie', - // <a href=""> '/<hr[^>]*>/i', // <hr> - '/<img[^>]*alt="([^"]+)"[^>]*>/i', // <img> '/(<table[^>]*>|<\/table>)/i', // <table> and </table> '/(<tr[^>]*>|<\/tr>)/i', // <tr> and </tr> '/<td[^>]*>(.*?)<\/td>/i', // <td> and </td> - '/<th[^>]*>(.*?)<\/th>/ie', // <th> and </th> '/&(nbsp|#160);/i', // Non-breaking space '/&(quot|rdquo|ldquo|#8220|#8221|#147|#148);/i', // Double quotes @@ -202,26 +194,18 @@ '', // <script>s -- which strip_tags supposedly has problems with '', // <style>s -- which strip_tags supposedly has problems with //'', // Comments -- which strip_tags might have problem a with - "ucwords(\"\n\n_\\1_\n\n\")", // H1 - H3 - "ucwords(\"\n\n\\1\n\n\")", // H4 - H6 - "\n\n", // <P> + "\n\n", // <P> "\n", // <br> - '_\\1_', // <b> - '_\\1_', // <strong> '_\\1_', // <i> '_\\1_', // <em> "\n\n", // <ul> and </ul> "\n\n", // <ol> and </ol> - " * \\1\n", // <li> and </li> - "\n * ", // <li> - '$this->_build_link_list("\\1", "\\2")', - // <a href=""> - "\n-------------------------\n", // <hr> - "[\\1]", // <img> - "\n\n", // <table> and </table> + "\t* \\1\n", // <li> and </li> + "\n\t* ", // <li> + "\n-------------------------\n", // <hr> + "\n\n", // <table> and </table> "\n", // <tr> and </tr> "\t\t\\1\n", // <td> and </td> - "ucwords(\"\t\t\\1\n\")", // <th> and </th> ' ', // Non-breaking space '"', // Double quotes "'", // Single quotes @@ -234,13 +218,60 @@ '--', '-', '*', - '£', + '£', 'EUR', // Euro sign. ? '', // Unknown/unhandled entities ' ' // Runs of spaces, post-handling ); /** + * List of preg* regular expression patterns to search for + * and replace using callback function. + * + * @var array $callback_search + * @access public + */ + var $callback_search = array( + '/<(h)[123456][^>]*>(.*?)<\/h[123456]>/i', // H1 - H3 + '/<(b)[^>]*>(.*?)<\/b>/i', // <b> + '/<(strong)[^>]*>(.*?)<\/strong>/i', // <strong> + '/<(a) [^>]*href=("|\')([^"\']+)\2[^>]*>(.*?)<\/a>/i', + // <a href=""> + '/<(th)[^>]*>(.*?)<\/th>/i', // <th> and </th> + ); + + /** + * List of preg* regular expression patterns to search for in PRE body, + * used in conjunction with $pre_replace. + * + * @var array $pre_search + * @access public + * @see $pre_replace + */ + var $pre_search = array( + "/\n/", + "/\t/", + '/ /', + '/<pre[^>]*>/', + '/<\/pre>/' + ); + + /** + * List of pattern replacements corresponding to patterns searched for PRE body. + * + * @var array $pre_replace + * @access public + * @see $pre_search + */ + var $pre_replace = array( + '<br>', + ' ', + ' ', + '', + '' + ); + + /** * Contains a list of HTML tags to allow in the resulting text. * * @var string $allowed_tags @@ -285,6 +316,15 @@ */ var $_link_count = 0; + /** + * Boolean flag, true if a table of link URLs should be listed after the text. + * + * @var boolean $_do_links + * @access private + * @see html2text() + */ + var $_do_links = true; + /** * Constructor. * @@ -294,15 +334,20 @@ * * @param string $source HTML content * @param boolean $from_file Indicates $source is a file to pull content from + * @param boolean $do_links Indicate whether a table of link URLs is desired + * @param integer $width Maximum width of the formatted text, 0 for no limit * @access public * @return void */ - function html2text( $source = '', $from_file = false ) + function html2text( $source = '', $from_file = false, $do_links = true, $width = 75 ) { if ( !empty($source) ) { $this->set_html($source, $from_file); } + $this->set_base_url(); + $this->_do_links = $do_links; + $this->width = $width; } /** @@ -315,13 +360,11 @@ */ function set_html( $source, $from_file = false ) { - $this->html = $source; - if ( $from_file && file_exists($source) ) { - $fp = fopen($source, 'r'); - $this->html = fread($fp, filesize($source)); - fclose($fp); + $this->html = file_get_contents($source); } + else + $this->html = $source; $this->_converted = false; } @@ -422,8 +465,15 @@ $text = trim(stripslashes($this->html)); + // Convert <PRE> + $this->_convert_pre($text); + + // Replace known html entities + $text = html_entity_decode($text, ENT_COMPAT, 'UTF-8'); + // Run our defined search-and-replace $text = preg_replace($this->search, $this->replace, $text); + $text = preg_replace_callback($this->callback_search, array('html2text', '_preg_callback'), $text); // Strip any other HTML tags $text = strip_tags($text, $this->allowed_tags); @@ -464,7 +514,9 @@ */ function _build_link_list( $link, $display ) { - if ( substr($link, 0, 7) == 'http://' || substr($link, 0, 8) == 'https://' || + if ( !$this->_do_links ) return $display; + + if ( substr($link, 0, 7) == 'http://' || substr($link, 0, 8) == 'https://' || substr($link, 0, 7) == 'mailto:' ) { $this->_link_count++; $this->_link_list .= "[" . $this->_link_count . "] $link\n"; @@ -485,7 +537,59 @@ return $display . $additional; } + + /** + * Helper function for PRE body conversion. + * + * @param string HTML content + * @access private + */ + function _convert_pre(&$text) + { + while(preg_match('/<pre[^>]*>(.*)<\/pre>/ismU', $text, $matches)) + { + $result = preg_replace($this->pre_search, $this->pre_replace, $matches[1]); + $text = preg_replace('/<pre[^>]*>.*<\/pre>/ismU', '<div><br>' . $result . '<br></div>', $text, 1); + } + } + /** + * Callback function for preg_replace_callback use. + * + * @param array PREG matches + * @return string + * @access private + */ + function _preg_callback($matches) + { + switch($matches[1]) + { + case 'b': + case 'strong': + return $this->_strtoupper($matches[2]); + case 'hr': + return $this->_strtoupper("\t\t". $matches[2] ."\n"); + case 'h': + return $this->_strtoupper("\n\n". $matches[2] ."\n\n"); + case 'a': + return $this->_build_link_list($matches[3], $matches[4]); + } + } + + /** + * Strtoupper multibyte wrapper function + * + * @param string + * @return string + * @access private + */ + function _strtoupper($str) + { + if (function_exists('mb_strtoupper')) + return mb_strtoupper($str); + else + return strtoupper($str); + } } ?>
pgpLuharjWpyr.pgp
Description: PGP signature