diff --git a/core/lib/Drupal/Component/Utility/Xss.php b/core/lib/Drupal/Component/Utility/Xss.php index a5fb9e0..5f8e981 100644 --- a/core/lib/Drupal/Component/Utility/Xss.php +++ b/core/lib/Drupal/Component/Utility/Xss.php @@ -192,7 +192,7 @@ protected static function attributes($attributes) { $mode = 0; $attribute_name = ''; $skip = FALSE; - $harmless = FALSE; + $skip_protocol_filtering = FALSE; while (strlen($attributes) != 0) { // Was the last operation successful? @@ -204,10 +204,22 @@ protected static function attributes($attributes) { if (preg_match('/^([-a-zA-Z]+)/', $attributes, $match)) { $attribute_name = strtolower($match[1]); $skip = ($attribute_name == 'style' || substr($attribute_name, 0, 2) == 'on'); - $harmless = substr($attribute_name, 0, 5) === 'data-' || in_array($attribute_name, array( + + // Values for attributes of type URI should be filtered for + // potentially malicious protocols (for example, an href-attribute + // starting with "javascript:"). + // However, for some non-URI attributes, performing this filtering + // actually causes valid and safe data to be mangled. To prevent + // this, we whitelist a number of non-URI attributes for which + // protocol filtering can be safely by-passed. + // + // @See \Drupal\Component\Utility\UrlHelper::filterBadProtocol() + // @See http://www.w3.org/TR/html4/index/attributes.html + $skip_protocol_filtering = substr($attribute_name, 0, 5) === 'data-' || in_array($attribute_name, array( 'title', 'alt', )); + $working = $mode = 1; $attributes = preg_replace('/^[-a-zA-Z]+/', '', $attributes); } @@ -233,7 +245,7 @@ protected static function attributes($attributes) { case 2: // Attribute value, a URL after href= for instance. if (preg_match('/^"([^"]*)"(\s+|$)/', $attributes, $match)) { - $thisval = $harmless ? $match[1] : UrlHelper::filterBadProtocol($match[1]); + $thisval = $skip_protocol_filtering ? $match[1] : UrlHelper::filterBadProtocol($match[1]); if (!$skip) { $attributes_array[] = "$attribute_name=\"$thisval\""; @@ -245,7 +257,7 @@ protected static function attributes($attributes) { } if (preg_match("/^'([^']*)'(\s+|$)/", $attributes, $match)) { - $thisval = $harmless ? $match[1] : UrlHelper::filterBadProtocol($match[1]); + $thisval = $skip_protocol_filtering ? $match[1] : UrlHelper::filterBadProtocol($match[1]); if (!$skip) { $attributes_array[] = "$attribute_name='$thisval'"; @@ -256,7 +268,7 @@ protected static function attributes($attributes) { } if (preg_match("%^([^\s\"']+)(\s+|$)%", $attributes, $match)) { - $thisval = $harmless ? $match[1] : UrlHelper::filterBadProtocol($match[1]); + $thisval = $skip_protocol_filtering ? $match[1] : UrlHelper::filterBadProtocol($match[1]); if (!$skip) { $attributes_array[] = "$attribute_name=\"$thisval\"";