diff --git a/core/modules/editor/src/EditorXssFilter/Standard.php b/core/modules/editor/src/EditorXssFilter/Standard.php
index 310248d..63750aa 100644
--- a/core/modules/editor/src/EditorXssFilter/Standard.php
+++ b/core/modules/editor/src/EditorXssFilter/Standard.php
@@ -7,7 +7,11 @@
namespace Drupal\editor\EditorXssFilter;
+use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Utility\Xss;
+use Drupal\Component\Utility\Html;
+use Drupal\Component\Utility\String;
+use Drupal\Component\Utility\Unicode;
use Drupal\filter\FilterFormatInterface;
use Drupal\editor\EditorXssFilterInterface;
@@ -85,7 +89,30 @@ public static function filterXss($html, FilterFormatInterface $format, FilterFor
// Also blacklist tags that are explicitly forbidden in either text format.
$blacklisted_tags = array_merge($blacklisted_tags, $forbidden_tags);
- return static::filter($html, $blacklisted_tags);
+ $output = Xss::filter($html, $blacklisted_tags);
+
+ // Since data-*-attributes can contain encoded markup that could be decoded
+ // and interpreted by editors, we need to apply XSS filtering to their
+ // contents.
+ return Standard::filterXssDataAttributes($output);
+ }
+
+ /**
+ * Applies a very permissive XSS/HTML filter to data-attributes.
+ */
+ protected static function filterXssDataAttributes($html) {
+ if (stristr($html, 'data-') !== FALSE) {
+ $dom = Html::load($html);
+ $xpath = new \DOMXPath($dom);
+ foreach ($xpath->query('//@*[starts-with(name(.), "data-")]') as $node) {
+ $value = String::decodeEntities($node->value);
+ $value = Xss::filterAdmin($value);
+ $node->value = SafeMarkup::checkPlain($value);
+ }
+ $html = Html::serialize($dom);
+ }
+
+ return $html;
}
diff --git a/core/modules/filter/src/Plugin/Filter/FilterCaption.php b/core/modules/filter/src/Plugin/Filter/FilterCaption.php
index 32977ec..b68e6d3 100644
--- a/core/modules/filter/src/Plugin/Filter/FilterCaption.php
+++ b/core/modules/filter/src/Plugin/Filter/FilterCaption.php
@@ -9,6 +9,7 @@
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\SafeMarkup;
+use Drupal\Component\Utility\String;
use Drupal\Component\Utility\Unicode;
use Drupal\Component\Utility\Xss;
use Drupal\filter\FilterProcessResult;
@@ -39,12 +40,12 @@ public function process($text, $langcode) {
$xpath = new \DOMXPath($dom);
foreach ($xpath->query('//*[@data-caption]') as $node) {
// Read the data-caption attribute's value, then delete it.
- $caption = SafeMarkup::checkPlain($node->getAttribute('data-caption'));
+ $caption = String::checkPlain($node->getAttribute('data-caption'));
$node->removeAttribute('data-caption');
// Sanitize caption: decode HTML encoding, limit allowed HTML tags; only
// allow inline tags that are allowed by default, plus
.
- $caption = Html::decodeEntities($caption);
+ $caption = String::decodeEntities($caption);
$caption = Xss::filter($caption, array('a', 'em', 'strong', 'cite', 'code', 'br'));
// The caption must be non-empty.
diff --git a/core/modules/filter/src/Tests/FilterUnitTest.php b/core/modules/filter/src/Tests/FilterUnitTest.php
index a72a050..e25b2b4 100644
--- a/core/modules/filter/src/Tests/FilterUnitTest.php
+++ b/core/modules/filter/src/Tests/FilterUnitTest.php
@@ -10,6 +10,7 @@
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\String;
use Drupal\Component\Utility\Xss;
+use Drupal\editor\EditorXssFilter\Standard;
use Drupal\filter\FilterPluginCollection;
use Drupal\simpletest\KernelTestBase;
@@ -199,7 +200,7 @@ function testCaptionFilter() {
// Editor XSS filter.
$test_editor_xss_filter = function ($input) {
$allowed_tags = array('img');
- return Xss::filter($input, $allowed_tags);
+ return Standard::filter($input, $allowed_tags);
};
// All the tricky cases encountered at https://drupal.org/node/2105841.
@@ -235,10 +236,10 @@ function testCaptionFilter() {
$this->assertIdentical($expected, $test_with_html_filter($input));
$this->assertIdentical($input, $test_editor_xss_filter($input));
// An evil anchor (to ensure XSS filtering is applied to the caption also).
- $input = '
';
- $expected = '
This is an evil test…';
+ $input = '
';
+ $expected = '
This is an evil test…';
$this->assertIdentical($expected, $test_with_html_filter($input));
- $expected_xss_filtered = '
';
+ $expected_xss_filtered = '
';
$this->assertIdentical($expected_xss_filtered, $test_editor_xss_filter($input));
}