public static function Standard::filterXss in Drupal 10
Same name and namespace in other branches
- 8 core/modules/editor/src/EditorXssFilter/Standard.php \Drupal\editor\EditorXssFilter\Standard::filterXss()
- 9 core/modules/editor/src/EditorXssFilter/Standard.php \Drupal\editor\EditorXssFilter\Standard::filterXss()
Filters HTML to prevent XSS attacks when a user edits it in a text editor.
Should filter as minimally as possible, only to remove XSS attack vectors.
Is only called when:
- loading a non-XSS-safe text editor for a $format that contains a filter preventing XSS attacks (a FilterInterface::TYPE_HTML_RESTRICTOR filter): if the output is safe, it should also be safe to edit.
- loading a non-XSS-safe text editor for a $format that doesn't contain a filter preventing XSS attacks, but we're switching from a previous text format ($original_format is not NULL) that did prevent XSS attacks: if the output was previously safe, it should be safe to switch to another text format and edit.
Parameters
string $html: The HTML to be filtered.
\Drupal\filter\FilterFormatInterface $format: The text format configuration entity. Provides context based upon which one may want to adjust the filtering.
\Drupal\filter\FilterFormatInterface|null $original_format: (optional) The original text format configuration entity (when switching text formats/editors). Also provides context based upon which one may want to adjust the filtering.
Return value
string The filtered HTML that cannot cause any XSSes anymore.
Overrides EditorXssFilterInterface::filterXss
2 calls to Standard::filterXss()
- FilterKernelTest::testCaptionFilter in core/
modules/ filter/ tests/ src/ Kernel/ FilterKernelTest.php - Tests the caption filter.
- StandardTest::testFilterXss in core/
modules/ editor/ tests/ src/ Unit/ EditorXssFilter/ StandardTest.php - Tests the method for filtering XSS.
File
- core/
modules/ editor/ src/ EditorXssFilter/ Standard.php, line 18
Class
- Standard
- Defines the standard text editor XSS filter.
Namespace
Drupal\editor\EditorXssFilterCode
public static function filterXss($html, FilterFormatInterface $format, FilterFormatInterface $original_format = NULL) {
// Apply XSS filtering, but blacklist the <script>, <style>, <link>, <embed>
// and <object> tags.
// The <script> and <style> tags are blacklisted because their contents
// can be malicious (and therefore they are inherently unsafe), whereas for
// all other tags, only their attributes can make them malicious. Since
// \Drupal\Component\Utility\Xss::filter() protects against malicious
// attributes, we take no blacklisting action.
// The exceptions to the above rule are <link>, <embed> and <object>:
// - <link> because the href attribute allows the attacker to import CSS
// using the HTTP(S) protocols which Xss::filter() considers safe by
// default. The imported remote CSS is applied to the main document, thus
// allowing for the same XSS attacks as a regular <style> tag.
// - <embed> and <object> because these tags allow non-HTML applications or
// content to be embedded using the src or data attributes, respectively.
// This is safe in the case of HTML documents, but not in the case of
// Flash objects for example, that may access/modify the main document
// directly.
// <iframe> is considered safe because it only allows HTML content to be
// embedded, hence ensuring the same origin policy always applies.
$dangerous_tags = [
'script',
'style',
'link',
'embed',
'object',
];
// Simply blacklisting these five dangerous tags would bring safety, but
// also user frustration: what if a text format is configured to allow
// <embed>, for example? Then we would strip that tag, even though it is
// allowed, thereby causing data loss!
// Therefore, we want to be smarter still. We want to take into account
// which HTML tags are allowed by the text format we're filtering for, and
// if we're switching from another text format, we want to take that
// format's allowed tags into account as well.
// In other words: we only expect markup allowed in both the original and
// the new format to continue to exist.
$format_restrictions = $format
->getHtmlRestrictions();
if ($original_format !== NULL) {
$original_format_restrictions = $original_format
->getHtmlRestrictions();
}
// Any tags that are explicitly whitelisted by the text format must be
// removed from the list of default dangerous tags: if they're explicitly
// allowed, then we must respect that configuration.
// When switching from another format, we must use the intersection of
// allowed tags: if either format is more restrictive, then the safety
// expectations of *both* formats apply.
$allowed_tags = self::getAllowedTags($format_restrictions);
if ($original_format !== NULL) {
$allowed_tags = array_intersect($allowed_tags, self::getAllowedTags($original_format_restrictions));
}
// Don't blacklist dangerous tags that are explicitly allowed in both text
// formats.
$blacklisted_tags = array_diff($dangerous_tags, $allowed_tags);
$output = static::filter($html, $blacklisted_tags);
// Since data-attributes can contain encoded HTML markup that could be
// decoded and interpreted by editors, we need to apply XSS filtering to
// their contents.
return static::filterXssDataAttributes($output);
}