From 1bacbc0563ffa313abf21173f975ba5dbe4284c0 Mon Sep 17 00:00:00 2001 From: "Edward Z. Yang" Date: Sun, 25 Dec 2011 04:17:19 -0500 Subject: [PATCH] Add isBenign and getDefaultScheme methods. Signed-off-by: Edward Z. Yang --- library/HTMLPurifier/URI.php | 29 ++++++++++++++++++++++++++--- library/HTMLPurifier/URIDefinition.php | 4 ++++ library/HTMLPurifier/URIFilter/Munge.php | 15 ++------------- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/library/HTMLPurifier/URI.php b/library/HTMLPurifier/URI.php index 79b7a71f..f158ef5e 100644 --- a/library/HTMLPurifier/URI.php +++ b/library/HTMLPurifier/URI.php @@ -40,7 +40,7 @@ class HTMLPurifier_URI } else { // no scheme: retrieve the default one $def = $config->getDefinition('URI'); - $scheme_obj = $registry->getScheme($def->defaultScheme, $config, $context); + $scheme_obj = $def->getDefaultScheme($config, $context); if (!$scheme_obj) { // something funky happened to the default scheme object trigger_error( @@ -204,8 +204,9 @@ class HTMLPurifier_URI * the current context. This is true when the host is null, or * when it matches the host supplied to the configuration. * - * Note that this does not do any scheme checking (URI.Munge, I'm - * looking at you). + * Note that this does not do any scheme checking, so it is mostly + * only appropriate for metadata that doesn't care about protocol + * security. isBenign is probably what you actually want. */ public function isLocal($config, $context) { if ($this->host === null) return true; @@ -214,6 +215,28 @@ class HTMLPurifier_URI return false; } + /** + * Returns true if this URL should be considered a 'benign' URL, + * that is: + * + * - It is a local URL (isLocal), and + * - It has a equal or better level of security + */ + public function isBenign($config, $context) { + if (!$this->isLocal($config, $context)) return false; + + $scheme_obj = $this->getSchemeObj($config, $context); + if (!$scheme_obj) return false; // conservative approach + + $current_scheme_obj = $config->getDefinition('URI')->getDefaultScheme($config, $context); + if ($current_scheme_obj->secure) { + if (!$scheme_obj->secure) { + return false; + } + } + return true; + } + } // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/URIDefinition.php b/library/HTMLPurifier/URIDefinition.php index ea2b8fe2..ded5b9b6 100644 --- a/library/HTMLPurifier/URIDefinition.php +++ b/library/HTMLPurifier/URIDefinition.php @@ -72,6 +72,10 @@ class HTMLPurifier_URIDefinition extends HTMLPurifier_Definition if (is_null($this->defaultScheme)) $this->defaultScheme = $config->get('URI.DefaultScheme'); } + public function getDefaultScheme($config, $context) { + return HTMLPurifier_URISchemeRegistry::instance()->getScheme($this->defaultScheme, $config, $context); + } + public function filter(&$uri, $config, $context) { foreach ($this->filters as $name => $f) { $result = $f->filter($uri, $config, $context); diff --git a/library/HTMLPurifier/URIFilter/Munge.php b/library/HTMLPurifier/URIFilter/Munge.php index 448f7646..de695df1 100644 --- a/library/HTMLPurifier/URIFilter/Munge.php +++ b/library/HTMLPurifier/URIFilter/Munge.php @@ -20,19 +20,8 @@ class HTMLPurifier_URIFilter_Munge extends HTMLPurifier_URIFilter $scheme_obj = $uri->getSchemeObj($config, $context); if (!$scheme_obj) return true; // ignore unknown schemes, maybe another postfilter did it - if (!$scheme_obj->browsable) return true; // ignore non-browseable schemes - - // don't redirect if target host is our host - if ($uri->isLocal($config, $context)) { - $uri_definition = $config->getDefinition('URI'); - // but do redirect if we're currently on a secure scheme, - // and the target scheme is insecure - $current_scheme_obj = HTMLPurifier_URISchemeRegistry::instance()->getScheme($uri_definition->defaultScheme, $config, $context); - if ($scheme_obj->secure || !$current_scheme_obj->secure) { - return true; - } - // target scheme was not secure, but we were secure - } + if (!$scheme_obj->browsable) return true; // ignore non-browseable schemes, since we can't munge those in a reasonable way + if ($uri->isBenign($config, $context)) return true; // don't redirect if a benign URL $this->makeReplace($uri, $config, $context); $this->replace = array_map('rawurlencode', $this->replace); -- 2.11.4.GIT