Same name and namespace in other branches
  1. 4.6.x modules/filter.module \filter_xss_bad_protocol()
  2. 4.7.x modules/filter.module \filter_xss_bad_protocol()
  3. 6.x includes/bootstrap.inc \filter_xss_bad_protocol()
  4. 7.x includes/common.inc \filter_xss_bad_protocol()

Processes an HTML attribute value and ensures it does not contain an URL with a disallowed protocol (e.g. javascript:)

Parameters

$string: The string with the attribute value.

$decode: Whether to decode entities in the $string. Set to FALSE if the $string is in plain text, TRUE otherwise. Defaults to TRUE.

Return value

Cleaned up and HTML-escaped version of $string.

1 call to filter_xss_bad_protocol()
check_url in includes/common.inc
Prepare a URL for use in an HTML attribute. Strips harmful protocols.

File

modules/filter/filter.module, line 1491
Framework for handling filtering of content.

Code

function filter_xss_bad_protocol($string, $decode = TRUE) {
  static $allowed_protocols;
  if (!isset($allowed_protocols)) {
    $allowed_protocols = array_flip(variable_get('filter_allowed_protocols', array(
      'http',
      'https',
      'ftp',
      'news',
      'nntp',
      'telnet',
      'mailto',
      'irc',
      'ssh',
      'sftp',
      'webcal',
    )));
  }

  // Get the plain text representation of the attribute value (i.e. its meaning).
  if ($decode) {
    $string = decode_entities($string);
  }

  // Iteratively remove any invalid protocol found.
  do {
    $before = $string;
    $colonpos = strpos($string, ':');
    if ($colonpos > 0) {

      // We found a colon, possibly a protocol. Verify.
      $protocol = substr($string, 0, $colonpos);

      // If a colon is preceded by a slash, question mark or hash, it cannot
      // possibly be part of the URL scheme. This must be a relative URL,
      // which inherits the (safe) protocol of the base document.
      if (preg_match('![/?#]!', $protocol)) {
        break;
      }

      // Per RFC2616, section 3.2.3 (URI Comparison) scheme comparison must be case-insensitive.
      // Check if this is a disallowed protocol.
      if (!isset($allowed_protocols[strtolower($protocol)])) {
        $string = substr($string, $colonpos + 1);
      }
    }
  } while ($before != $string);
  return check_plain($string);
}