mirror of
https://github.com/ezyang/htmlpurifier.git
synced 2024-12-22 08:21:52 +00:00
Add %HTML.TargetNoreferrer, which adds rel="noreferrer" when target attribute is set
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
This commit is contained in:
parent
cc35c8eb8c
commit
1675fc7caf
5
NEWS
5
NEWS
@ -10,6 +10,11 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
|
||||
==========================
|
||||
|
||||
4.8.0, unknown release date
|
||||
# By default, when a link has a target attribute associated
|
||||
with it, we now also add rel="noreferrer" in order to
|
||||
prevent the new window from being able to overwrite
|
||||
the original frame. To disable this protection,
|
||||
set %HTML.TargetNoreferrer to FALSE.
|
||||
! Full PHP 7 compatibility, the test suite is ALL GO.
|
||||
! %CSS.AllowDuplicates permits duplicate CSS properties.
|
||||
! Support for 'tel' URIs.
|
||||
|
@ -227,6 +227,11 @@
|
||||
<line>271</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="HTML.TargetNoreferrer">
|
||||
<file name="HTMLPurifier/HTMLModuleManager.php">
|
||||
<line>276</line>
|
||||
</file>
|
||||
</directive>
|
||||
<directive id="Attr.IDBlacklist">
|
||||
<file name="HTMLPurifier/IDAccumulator.php">
|
||||
<line>27</line>
|
||||
|
@ -137,6 +137,7 @@ require 'HTMLPurifier/AttrTransform/SafeObject.php';
|
||||
require 'HTMLPurifier/AttrTransform/SafeParam.php';
|
||||
require 'HTMLPurifier/AttrTransform/ScriptRequired.php';
|
||||
require 'HTMLPurifier/AttrTransform/TargetBlank.php';
|
||||
require 'HTMLPurifier/AttrTransform/TargetNoreferrer.php';
|
||||
require 'HTMLPurifier/AttrTransform/Textarea.php';
|
||||
require 'HTMLPurifier/ChildDef/Chameleon.php';
|
||||
require 'HTMLPurifier/ChildDef/Custom.php';
|
||||
@ -175,6 +176,7 @@ require 'HTMLPurifier/HTMLModule/StyleAttribute.php';
|
||||
require 'HTMLPurifier/HTMLModule/Tables.php';
|
||||
require 'HTMLPurifier/HTMLModule/Target.php';
|
||||
require 'HTMLPurifier/HTMLModule/TargetBlank.php';
|
||||
require 'HTMLPurifier/HTMLModule/TargetNoreferrer.php';
|
||||
require 'HTMLPurifier/HTMLModule/Text.php';
|
||||
require 'HTMLPurifier/HTMLModule/Tidy.php';
|
||||
require 'HTMLPurifier/HTMLModule/XMLCommonAttributes.php';
|
||||
|
@ -131,6 +131,7 @@ require_once $__dir . '/HTMLPurifier/AttrTransform/SafeObject.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/SafeParam.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/ScriptRequired.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/TargetBlank.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/TargetNoreferrer.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Textarea.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef/Chameleon.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef/Custom.php';
|
||||
@ -169,6 +170,7 @@ require_once $__dir . '/HTMLPurifier/HTMLModule/StyleAttribute.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tables.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Target.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/TargetBlank.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/TargetNoreferrer.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Text.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/XMLCommonAttributes.php';
|
||||
|
37
library/HTMLPurifier/AttrTransform/TargetNoreferrer.php
Normal file
37
library/HTMLPurifier/AttrTransform/TargetNoreferrer.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
// must be called POST validation
|
||||
|
||||
/**
|
||||
* Adds rel="noreferrer" to any links which target a different window
|
||||
* than the current one. This is used to prevent malicious websites
|
||||
* from silently replacing the original window, which could be used
|
||||
* to do phishing.
|
||||
* This transform is controlled by %HTML.TargetNoreferrer.
|
||||
*/
|
||||
class HTMLPurifier_AttrTransform_TargetNoreferrer extends HTMLPurifier_AttrTransform
|
||||
{
|
||||
/**
|
||||
* @param array $attr
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return array
|
||||
*/
|
||||
public function transform($attr, $config, $context)
|
||||
{
|
||||
if (isset($attr['rel'])) {
|
||||
$rels = explode(' ', $attr['rel']);
|
||||
} else {
|
||||
$rels = array();
|
||||
}
|
||||
if (isset($attr['target']) && !in_array('noreferrer', $rels)) {
|
||||
$rels[] = 'noreferrer';
|
||||
}
|
||||
if (!empty($rels) || isset($attr['rel'])) {
|
||||
$attr['rel'] = implode(' ', $rels);
|
||||
}
|
||||
|
||||
return $attr;
|
||||
}
|
||||
}
|
||||
|
Binary file not shown.
@ -0,0 +1,9 @@
|
||||
HTML.TargetNoreferrer
|
||||
TYPE: bool
|
||||
VERSION: 4.8.0
|
||||
DEFAULT: TRUE
|
||||
--DESCRIPTION--
|
||||
If enabled, noreferrer rel attributes are added to links which have
|
||||
a target attribute associated with them. This prevents malicious
|
||||
destinations from overwriting the original window.
|
||||
--# vim: et sw=4 sts=4
|
21
library/HTMLPurifier/HTMLModule/TargetNoreferrer.php
Normal file
21
library/HTMLPurifier/HTMLModule/TargetNoreferrer.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Module adds the target-based noreferrer attribute transformation to a tags. It
|
||||
* is enabled by HTML.TargetNoreferrer
|
||||
*/
|
||||
class HTMLPurifier_HTMLModule_TargetNoreferrer extends HTMLPurifier_HTMLModule
|
||||
{
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
public $name = 'TargetNoreferrer';
|
||||
|
||||
/**
|
||||
* @param HTMLPurifier_Config $config
|
||||
*/
|
||||
public function setup($config) {
|
||||
$a = $this->addBlankElement('a');
|
||||
$a->attr_transform_post[] = new HTMLPurifier_AttrTransform_TargetNoreferrer();
|
||||
}
|
||||
}
|
@ -271,6 +271,11 @@ class HTMLPurifier_HTMLModuleManager
|
||||
if ($config->get('HTML.TargetBlank')) {
|
||||
$modules[] = 'TargetBlank';
|
||||
}
|
||||
// NB: HTML.TargetNoreferrer must be AFTER HTML.TargetBlank
|
||||
// so that its post-attr-transform gets run afterwards.
|
||||
if ($config->get('HTML.TargetNoreferrer')) {
|
||||
$modules[] = 'TargetNoreferrer';
|
||||
}
|
||||
|
||||
// merge in custom modules
|
||||
$modules = array_merge($modules, $this->userModules);
|
||||
|
@ -13,7 +13,7 @@ class HTMLPurifier_HTMLModule_TargetBlankTest extends HTMLPurifier_HTMLModuleHar
|
||||
{
|
||||
$this->assertResult(
|
||||
'<a href="http://google.com">a</a><a href="/local">b</a><a href="mailto:foo@example.com">c</a>',
|
||||
'<a href="http://google.com" target="_blank">a</a><a href="/local">b</a><a href="mailto:foo@example.com">c</a>'
|
||||
'<a href="http://google.com" target="_blank" rel="noreferrer">a</a><a href="/local">b</a><a href="mailto:foo@example.com">c</a>'
|
||||
);
|
||||
}
|
||||
|
||||
|
42
tests/HTMLPurifier/HTMLModule/TargetNoreferrerTest.php
Normal file
42
tests/HTMLPurifier/HTMLModule/TargetNoreferrerTest.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
class HTMLPurifier_HTMLModule_TargetNoreferrerTest extends HTMLPurifier_HTMLModuleHarness
|
||||
{
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->config->set('HTML.TargetNoreferrer', true);
|
||||
$this->config->set('Attr.AllowedFrameTargets', '_blank');
|
||||
}
|
||||
|
||||
public function testNoreferrer()
|
||||
{
|
||||
$this->assertResult(
|
||||
'<a href="http://google.com" target="_blank">x</a>',
|
||||
'<a href="http://google.com" target="_blank" rel="noreferrer">x</a>'
|
||||
);
|
||||
}
|
||||
|
||||
public function testNoreferrerNoDupe()
|
||||
{
|
||||
$this->config->set('Attr.AllowedRel', 'noreferrer');
|
||||
$this->assertResult(
|
||||
'<a href="http://google.com" target="_blank" rel="noreferrer">x</a>',
|
||||
'<a href="http://google.com" target="_blank" rel="noreferrer">x</a>'
|
||||
);
|
||||
}
|
||||
|
||||
public function testTargetBlankNoreferrer()
|
||||
{
|
||||
$this->config->set('HTML.TargetBlank', true);
|
||||
$this->assertResult(
|
||||
'<a href="http://google.com">x</a>',
|
||||
'<a href="http://google.com" target="_blank" rel="noreferrer">x</a>'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
@ -189,7 +189,7 @@ class HTMLPurifier_Strategy_ValidateAttributesTest extends
|
||||
{
|
||||
$this->config->set('Attr.AllowedFrameTargets', '_top');
|
||||
$this->config->set('HTML.Doctype', 'XHTML 1.0 Transitional');
|
||||
$this->assertResult('<a href="foo" target="_top" />');
|
||||
$this->assertResult('<a href="foo" target="_top" rel="noreferrer" />');
|
||||
}
|
||||
|
||||
public function testRemoveTargetWhenNotSupported()
|
||||
|
Loading…
Reference in New Issue
Block a user