diff --git a/NEWS b/NEWS index 4b134259..4eb34c6c 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,8 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier ========================== 4.6.0, unknown release date +# Secure URI munge hashing algorithm has changed to hash_hmac("sha256", $url, $secret). + Please update any verification scripts you may have. # URI parsing algorithm was made more strict, so only prefixes which looks like schemes will actually be schemes. Thanks Michael Gusev for fixing. diff --git a/library/HTMLPurifier/ConfigSchema/schema/URI.MungeSecretKey.txt b/library/HTMLPurifier/ConfigSchema/schema/URI.MungeSecretKey.txt index 0d00f62e..1e17c1d4 100644 --- a/library/HTMLPurifier/ConfigSchema/schema/URI.MungeSecretKey.txt +++ b/library/HTMLPurifier/ConfigSchema/schema/URI.MungeSecretKey.txt @@ -11,7 +11,7 @@ DEFAULT: NULL to check if a URI has passed through HTML Purifier with this line:

-
$checksum === sha1($secret_key . ':' . $url)
+
$checksum === hash_hmac("sha256", $url, $secret_key)

If the output is TRUE, the redirector script should accept the URI. diff --git a/library/HTMLPurifier/URIFilter/Munge.php b/library/HTMLPurifier/URIFilter/Munge.php index bab748a7..e9631f2a 100644 --- a/library/HTMLPurifier/URIFilter/Munge.php +++ b/library/HTMLPurifier/URIFilter/Munge.php @@ -47,6 +47,9 @@ class HTMLPurifier_URIFilter_Munge extends HTMLPurifier_URIFilter $this->parser = new HTMLPurifier_URIParser(); $this->doEmbed = $config->get('URI.MungeResources'); $this->secretKey = $config->get('URI.MungeSecretKey'); + if ($this->secretKey && !function_exists('hash_hmac')) { + trigger_error("Cannot use %URI.MungeSecretKey without hash_hmac support.", E_USER_ERROR); + } return true; } @@ -104,7 +107,7 @@ class HTMLPurifier_URIFilter_Munge extends HTMLPurifier_URIFilter $this->replace['%p'] = $context->get('CurrentCSSProperty', true); // not always available if ($this->secretKey) { - $this->replace['%t'] = sha1($this->secretKey . ':' . $string); + $this->replace['%t'] = hash_hmac("sha256", $string, $this->secretKey); } } } diff --git a/tests/HTMLPurifier/HTMLT/munge-extra.htmlt b/tests/HTMLPurifier/HTMLT/munge-extra.htmlt index 4b1c70a9..8438e3cc 100644 --- a/tests/HTMLPurifier/HTMLT/munge-extra.htmlt +++ b/tests/HTMLPurifier/HTMLT/munge-extra.htmlt @@ -6,6 +6,6 @@ URI.MungeResources = true Link example.com --EXPECT-- -Link -example.com +Link +example.com --# vim: et sw=4 sts=4 diff --git a/tests/HTMLPurifier/HTMLT/secure-munge.htmlt b/tests/HTMLPurifier/HTMLT/secure-munge.htmlt index 114cb000..bf5b3244 100644 --- a/tests/HTMLPurifier/HTMLT/secure-munge.htmlt +++ b/tests/HTMLPurifier/HTMLT/secure-munge.htmlt @@ -5,6 +5,6 @@ URI.MungeSecretKey = "foo" foo local --EXPECT-- -foo +foo local --# vim: et sw=4 sts=4 diff --git a/tests/HTMLPurifier/URIFilter/MungeTest.php b/tests/HTMLPurifier/URIFilter/MungeTest.php index 9505a156..60658da2 100644 --- a/tests/HTMLPurifier/URIFilter/MungeTest.php +++ b/tests/HTMLPurifier/URIFilter/MungeTest.php @@ -107,7 +107,7 @@ class HTMLPurifier_URIFilter_MungeTest extends HTMLPurifier_URIFilterHarness public function testSecureMungeStandard() { $this->setSecureMunge(); - $this->assertFiltering('http://google.com', '/redirect.php?url=http%3A%2F%2Fgoogle.com&checksum=0072e2f817fd2844825def74e54443debecf0892'); + $this->assertFiltering('http://google.com', '/redirect.php?url=http%3A%2F%2Fgoogle.com&checksum=46267a796aca0ea5839f24c4c97ad2648373a4eca31b1c0d1fa7c7ff26798f79'); } public function testSecureMungeIgnoreUnknownSchemes() @@ -127,7 +127,7 @@ class HTMLPurifier_URIFilter_MungeTest extends HTMLPurifier_URIFilterHarness { $this->setSecureMunge(); $this->setMunge('/links/%s/%t'); - $this->assertFiltering('http://google.com', '/links/http%3A%2F%2Fgoogle.com/0072e2f817fd2844825def74e54443debecf0892'); + $this->assertFiltering('http://google.com', '/links/http%3A%2F%2Fgoogle.com/46267a796aca0ea5839f24c4c97ad2648373a4eca31b1c0d1fa7c7ff26798f79'); } public function testMungeIgnoreSameDomain()