mirror of
https://github.com/ezyang/htmlpurifier.git
synced 2024-12-31 20:01:52 +00:00
[1.2.0]
- Added %URI.DisableExternal, which prevents links to external websites. You can also use %URI.Host to permit absolute linking to subdomains - Fixed a few bugs involving null configuration values git-svn-id: http://htmlpurifier.org/svnroot/htmlpurifier/trunk@522 48356398-32a2-884e-a903-53898d9a118a
This commit is contained in:
parent
926b94bdd3
commit
f38fe431ed
2
NEWS
2
NEWS
@ -13,6 +13,8 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
|
|||||||
! Added percent encoding normalization
|
! Added percent encoding normalization
|
||||||
! XSS attacks smoketest given facelift
|
! XSS attacks smoketest given facelift
|
||||||
! Configuration documentation now has table of contents
|
! Configuration documentation now has table of contents
|
||||||
|
! Added %URI.DisableExternal, which prevents links to external websites. You
|
||||||
|
can also use %URI.Host to permit absolute linking to subdomains
|
||||||
- Documentation updated
|
- Documentation updated
|
||||||
+ TODO added request Phalanger
|
+ TODO added request Phalanger
|
||||||
+ TODO added request Native compression
|
+ TODO added request Native compression
|
||||||
|
@ -39,8 +39,4 @@ time. Note the naming convention: %Namespace.Directive
|
|||||||
%URI.AddRelNofollow - will add rel="nofollow" to all links, preventing the
|
%URI.AddRelNofollow - will add rel="nofollow" to all links, preventing the
|
||||||
spread of ill-gotten pagerank
|
spread of ill-gotten pagerank
|
||||||
|
|
||||||
%URI.Host - host of website, for external link checks
|
|
||||||
|
|
||||||
%URI.RelativeToAbsolute - transforms all relative URIs to absolute form
|
%URI.RelativeToAbsolute - transforms all relative URIs to absolute form
|
||||||
|
|
||||||
%URI.DisableExternal - disable external links
|
|
||||||
|
@ -12,6 +12,28 @@ HTMLPurifier_ConfigSchema::define(
|
|||||||
'select the proper object validator when no scheme information is present.'
|
'select the proper object validator when no scheme information is present.'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
HTMLPurifier_ConfigSchema::define(
|
||||||
|
'URI', 'Host', null, 'string/null',
|
||||||
|
'Defines the domain name of the server, so we can determine whether or '.
|
||||||
|
'an absolute URI is from your website or not. Not strictly necessary, '.
|
||||||
|
'as users should be using relative URIs to reference resources on your '.
|
||||||
|
'website. It will, however, let you use absolute URIs to link to '.
|
||||||
|
'subdomains of the domain you post here: i.e. example.com will allow '.
|
||||||
|
'sub.example.com. However, higher up domains will still be excluded: '.
|
||||||
|
'if you set %URI.Host to sub.example.com, example.com will be blocked. '.
|
||||||
|
'This directive has been available since 1.2.0.'
|
||||||
|
);
|
||||||
|
|
||||||
|
HTMLPurifier_ConfigSchema::Define(
|
||||||
|
'URI', 'DisableExternal', false, 'bool',
|
||||||
|
'Disables links to external websites. This is a highly effective '.
|
||||||
|
'anti-spam and anti-pagerank-leech measure, but comes at a hefty price: no'.
|
||||||
|
'links or images outside of your domain will be allowed. Non-linkified '.
|
||||||
|
'URIs will still be preserved. If you want to be able to link to '.
|
||||||
|
'subdomains or use absolute URIs, specify %URI.Host for your website. '.
|
||||||
|
'This directive has been available since 1.2.0.'
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates a URI as defined by RFC 3986.
|
* Validates a URI as defined by RFC 3986.
|
||||||
* @note Scheme-specific mechanics deferred to HTMLPurifier_URIScheme
|
* @note Scheme-specific mechanics deferred to HTMLPurifier_URIScheme
|
||||||
@ -81,6 +103,13 @@ class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef
|
|||||||
|
|
||||||
if ($authority !== null) {
|
if ($authority !== null) {
|
||||||
|
|
||||||
|
// remove URI if it's absolute and we disallow externals
|
||||||
|
unset($our_host);
|
||||||
|
if ($config->get('URI', 'DisableExternal')) {
|
||||||
|
$our_host = $config->get('URI', 'Host');
|
||||||
|
if ($our_host === null) return false;
|
||||||
|
}
|
||||||
|
|
||||||
$HEXDIG = '[A-Fa-f0-9]';
|
$HEXDIG = '[A-Fa-f0-9]';
|
||||||
$unreserved = 'A-Za-z0-9-._~'; // make sure you wrap with []
|
$unreserved = 'A-Za-z0-9-._~'; // make sure you wrap with []
|
||||||
$sub_delims = '!$&\'()'; // needs []
|
$sub_delims = '!$&\'()'; // needs []
|
||||||
@ -103,6 +132,17 @@ class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef
|
|||||||
$host = $this->host->validate($host, $config, $context);
|
$host = $this->host->validate($host, $config, $context);
|
||||||
if ($host === false) $host = null;
|
if ($host === false) $host = null;
|
||||||
|
|
||||||
|
// more lenient absolute checking
|
||||||
|
if (isset($our_host)) {
|
||||||
|
$host_parts = array_reverse(explode('.', $host));
|
||||||
|
// could be cached
|
||||||
|
$our_host_parts = array_reverse(explode('.', $our_host));
|
||||||
|
foreach ($our_host_parts as $i => $discard) {
|
||||||
|
if (!isset($host_parts[$i])) return false;
|
||||||
|
if ($host_parts[$i] != $our_host_parts[$i]) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// userinfo and host are validated within the regexp
|
// userinfo and host are validated within the regexp
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -60,7 +60,7 @@ class HTMLPurifier_Config
|
|||||||
* @param $key String key
|
* @param $key String key
|
||||||
*/
|
*/
|
||||||
function get($namespace, $key) {
|
function get($namespace, $key) {
|
||||||
if (!isset($this->conf[$namespace][$key])) {
|
if (!isset($this->def->info[$namespace][$key])) {
|
||||||
trigger_error('Cannot retrieve value of undefined directive',
|
trigger_error('Cannot retrieve value of undefined directive',
|
||||||
E_USER_WARNING);
|
E_USER_WARNING);
|
||||||
return;
|
return;
|
||||||
@ -75,7 +75,7 @@ class HTMLPurifier_Config
|
|||||||
* @param $value Mixed value
|
* @param $value Mixed value
|
||||||
*/
|
*/
|
||||||
function set($namespace, $key, $value) {
|
function set($namespace, $key, $value) {
|
||||||
if (!isset($this->conf[$namespace][$key])) {
|
if (!isset($this->def->info[$namespace][$key])) {
|
||||||
trigger_error('Cannot set undefined directive to value',
|
trigger_error('Cannot set undefined directive to value',
|
||||||
E_USER_WARNING);
|
E_USER_WARNING);
|
||||||
return;
|
return;
|
||||||
|
@ -233,7 +233,6 @@ class HTMLPurifier_AttrDef_URITest extends HTMLPurifier_AttrDefHarness
|
|||||||
function testIntegration() {
|
function testIntegration() {
|
||||||
|
|
||||||
$this->def = new HTMLPurifier_AttrDef_URI();
|
$this->def = new HTMLPurifier_AttrDef_URI();
|
||||||
$this->config = $this->context = null;
|
|
||||||
|
|
||||||
$this->assertDef('http://www.google.com/');
|
$this->assertDef('http://www.google.com/');
|
||||||
$this->assertDef('javascript:bad_stuff();', false);
|
$this->assertDef('javascript:bad_stuff();', false);
|
||||||
@ -244,6 +243,24 @@ class HTMLPurifier_AttrDef_URITest extends HTMLPurifier_AttrDefHarness
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testDisableExternal() {
|
||||||
|
|
||||||
|
$this->def = new HTMLPurifier_AttrDef_URI();
|
||||||
|
$this->config->set('URI', 'DisableExternal', true);
|
||||||
|
|
||||||
|
$this->assertDef('/foobar.txt');
|
||||||
|
$this->assertDef('http://google.com/', false);
|
||||||
|
$this->assertDef('http://sub.example.com/alas?foo=asd', false);
|
||||||
|
|
||||||
|
$this->config->set('URI', 'Host', 'sub.example.com');
|
||||||
|
|
||||||
|
$this->assertDef('http://sub.example.com/alas?foo=asd');
|
||||||
|
$this->assertDef('http://example.com/teehee', false);
|
||||||
|
$this->assertDef('http://www.example.com/#man', false);
|
||||||
|
$this->assertDef('http://go.sub.example.com/perhaps?p=foo');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
@ -37,6 +37,10 @@ class HTMLPurifier_ConfigTest extends UnitTestCase
|
|||||||
'Core', 'Encoding', 'utf-8', 'istring', 'Case insensitivity!'
|
'Core', 'Encoding', 'utf-8', 'istring', 'Case insensitivity!'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
HTMLPurifier_ConfigSchema::define(
|
||||||
|
'Extension', 'CanBeNull', null, 'string/null', 'Null or string!'
|
||||||
|
);
|
||||||
|
|
||||||
HTMLPurifier_ConfigSchema::defineAllowedValues(
|
HTMLPurifier_ConfigSchema::defineAllowedValues(
|
||||||
'Extension', 'Pert', array('foo', 'moo')
|
'Extension', 'Pert', array('foo', 'moo')
|
||||||
);
|
);
|
||||||
@ -92,6 +96,21 @@ class HTMLPurifier_ConfigTest extends UnitTestCase
|
|||||||
$this->assertNoErrors();
|
$this->assertNoErrors();
|
||||||
$this->assertIdentical($config->get('Core', 'Encoding'), 'iso-8859-1');
|
$this->assertIdentical($config->get('Core', 'Encoding'), 'iso-8859-1');
|
||||||
|
|
||||||
|
// set null to directive that allows null
|
||||||
|
$config->set('Extension', 'CanBeNull', null);
|
||||||
|
$this->assertNoErrors();
|
||||||
|
$this->assertIdentical($config->get('Extension', 'CanBeNull'), null);
|
||||||
|
|
||||||
|
$config->set('Extension', 'CanBeNull', 'foobar');
|
||||||
|
$this->assertNoErrors();
|
||||||
|
$this->assertIdentical($config->get('Extension', 'CanBeNull'), 'foobar');
|
||||||
|
|
||||||
|
// set null to directive that doesn't allow null
|
||||||
|
$config->set('Extension', 'Pert', null);
|
||||||
|
$this->assertError('Value is of invalid type');
|
||||||
|
$this->assertNoErrors();
|
||||||
|
$this->swallowErrors();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_getDefinition() {
|
function test_getDefinition() {
|
||||||
|
Loading…
Reference in New Issue
Block a user