Standard::filterXss

public static Standard::filterXss($html, FilterFormatInterface $format, FilterFormatInterface $original_format = NULL)

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

File

core/modules/editor/src/EditorXssFilter/Standard.php, line 18

Class

Standard
Defines the standard text editor XSS filter.

Namespace

Drupal\editor\EditorXssFilter

Code

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 therefor 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 = array('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!
  // Therefor, we want to be smarter still. We want to take into account which
  // HTML tags are allowed and forbidden 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 and forbidden 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 blacklisted by the text format must be
  // appended to the list of default dangerous tags: if they're explicitly
  // forbidden, then we must respect that configuration.
  // When switching from another text format, we must use the union of
  // forbidden tags: if either text format is more restrictive, then the
  // safety expectations of *both* text formats apply.
  $forbidden_tags = self::getForbiddenTags($format_restrictions);
  if ($original_format !== NULL) {
    $forbidden_tags = array_merge($forbidden_tags, self::getForbiddenTags($original_format_restrictions));
  }

  // 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);

  // Also blacklist tags that are explicitly forbidden in either text format.
  $blacklisted_tags = array_merge($blacklisted_tags, $forbidden_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);
}
doc_Drupal
2016-10-29 09:43:53
Comments
Leave a Comment

Please login to continue.