mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-02 22:28:37 +02:00
NEW Allow specifying element whitelist in HTMLText fields
This commit is contained in:
parent
30e3904e4c
commit
d6630d240a
13
docs/en/changelogs/rc/3.1.3-rc1.md
Normal file
13
docs/en/changelogs/rc/3.1.3-rc1.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# 3.1.3-rc1
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
* ExtraMeta fields can now only contain `meta` and `link` elements
|
||||||
|
|
||||||
|
## Upgrading
|
||||||
|
|
||||||
|
### ExtraMeta fields can now only contain `meta` and `link` elements
|
||||||
|
|
||||||
|
Previously ExtraMeta fields could contain any HTML elements. From 3.1.3-rc1 the contents are filtered
|
||||||
|
on write to only allow `meta` and `link` elements. The first time after upgrading that you save a page
|
||||||
|
that has other elements in ExtraMeta they will be deleted.
|
@ -34,12 +34,45 @@ class HTMLText extends Text {
|
|||||||
|
|
||||||
protected $processShortcodes = true;
|
protected $processShortcodes = true;
|
||||||
|
|
||||||
|
protected $whitelist = false;
|
||||||
|
|
||||||
|
public function __construct($name = null, $options = array()) {
|
||||||
|
if(is_string($options)) {
|
||||||
|
$options = array('whitelist' => $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::__construct($name, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $options
|
||||||
|
*
|
||||||
|
* Options accepted in addition to those provided by Text:
|
||||||
|
*
|
||||||
|
* - shortcodes: If true, shortcodes will be turned into the appropriate HTML.
|
||||||
|
* If false, shortcodes will not be processed.
|
||||||
|
*
|
||||||
|
* - whitelist: If provided, a comma-separated list of elements that will be allowed to be stored
|
||||||
|
* (be careful on relying on this for XSS protection - some seemingly-safe elements allow
|
||||||
|
* attributes that can be exploited, for instance <img onload="exploiting_code();" src="..." />)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
public function setOptions(array $options = array()) {
|
public function setOptions(array $options = array()) {
|
||||||
parent::setOptions($options);
|
parent::setOptions($options);
|
||||||
|
|
||||||
if(array_key_exists("shortcodes", $options)) {
|
if(array_key_exists("shortcodes", $options)) {
|
||||||
$this->processShortcodes = !!$options["shortcodes"];
|
$this->processShortcodes = !!$options["shortcodes"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(array_key_exists("whitelist", $options)) {
|
||||||
|
if(is_array($options['whitelist'])) {
|
||||||
|
$this->whitelist = $options['whitelist'];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$this->whitelist = preg_split('/,\s*/', $options['whitelist']);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -150,6 +183,23 @@ class HTMLText extends Text {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function prepValueForDB($value) {
|
||||||
|
if($this->whitelist) {
|
||||||
|
$dom = Injector::inst()->create('HTMLValue', $value);
|
||||||
|
|
||||||
|
$query = array();
|
||||||
|
foreach ($this->whitelist as $tag) $query[] = 'not(self::'.$tag.')';
|
||||||
|
|
||||||
|
foreach($dom->query('//body//*['.implode(' and ', $query).']') as $el) {
|
||||||
|
if ($el->parentNode) $el->parentNode->removeChild($el);
|
||||||
|
}
|
||||||
|
|
||||||
|
$value = $dom->getContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::prepValueForDB($value);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the field has meaningful content.
|
* Returns true if the field has meaningful content.
|
||||||
* Excludes null content like <h1></h1>, <p></p> ,etc
|
* Excludes null content like <h1></h1>, <p></p> ,etc
|
||||||
|
@ -176,4 +176,14 @@ class HTMLTextTest extends SapphireTest {
|
|||||||
$h->setValue("<p>test</p>");
|
$h->setValue("<p>test</p>");
|
||||||
$this->assertTrue($h->exists());
|
$this->assertTrue($h->exists());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testWhitelist() {
|
||||||
|
$textObj = new HTMLText('Test', 'meta,link');
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
$textObj->prepValueForDB('<meta content="Keep"><link href="Also Keep">'),
|
||||||
|
$textObj->prepValueForDB('<meta content="Keep"><p>Remove</p><link href="Also Keep" />'),
|
||||||
|
'Removes any elements not in whitelist'
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user