mirror of
https://github.com/ezyang/htmlpurifier.git
synced 2025-01-18 11:41:52 +00:00
[3.1.1] General munge improvements
- Add CurrentCSSProperty context variable - Move Munge to its own class, derived off of SecureMunge. - Rename %URI.SecureMunge to %URI.Munge - Rename %URI.SecureMungeSecretKey to %URI.MungeSecretKey - Add extra substitutions for munge git-svn-id: http://htmlpurifier.org/svnroot/htmlpurifier/trunk@1803 48356398-32a2-884e-a903-53898d9a118a
This commit is contained in:
parent
7189ec2790
commit
463aa3a0fa
13
NEWS
13
NEWS
@ -12,14 +12,19 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
|
|||||||
3.1.1, unknown release date
|
3.1.1, unknown release date
|
||||||
! More robust imagecrash protection with height/width CSS with %CSS.MaxImgLength,
|
! More robust imagecrash protection with height/width CSS with %CSS.MaxImgLength,
|
||||||
and height/width HTML with %HTML.MaxImgLength.
|
and height/width HTML with %HTML.MaxImgLength.
|
||||||
! %URI.SecureMunge for secure URI munging (as opposed to %URI.Munge). Be sure
|
! %URI.SecureMunge for secure URI munging (as opposed to %URI.Munge). Thanks Chris
|
||||||
to set %URI.SecureMungeSecretKey when using this directive. Thanks Chris
|
for sponsoring this feature. Check out the corresponding documentation
|
||||||
for sponsoring this feature.
|
for details. (Att Nightly testers: The API for this feature changed before
|
||||||
|
the general release. Namely, rename your directives %URI.SecureMungeSecretKey =>
|
||||||
|
%URI.MungeSecretKey and and %URI.SecureMunge => %URI.Munge)
|
||||||
! Implemented post URI filtering. Set member variable $post to true to set
|
! Implemented post URI filtering. Set member variable $post to true to set
|
||||||
a URIFilter as such.
|
a URIFilter as such.
|
||||||
! Allow modules to define injectors via $info_injector. Injectors are
|
! Allow modules to define injectors via $info_injector. Injectors are
|
||||||
automatically disabled if injector's needed elements are not found.
|
automatically disabled if injector's needed elements are not found.
|
||||||
! Support for "safe" objects added, use %HTML.SafeObject and %HTML.SafeEmbed.
|
! Support for "safe" objects added, use %HTML.SafeObject and %HTML.SafeEmbed.
|
||||||
|
! Added substitutions for %e, %n, %a and %p in %URI.Munge (in order,
|
||||||
|
embedded, tag name, attribute name, CSS property name). See %URI.Munge
|
||||||
|
for more details.
|
||||||
- Disable percent height/width attributes for img
|
- Disable percent height/width attributes for img
|
||||||
- AttrValidator operations are now atomic; updates to attributes are not
|
- AttrValidator operations are now atomic; updates to attributes are not
|
||||||
manifest in token until end of operations. This prevents naughty internal
|
manifest in token until end of operations. This prevents naughty internal
|
||||||
@ -67,6 +72,8 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
|
|||||||
. URIFilter->prepare can return false in order to abort loading of the filter
|
. URIFilter->prepare can return false in order to abort loading of the filter
|
||||||
. Factory for AttrDef_URI implemented, URI#embedded to indicate URI that embeds
|
. Factory for AttrDef_URI implemented, URI#embedded to indicate URI that embeds
|
||||||
an external resource.
|
an external resource.
|
||||||
|
. %URI.Munge functionality factored out into a post-filter class.
|
||||||
|
. Added CurrentCSSProperty context variable during CSS validation
|
||||||
|
|
||||||
3.1.0, released 2008-05-18
|
3.1.0, released 2008-05-18
|
||||||
# Unnecessary references to objects (vestiges of PHP4) removed from method
|
# Unnecessary references to objects (vestiges of PHP4) removed from method
|
||||||
|
@ -236,11 +236,6 @@
|
|||||||
<line>28</line>
|
<line>28</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="URI.Munge">
|
|
||||||
<file name="HTMLPurifier/AttrDef/URI.php">
|
|
||||||
<line>77</line>
|
|
||||||
</file>
|
|
||||||
</directive>
|
|
||||||
<directive id="Core.ColorKeywords">
|
<directive id="Core.ColorKeywords">
|
||||||
<file name="HTMLPurifier/AttrDef/CSS/Color.php">
|
<file name="HTMLPurifier/AttrDef/CSS/Color.php">
|
||||||
<line>12</line>
|
<line>12</line>
|
||||||
@ -387,14 +382,14 @@
|
|||||||
<line>8</line>
|
<line>8</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="URI.SecureMunge">
|
<directive id="URI.MungeResources">
|
||||||
<file name="HTMLPurifier/URIFilter/SecureMunge.php">
|
<file name="HTMLPurifier/URIFilter/Munge.php">
|
||||||
<line>9</line>
|
<line>14</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
<directive id="URI.SecureMungeSecretKey">
|
<directive id="URI.MungeSecretKey">
|
||||||
<file name="HTMLPurifier/URIFilter/SecureMunge.php">
|
<file name="HTMLPurifier/URIFilter/Munge.php">
|
||||||
<line>10</line>
|
<line>15</line>
|
||||||
</file>
|
</file>
|
||||||
</directive>
|
</directive>
|
||||||
</usage>
|
</usage>
|
||||||
|
@ -184,7 +184,7 @@ require 'HTMLPurifier/URIFilter/DisableExternal.php';
|
|||||||
require 'HTMLPurifier/URIFilter/DisableExternalResources.php';
|
require 'HTMLPurifier/URIFilter/DisableExternalResources.php';
|
||||||
require 'HTMLPurifier/URIFilter/HostBlacklist.php';
|
require 'HTMLPurifier/URIFilter/HostBlacklist.php';
|
||||||
require 'HTMLPurifier/URIFilter/MakeAbsolute.php';
|
require 'HTMLPurifier/URIFilter/MakeAbsolute.php';
|
||||||
require 'HTMLPurifier/URIFilter/SecureMunge.php';
|
require 'HTMLPurifier/URIFilter/Munge.php';
|
||||||
require 'HTMLPurifier/URIScheme/ftp.php';
|
require 'HTMLPurifier/URIScheme/ftp.php';
|
||||||
require 'HTMLPurifier/URIScheme/http.php';
|
require 'HTMLPurifier/URIScheme/http.php';
|
||||||
require 'HTMLPurifier/URIScheme/https.php';
|
require 'HTMLPurifier/URIScheme/https.php';
|
||||||
|
@ -178,7 +178,7 @@ require_once $__dir . '/HTMLPurifier/URIFilter/DisableExternal.php';
|
|||||||
require_once $__dir . '/HTMLPurifier/URIFilter/DisableExternalResources.php';
|
require_once $__dir . '/HTMLPurifier/URIFilter/DisableExternalResources.php';
|
||||||
require_once $__dir . '/HTMLPurifier/URIFilter/HostBlacklist.php';
|
require_once $__dir . '/HTMLPurifier/URIFilter/HostBlacklist.php';
|
||||||
require_once $__dir . '/HTMLPurifier/URIFilter/MakeAbsolute.php';
|
require_once $__dir . '/HTMLPurifier/URIFilter/MakeAbsolute.php';
|
||||||
require_once $__dir . '/HTMLPurifier/URIFilter/SecureMunge.php';
|
require_once $__dir . '/HTMLPurifier/URIFilter/Munge.php';
|
||||||
require_once $__dir . '/HTMLPurifier/URIScheme/ftp.php';
|
require_once $__dir . '/HTMLPurifier/URIScheme/ftp.php';
|
||||||
require_once $__dir . '/HTMLPurifier/URIScheme/http.php';
|
require_once $__dir . '/HTMLPurifier/URIScheme/http.php';
|
||||||
require_once $__dir . '/HTMLPurifier/URIScheme/https.php';
|
require_once $__dir . '/HTMLPurifier/URIScheme/https.php';
|
||||||
|
@ -29,6 +29,12 @@ class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef
|
|||||||
$declarations = explode(';', $css);
|
$declarations = explode(';', $css);
|
||||||
$propvalues = array();
|
$propvalues = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the current CSS property being validated.
|
||||||
|
*/
|
||||||
|
$property = false;
|
||||||
|
$context->register('CurrentCSSProperty', $property);
|
||||||
|
|
||||||
foreach ($declarations as $declaration) {
|
foreach ($declarations as $declaration) {
|
||||||
if (!$declaration) continue;
|
if (!$declaration) continue;
|
||||||
if (!strpos($declaration, ':')) continue;
|
if (!strpos($declaration, ':')) continue;
|
||||||
@ -61,6 +67,8 @@ class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef
|
|||||||
$propvalues[$property] = $result;
|
$propvalues[$property] = $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$context->destroy('CurrentCSSProperty');
|
||||||
|
|
||||||
// procedure does not write the new CSS simultaneously, so it's
|
// procedure does not write the new CSS simultaneously, so it's
|
||||||
// slightly inefficient, but it's the only way of getting rid of
|
// slightly inefficient, but it's the only way of getting rid of
|
||||||
// duplicates. Perhaps config to optimize it, but not now.
|
// duplicates. Perhaps config to optimize it, but not now.
|
||||||
|
@ -68,18 +68,7 @@ class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef
|
|||||||
if (!$ok) return false;
|
if (!$ok) return false;
|
||||||
|
|
||||||
// back to string
|
// back to string
|
||||||
$result = $uri->toString();
|
return $uri->toString();
|
||||||
|
|
||||||
// munge entire URI if necessary
|
|
||||||
if (
|
|
||||||
!is_null($uri->host) && // indicator for authority
|
|
||||||
!empty($scheme_obj->browsable) &&
|
|
||||||
!is_null($munge = $config->get('URI', 'Munge'))
|
|
||||||
) {
|
|
||||||
$result = str_replace('%s', rawurlencode($result), $munge);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
@ -6,7 +6,7 @@ DEFAULT: NULL
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
Munges all browsable (usually http, https and ftp)
|
Munges all browsable (usually http, https and ftp)
|
||||||
absolute URI's into another URI, usually a URI redirection service.
|
absolute URIs into another URI, usually a URI redirection service.
|
||||||
This directive accepts a URI, formatted with a <code>%s</code> where
|
This directive accepts a URI, formatted with a <code>%s</code> where
|
||||||
the url-encoded original URI should be inserted (sample:
|
the url-encoded original URI should be inserted (sample:
|
||||||
<code>http://www.google.com/url?q=%s</code>).
|
<code>http://www.google.com/url?q=%s</code>).
|
||||||
@ -19,13 +19,58 @@ DEFAULT: NULL
|
|||||||
Prevent PageRank leaks, while being fairly transparent
|
Prevent PageRank leaks, while being fairly transparent
|
||||||
to users (you may also want to add some client side JavaScript to
|
to users (you may also want to add some client side JavaScript to
|
||||||
override the text in the statusbar). <strong>Notice</strong>:
|
override the text in the statusbar). <strong>Notice</strong>:
|
||||||
Many security experts believe that this form of protection does
|
Many security experts believe that this form of protection does not deter spam-bots.
|
||||||
not deter spam-bots.
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
Redirect users to a splash page telling them they are leaving your
|
Redirect users to a splash page telling them they are leaving your
|
||||||
website. While this is poor usability practice, it is often
|
website. While this is poor usability practice, it is often mandated
|
||||||
mandated
|
|
||||||
in corporate environments.
|
in corporate environments.
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<p>
|
||||||
|
You may want to also use %URI.MungeSecretKey along with this directive
|
||||||
|
in order to enforce what URIs your redirector script allows. Open
|
||||||
|
redirector scripts can be a security risk and negatively affect the
|
||||||
|
reputation of your domain name.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Starting with HTML Purifier 3.1.1, there is also these substitutions:
|
||||||
|
</p>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Key</th>
|
||||||
|
<th>Description</th>
|
||||||
|
<th>Example <code><a href=""></code></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>%r</td>
|
||||||
|
<td>1 - The URI embeds a resource<br />(blank) - The URI is merely a link</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>%n</td>
|
||||||
|
<td>The name of the tag this URI came from</td>
|
||||||
|
<td>a</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>%m</td>
|
||||||
|
<td>The name of the attribute this URI came from</td>
|
||||||
|
<td>href</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>%p</td>
|
||||||
|
<td>The name of the CSS property this URI came from, or blank if irrelevant</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<p>
|
||||||
|
Admittedly, these letters are somewhat arbitrary; the only stipulation
|
||||||
|
was that they couldn't be a through f. r is for resource (I would have preferred
|
||||||
|
e, but you take what you can get), n is for name, m
|
||||||
|
was picked because it came after n (and I couldn't use a), p is for
|
||||||
|
property.
|
||||||
|
</p>
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
URI.MungeResources
|
||||||
|
TYPE: bool
|
||||||
|
VERSION: 3.1.1
|
||||||
|
DEFAULT: false
|
||||||
|
--DESCRIPTION--
|
||||||
|
<p>
|
||||||
|
If true, any URI munging directives like %URI.Munge or %URI.SecureMunge
|
||||||
|
will also apply to embedded resources, such as <code><img src=""></code>.
|
||||||
|
Be careful enabling this directive if you have a redirector script
|
||||||
|
that does not use the <code>Location</code> HTTP header; all of your images
|
||||||
|
and other embedded resources will break.
|
||||||
|
</ul>
|
@ -0,0 +1,29 @@
|
|||||||
|
URI.MungeSecretKey
|
||||||
|
TYPE: string/null
|
||||||
|
VERSION: 3.1.1
|
||||||
|
DEFAULT: NULL
|
||||||
|
--DESCRIPTION--
|
||||||
|
<p>
|
||||||
|
This directive enables secure checksum generation along with %URI.Munge.
|
||||||
|
It should be set to a secure key that is not shared with anyone else.
|
||||||
|
The checksum can be placed in the URI using %t. Use of this checksum
|
||||||
|
affords an additional level of protection by allowing a redirector
|
||||||
|
to check if a URI has passed through HTML Purifier with this line:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre>$checksum === sha1($secret_key . ':' . $url)</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If the output is TRUE, the redirector script should accept the URI.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Please note that it would still be possible for an attacker to procure
|
||||||
|
secure hashes en-mass by abusing your website's Preview feature or the
|
||||||
|
like, but this service affords an additional level of protection
|
||||||
|
that should be combined with website blacklisting.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Remember this has no effect if %URI.Munge is not on.
|
||||||
|
</p>
|
@ -1,33 +0,0 @@
|
|||||||
URI.SecureMunge
|
|
||||||
TYPE: string/null
|
|
||||||
VERSION: 3.1.1
|
|
||||||
DEFAULT: NULL
|
|
||||||
--DESCRIPTION--
|
|
||||||
<p>
|
|
||||||
Like %URI.Munge, this directive munges browsable external resources
|
|
||||||
into another URI redirection service. %URI.SecureMunge accepts a URI
|
|
||||||
with a %s located where the original URI should be substituted in,
|
|
||||||
and %t located where the secure checksum should be provided.
|
|
||||||
However, this directive affords
|
|
||||||
an additional level of protection by generating a secure checksum from
|
|
||||||
the URI as well as a secret key provided by %URI.SecureMungeSecretKey.
|
|
||||||
Any redirector script can check this key by using:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>$checksum === sha1($secret_key . ':' . $url)</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
If the output is TRUE, the redirector script should accept the URI.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Please note that it would still be possible for an attacker to procure
|
|
||||||
secure hashes en-mass by abusing your website's Preview feature or the
|
|
||||||
like, but this service affords an additional level of protection
|
|
||||||
that should be combined with website blacklisting.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<strong>This is a post-filter.</strong> This filter may conflict with other
|
|
||||||
post-filters that deal with external links.
|
|
||||||
</p>
|
|
@ -1,11 +0,0 @@
|
|||||||
URI.SecureMungeSecretKey
|
|
||||||
TYPE: string/null
|
|
||||||
VERSION: 3.1.1
|
|
||||||
DEFAULT: NULL
|
|
||||||
--DESCRIPTION--
|
|
||||||
<p>
|
|
||||||
This is the secret key used in conjunction with %URI.SecureMunge. Your
|
|
||||||
redirector script needs to know about this key, and no one else should
|
|
||||||
know about this key. Please see the above
|
|
||||||
directive for more details.
|
|
||||||
</p>
|
|
@ -28,7 +28,7 @@ class HTMLPurifier_URIDefinition extends HTMLPurifier_Definition
|
|||||||
$this->registerFilter(new HTMLPurifier_URIFilter_DisableExternalResources());
|
$this->registerFilter(new HTMLPurifier_URIFilter_DisableExternalResources());
|
||||||
$this->registerFilter(new HTMLPurifier_URIFilter_HostBlacklist());
|
$this->registerFilter(new HTMLPurifier_URIFilter_HostBlacklist());
|
||||||
$this->registerFilter(new HTMLPurifier_URIFilter_MakeAbsolute());
|
$this->registerFilter(new HTMLPurifier_URIFilter_MakeAbsolute());
|
||||||
$this->registerFilter(new HTMLPurifier_URIFilter_SecureMunge());
|
$this->registerFilter(new HTMLPurifier_URIFilter_Munge());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function registerFilter($filter) {
|
public function registerFilter($filter) {
|
||||||
|
48
library/HTMLPurifier/URIFilter/Munge.php
Normal file
48
library/HTMLPurifier/URIFilter/Munge.php
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class HTMLPurifier_URIFilter_Munge extends HTMLPurifier_URIFilter
|
||||||
|
{
|
||||||
|
public $name = 'Munge';
|
||||||
|
public $post = true;
|
||||||
|
private $target, $parser, $doEmbed, $secretKey;
|
||||||
|
|
||||||
|
protected $replace = array();
|
||||||
|
|
||||||
|
public function prepare($config) {
|
||||||
|
$this->target = $config->get('URI', $this->name);
|
||||||
|
$this->parser = new HTMLPurifier_URIParser();
|
||||||
|
$this->doEmbed = $config->get('URI', 'MungeResources');
|
||||||
|
$this->secretKey = $config->get('URI', 'MungeSecretKey');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public function filter(&$uri, $config, $context) {
|
||||||
|
if ($context->get('EmbeddedURI', true) && !$this->doEmbed) return true;
|
||||||
|
|
||||||
|
$scheme_obj = $uri->getSchemeObj($config, $context);
|
||||||
|
if (!$scheme_obj) return true; // ignore unknown schemes, maybe another postfilter did it
|
||||||
|
if (is_null($uri->host) || empty($scheme_obj->browsable)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->makeReplace($uri, $config, $context);
|
||||||
|
$this->replace = array_map('rawurlencode', $this->replace);
|
||||||
|
|
||||||
|
$new_uri = strtr($this->target, $this->replace);
|
||||||
|
$uri = $this->parser->parse($new_uri); // overwrite
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function makeReplace($uri, $config, $context) {
|
||||||
|
$string = $uri->toString();
|
||||||
|
// always available
|
||||||
|
$this->replace['%s'] = $string;
|
||||||
|
$this->replace['%r'] = $context->get('EmbeddedURI', true);
|
||||||
|
$token = $context->get('CurrentToken', true);
|
||||||
|
$this->replace['%n'] = $token ? $token->name : null;
|
||||||
|
$this->replace['%m'] = $context->get('CurrentAttr', true);
|
||||||
|
$this->replace['%p'] = $context->get('CurrentCSSProperty', true);
|
||||||
|
// not always available
|
||||||
|
if ($this->secretKey) $this->replace['%t'] = sha1($this->secretKey . ':' . $string);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,33 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class HTMLPurifier_URIFilter_SecureMunge extends HTMLPurifier_URIFilter
|
|
||||||
{
|
|
||||||
public $name = 'SecureMunge';
|
|
||||||
public $post = true;
|
|
||||||
private $target, $secretKey, $parser;
|
|
||||||
public function prepare($config) {
|
|
||||||
$this->target = $config->get('URI', 'SecureMunge');
|
|
||||||
$this->secretKey = $config->get('URI', 'SecureMungeSecretKey');
|
|
||||||
$this->parser = new HTMLPurifier_URIParser();
|
|
||||||
if (!$this->secretKey) {
|
|
||||||
trigger_error('URI.SecureMunge is being ignored due to lack of value for URI.SecureMungeSecretKey', E_USER_WARNING);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
public function filter(&$uri, $config, $context) {
|
|
||||||
if (!$this->target || !$this->secretKey) return true;
|
|
||||||
if ($context->get('EmbeddedURI', true)) return true; // abort for embedded URIs
|
|
||||||
$scheme_obj = $uri->getSchemeObj($config, $context);
|
|
||||||
if (!$scheme_obj) return true; // ignore unknown schemes, maybe another postfilter did it
|
|
||||||
if (is_null($uri->host) || empty($scheme_obj->browsable)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
$string = $uri->toString();
|
|
||||||
$checksum = sha1($this->secretKey . ':' . $string);
|
|
||||||
$new_uri = str_replace('%s', rawurlencode($string), $this->target);
|
|
||||||
$new_uri = str_replace('%t', $checksum, $new_uri);
|
|
||||||
$uri = $this->parser->parse($new_uri); // overwrite
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
115
tests/HTMLPurifier/URIFilter/MungeTest.php
Normal file
115
tests/HTMLPurifier/URIFilter/MungeTest.php
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class HTMLPurifier_URIFilter_MungeTest extends HTMLPurifier_URIFilterHarness
|
||||||
|
{
|
||||||
|
|
||||||
|
function setUp() {
|
||||||
|
parent::setUp();
|
||||||
|
$this->filter = new HTMLPurifier_URIFilter_Munge();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setMunge($uri = 'http://www.google.com/url?q=%s') {
|
||||||
|
$this->config->set('URI', 'Munge', $uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setSecureMunge($key = 'secret') {
|
||||||
|
$this->setMunge('/redirect.php?url=%s&checksum=%t');
|
||||||
|
$this->config->set('URI', 'MungeSecretKey', $key);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testMunge() {
|
||||||
|
$this->setMunge();
|
||||||
|
$this->assertFiltering(
|
||||||
|
'http://www.example.com/',
|
||||||
|
'http://www.google.com/url?q=http%3A%2F%2Fwww.example.com%2F'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testMungeReplaceTagName() {
|
||||||
|
$this->setMunge('/r?tagname=%n&url=%s');
|
||||||
|
$token = new HTMLPurifier_Token_Start('a');
|
||||||
|
$this->context->register('CurrentToken', $token);
|
||||||
|
$this->assertFiltering('http://google.com', '/r?tagname=a&url=http%3A%2F%2Fgoogle.com');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testMungeReplaceAttribute() {
|
||||||
|
$this->setMunge('/r?attr=%m&url=%s');
|
||||||
|
$attr = 'href';
|
||||||
|
$this->context->register('CurrentAttr', $attr);
|
||||||
|
$this->assertFiltering('http://google.com', '/r?attr=href&url=http%3A%2F%2Fgoogle.com');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testMungeReplaceResource() {
|
||||||
|
$this->setMunge('/r?embeds=%r&url=%s');
|
||||||
|
$embeds = false;
|
||||||
|
$this->context->register('EmbeddedURI', $embeds);
|
||||||
|
$this->assertFiltering('http://google.com', '/r?embeds=&url=http%3A%2F%2Fgoogle.com');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testMungeReplaceCSSProperty() {
|
||||||
|
$this->setMunge('/r?property=%p&url=%s');
|
||||||
|
$property = 'background';
|
||||||
|
$this->context->register('CurrentCSSProperty', $property);
|
||||||
|
$this->assertFiltering('http://google.com', '/r?property=background&url=http%3A%2F%2Fgoogle.com');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testIgnoreEmbedded() {
|
||||||
|
$this->setMunge();
|
||||||
|
$embeds = true;
|
||||||
|
$this->context->register('EmbeddedURI', $embeds);
|
||||||
|
$this->assertFiltering('http://example.com');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testProcessEmbedded() {
|
||||||
|
$this->setMunge();
|
||||||
|
$this->config->set('URI', 'MungeResources', true);
|
||||||
|
$embeds = true;
|
||||||
|
$this->context->register('EmbeddedURI', $embeds);
|
||||||
|
$this->assertFiltering('http://www.example.com/', 'http://www.google.com/url?q=http%3A%2F%2Fwww.example.com%2F');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testPreserveRelative() {
|
||||||
|
$this->setMunge();
|
||||||
|
$this->assertFiltering('index.html');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testMungeIgnoreUnknownSchemes() {
|
||||||
|
$this->setMunge();
|
||||||
|
$this->assertFiltering('javascript:foobar();', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSecureMungePreserve() {
|
||||||
|
$this->setSecureMunge();
|
||||||
|
$this->assertFiltering('/local');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSecureMungePreserveEmbedded() {
|
||||||
|
$this->setSecureMunge();
|
||||||
|
$embedded = true;
|
||||||
|
$this->context->register('EmbeddedURI', $embedded);
|
||||||
|
$this->assertFiltering('http://google.com');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSecureMungeStandard() {
|
||||||
|
$this->setSecureMunge();
|
||||||
|
$this->assertFiltering('http://google.com', '/redirect.php?url=http%3A%2F%2Fgoogle.com&checksum=0072e2f817fd2844825def74e54443debecf0892');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSecureMungeIgnoreUnknownSchemes() {
|
||||||
|
// This should be integration tested as well to be false
|
||||||
|
$this->setSecureMunge();
|
||||||
|
$this->assertFiltering('javascript:', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSecureMungeIgnoreUnbrowsableSchemes() {
|
||||||
|
$this->setSecureMunge();
|
||||||
|
$this->assertFiltering('news:', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSecureMungeToDirectory() {
|
||||||
|
$this->setSecureMunge();
|
||||||
|
$this->setMunge('/links/%s/%t');
|
||||||
|
$this->assertFiltering('http://google.com', '/links/http%3A%2F%2Fgoogle.com/0072e2f817fd2844825def74e54443debecf0892');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,55 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class HTMLPurifier_URIFilter_SecureMungeTest extends HTMLPurifier_URIFilterHarness
|
|
||||||
{
|
|
||||||
|
|
||||||
function setUp() {
|
|
||||||
parent::setUp();
|
|
||||||
$this->filter = new HTMLPurifier_URIFilter_SecureMunge();
|
|
||||||
$this->setSecureMunge();
|
|
||||||
$this->setSecretKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
function setSecureMunge($uri = '/redirect.php?url=%s&checksum=%t') {
|
|
||||||
$this->config->set('URI', 'SecureMunge', $uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
function setSecretKey($key = 'secret') {
|
|
||||||
$this->config->set('URI', 'SecureMungeSecretKey', $key);
|
|
||||||
}
|
|
||||||
|
|
||||||
function testPreserve() {
|
|
||||||
$this->assertFiltering('/local');
|
|
||||||
}
|
|
||||||
|
|
||||||
function testPreserveEmbedded() {
|
|
||||||
$embedded = true;
|
|
||||||
$this->context->register('EmbeddedURI', $embedded);
|
|
||||||
$this->assertFiltering('http://google.com');
|
|
||||||
}
|
|
||||||
|
|
||||||
function testStandardMunge() {
|
|
||||||
$this->assertFiltering('http://google.com', '/redirect.php?url=http%3A%2F%2Fgoogle.com&checksum=0072e2f817fd2844825def74e54443debecf0892');
|
|
||||||
}
|
|
||||||
|
|
||||||
function testIgnoreUnknownSchemes() {
|
|
||||||
// This should be integration tested as well to be false
|
|
||||||
$this->assertFiltering('javascript:', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
function testIgnoreUnbrowsableSchemes() {
|
|
||||||
$this->assertFiltering('news:', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
function testMungeToDirectory() {
|
|
||||||
$this->setSecureMunge('/links/%s/%t');
|
|
||||||
$this->assertFiltering('http://google.com', '/links/http%3A%2F%2Fgoogle.com/0072e2f817fd2844825def74e54443debecf0892');
|
|
||||||
}
|
|
||||||
|
|
||||||
function testErrorNoSecretKey() {
|
|
||||||
$this->setSecretKey(null);
|
|
||||||
$this->expectError('URI.SecureMunge is being ignored due to lack of value for URI.SecureMungeSecretKey');
|
|
||||||
$this->assertFiltering('http://google.com');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -186,8 +186,8 @@ alert("<This is compatible with XHTML>");
|
|||||||
}
|
}
|
||||||
|
|
||||||
function test_secureMunge() {
|
function test_secureMunge() {
|
||||||
$this->config->set('URI', 'SecureMunge', '/redirect.php?url=%s&check=%t');
|
$this->config->set('URI', 'Munge', '/redirect.php?url=%s&check=%t');
|
||||||
$this->config->set('URI', 'SecureMungeSecretKey', 'foo');
|
$this->config->set('URI', 'MungeSecretKey', 'foo');
|
||||||
$this->assertPurification(
|
$this->assertPurification(
|
||||||
'<a href="http://localhost">foo</a><img src="http://localhost" alt="local" />',
|
'<a href="http://localhost">foo</a><img src="http://localhost" alt="local" />',
|
||||||
'<a href="/redirect.php?url=http%3A%2F%2Flocalhost&check=8e8223ae8fac24561104180ea549c21fbd111be7">foo</a><img src="http://localhost" alt="local" />'
|
'<a href="/redirect.php?url=http%3A%2F%2Flocalhost&check=8e8223ae8fac24561104180ea549c21fbd111be7">foo</a><img src="http://localhost" alt="local" />'
|
||||||
@ -206,13 +206,25 @@ alert("<This is compatible with XHTML>");
|
|||||||
function test_safeObjectAndEmbedWithSecureMunge() {
|
function test_safeObjectAndEmbedWithSecureMunge() {
|
||||||
$this->config->set('HTML', 'SafeObject', true);
|
$this->config->set('HTML', 'SafeObject', true);
|
||||||
$this->config->set('HTML', 'SafeEmbed', true);
|
$this->config->set('HTML', 'SafeEmbed', true);
|
||||||
$this->config->set('URI', 'SecureMunge', '/redirect.php?url=%s&check=%t');
|
$this->config->set('URI', 'Munge', '/redirect.php?url=%s&check=%t');
|
||||||
$this->config->set('URI', 'SecureMungeSecretKey', 'foo');
|
$this->config->set('URI', 'MungeSecretKey', 'foo');
|
||||||
$this->assertPurification(
|
$this->assertPurification(
|
||||||
'<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/Oq3FV_zdyy0&hl=en"></param><embed src="http://www.youtube.com/v/Oq3FV_zdyy0&hl=en" type="application/x-shockwave-flash" width="425" height="344"></embed></object>',
|
'<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/Oq3FV_zdyy0&hl=en"></param><embed src="http://www.youtube.com/v/Oq3FV_zdyy0&hl=en" type="application/x-shockwave-flash" width="425" height="344"></embed></object>',
|
||||||
'<object width="425" height="344" data="http://www.youtube.com/v/Oq3FV_zdyy0&hl=en" type="application/x-shockwave-flash"><param name="allowScriptAccess" value="never" /><param name="allowNetworking" value="internal" /><param name="movie" value="http://www.youtube.com/v/Oq3FV_zdyy0&hl=en" /><embed src="http://www.youtube.com/v/Oq3FV_zdyy0&hl=en" type="application/x-shockwave-flash" width="425" height="344" allowscriptaccess="never" allownetworking="internal" /></object>'
|
'<object width="425" height="344" data="http://www.youtube.com/v/Oq3FV_zdyy0&hl=en" type="application/x-shockwave-flash"><param name="allowScriptAccess" value="never" /><param name="allowNetworking" value="internal" /><param name="movie" value="http://www.youtube.com/v/Oq3FV_zdyy0&hl=en" /><embed src="http://www.youtube.com/v/Oq3FV_zdyy0&hl=en" type="application/x-shockwave-flash" width="425" height="344" allowscriptaccess="never" allownetworking="internal" /></object>'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function test_mungeWithExtraParams() {
|
||||||
|
$this->config->set('URI', 'Munge', '/redirect?s=%s&t=%t&r=%r&n=%n&m=%m&p=%p');
|
||||||
|
$this->config->set('URI', 'MungeSecretKey', 'foo');
|
||||||
|
$this->config->set('URI', 'MungeResources', true);
|
||||||
|
$this->assertPurification(
|
||||||
|
'<a href="http://example.com">Link</a><img src="http://example.com" style="background-image:url(http://example.com);" alt="example.com" />',
|
||||||
|
'<a href="/redirect?s=http%3A%2F%2Fexample.com&t=c15354f3953dfec262c55b1403067e0d045a3059&r=&n=a&m=href&p=">Link</a>'.
|
||||||
|
'<img src="/redirect?s=http%3A%2F%2Fexample.com&t=c15354f3953dfec262c55b1403067e0d045a3059&r=1&n=img&m=src&p=" '.
|
||||||
|
'style="background-image:url(/redirect?s=http%3A%2F%2Fexample.com&t=c15354f3953dfec262c55b1403067e0d045a3059&r=1&n=img&m=style&p=background-image);" alt="example.com" />'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user