<?php
/**
* This filter attempts to make HTML safe for viewing. IT IS NOT PERFECT. If
- * you enable HTML viewing, you are opening a security hole. With the current
- * state of the web, I believe that the best we can do is to make sure that
- * people *KNOW* HTML is a security hole, clean up what we can, and leave it
- * at that.
+ * you enable HTML viewing, you are opening a security hole.
*
* Filter parameters:
* ------------------
* <pre>
- * 'body_only' - (boolean) Only scan within the HTML body tags?
- * DEFAULT: true
+ * 'charset' - (string) The charset of the text.
+ * DEFAULT: UTF-8
* 'noprefetch' - (boolean) Disable DNS pre-fetching? See:
* https://developer.mozilla.org/En/Controlling_DNS_prefetching
* DEFAULT: false
- * 'replace' - (string) The string to replace filtered tags with.
- * DEFAULT: 'XSSCleaned'
+ * 'return_document' - (string) If true, returns a full HTML representation of
+ * the document.
+ * DEFAULT: false (returns the contents contained inside
+ * the BODY tag)
* 'strip_styles' - (boolean) Strip style tags?
* DEFAULT: true
- * 'strip_style_attributes' - (boolean) Strip style attributes in all HTML
- * tags?
+ * 'strip_style_attributes' - (boolean) Strip style attributes in all tags?
* DEFAULT: true
* </pre>
*
* did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
*
* @author Jan Schneider <jan@horde.org>
+ * @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @license http://www.fsf.org/copyleft/lgpl.html LGPL
* @package Text_Filter
* @var array
*/
protected $_params = array(
- 'body_only' => true,
+ 'charset' => 'UTF-8',
'noprefetch' => false,
- 'replace' => 'XSSCleaned',
+ 'return_document' => false,
'strip_styles' => true,
'strip_style_attributes' => true
);
/**
- * Stored CDATA information.
- *
- * @var string
- */
- protected $_cdata = array();
-
- /**
- * CDATA count.
- *
- * @var integer
- */
- protected $_cdatacount = 0;
-
- /**
* Returns a hash with replace patterns.
*
* @return array Patterns hash.
*/
public function getPatterns()
{
- $patterns = array();
-
- /* Remove all control characters. */
- $patterns['/[\x00-\x08\x0e-\x1f]/'] = '';
-
- /* Removes HTML comments (including some scripts & styles). */
- if ($this->_params['strip_styles']) {
- $patterns['/<!--.*?-->/s'] = '';
- }
-
- /* Change space entities to space characters. */
- $patterns['/&#(?:x0*20|0*32);?/i'] = ' ';
-
- /* If we have a semicolon, it is deterministically detectable and
- * fixable, without introducing collateral damage. */
- $patterns['/&#x?0*(?:[9A-D]|1[0-3]);/i'] = ' ';
-
- /* Hex numbers (usually having an x prefix) are also deterministic,
- * even if we don't have the semi. Note that some browsers will treat
- * &#a or �a as a hex number even without the x prefix; hence /x?/
- * which will cover those cases in this rule. */
- $patterns['/&#x?0*[9A-D]([^0-9A-F]|$)/i'] = ' \\1';
-
- /* Decimal numbers without trailing semicolons. The problem is that
- * some browsers will interpret 
a as "\na", some as "Ċ" so we
- * have to clean the 
 to be safe for the "\na" case at the expense
- * of mangling a valid entity in other cases. (Solution for valid HTML
- * authors: always use the semicolon.) */
- $patterns['/�*(?:9|1[0-3])([^0-9]|$)/i'] = ' \\1';
-
- /* Remove overly long numeric entities. */
- $patterns['/&#x?0*[0-9A-F]{6,};?/i'] = ' ';
-
- /* Remove everything outside of and including the <html> and <body>
- * tags. */
- if ($this->_params['body_only']) {
- $patterns['/^.*<(?:body|html)[^>]*>/si'] = '';
- $patterns['/<\/(?:body|html)>.*$/si'] = '';
- }
-
- /* Get all attribute="javascript:foo()" tags. This is essentially the
- * regex /(=|url\()("?)[^>]*script:/ but expanded to catch camouflage
- * with spaces and entities. */
- $preg = '/((=|�*61;?|�*3D;?)|' .
- '((u|�*85;?|�*55;?|�*117;?|�*75;?|\\\\0*75)\s*' .
- '(r|�*82;?|�*52;?|�*114;?|�*72;?|\\\\0*72)\s*' .
- '(l|�*76;?|�*4c;?|�*108;?|�*6c;?|\\\\0*6c)\s*' .
- '(\(|\\\\0*28)))\s*' .
- '(\'|�*34;?|�*22;?|"|�*39;?|�*27;?)?' .
- '[^>]*\s*' .
- '(s|�*83;?|�*53;?|�*115;?|�*73;?|\\\\0*73)\s*' .
- '(c|�*67;?|�*43;?|�*99;?|�*63;?|\\\\0*63)\s*' .
- '(r|�*82;?|�*52;?|�*114;?|�*72;?|\\\\0*72)\s*' .
- '(i|�*73;?|�*49;?|�*105;?|�*69;?|\\\\0*69)\s*' .
- '(p|�*80;?|�*50;?|�*112;?|�*70;?|\\\\0*70)\s*' .
- '(t|�*84;?|�*54;?|�*116;?|�*74;?|\\\\0*74)\s*' .
- '(:|�*58;?|�*3a;?|\\\\0*3a)/i';
- $patterns[$preg] = '\1\8' . $this->_params['replace'];
-
- /* Get all on<foo>="bar()". NEVER allow these. */
- $patterns['/([\s"\'\/]+' .
- '(o|�*79;?|�*4f;?|�*111;?|�*6f;?)' .
- '(n|�*78;?|�*4e;?|�*110;?|�*6e;?)' .
- '\w+)[^=a-z0-9"\'>]*=/i'] = '\1' . $this->_params['replace'] . '=';
-
- /* Remove all scripts since they might introduce garbage if they are
- * not quoted properly. */
- $patterns['|<script[^>]*>.*?</script>|is'] = '<' . $this->_params['replace'] . '_script />';
-
- /* Get all tags that might cause trouble - <object>, <embed>,
- * <applet>, etc. Meta refreshes and iframes, too. */
- $malicious = array(
- '/<([^>a-z]*)' .
- '(?:s|�*83;?|�*53;?|�*115;?|�*73;?)\s*' .
- '(?:c|�*67;?|�*43;?|�*99;?|�*63;?)\s*' .
- '(?:r|�*82;?|�*52;?|�*114;?|�*72;?)\s*' .
- '(?:i|�*73;?|�*49;?|�*105;?|�*69;?)\s*' .
- '(?:p|�*80;?|�*50;?|�*112;?|�*70;?)\s*' .
- '(?:t|�*84;?|�*54;?|�*116;?|�*74;?)/i',
-
- '/<([^>a-z]*)' .
- '(?:e|�*69;?|�*45;?|�*101;?|�*65;?)\s*' .
- '(?:m|�*77;?|�*4d;?|�*109;?|�*6d;?)\s*' .
- '(?:b|�*66;?|�*42;?|�*98;?|�*62;?)\s*' .
- '(?:e|�*69;?|�*45;?|�*101;?|�*65;?)\s*' .
- '(?:d|�*68;?|�*44;?|�*100;?|�*64;?)/i',
-
- '/<([^>a-z]*)' .
- '(?:x|�*88;?|�*58;?|�*120;?|�*78;?)\s*' .
- '(?:m|�*77;?|�*4d;?|�*109;?|�*6d;?)\s*' .
- '(?:l|�*76;?|�*4c;?|�*108;?|�*6c;?)/i',
-
- '/<([^>a-z]*)\?([^>a-z]*)' .
- '(?:i|�*73;?|�*49;?|�*105;?|�*69;?)\s*' .
- '(?:m|�*77;?|�*4d;?|�*109;?|�*6d;?)\s*' .
- '(?:p|�*80;?|�*50;?|�*112;?|�*70;?)\s*' .
- '(?:o|�*79;?|�*4f;?|�*111;?|�*6f;?)\s*' .
- '(?:r|�*82;?|�*52;?|�*114;?|�*72;?)\s*' .
- '(?:t|�*84;?|�*54;?|�*116;?|�*74;?)/i',
-
- '/<([^>a-z]*)' .
- '(?:m|�*77;?|�*4d;?|�*109;?|�*6d;?)\s*' .
- '(?:e|�*69;?|�*45;?|�*101;?|�*65;?)\s*' .
- '(?:t|�*84;?|�*54;?|�*116;?|�*74;?)\s*' .
- '(?:a|�*65;?|�*41;?|�*97;?|�*61;?)/i',
-
- '/<([^>a-z]*)' .
- '(?:j|�*74;?|�*4a;?|�*106;?|�*6a;?)\s*' .
- '(?:a|�*65;?|�*41;?|�*97;?|�*61;?)\s*' .
- '(?:v|�*86;?|�*56;?|�*118;?|�*76;?)\s*' .
- '(?:a|�*65;?|�*41;?|�*97;?|�*61;?)/i',
-
- '/<([^>a-z]*)' .
- '(?:o|�*79;?|�*4f;?|�*111;?|�*6f;?)\s*' .
- '(?:b|�*66;?|�*42;?|�*98;?|�*62;?)\s*' .
- '(?:j|�*74;?|�*4a;?|�*106;?|�*6a;?)\s*' .
- '(?:e|�*69;?|�*45;?|�*101;?|�*65;?)\s*' .
- '(?:c|�*67;?|�*43;?|�*99;?|�*63;?)\s*' .
- '(?:t|�*84;?|�*54;?|�*116;?|�*74;?)/i',
-
- '/<([^>a-z]*)' .
- '(?:a|�*65;?|�*41;?|�*97;?|�*61;?)\s*' .
- '(?:p|�*80;?|�*50;?|�*112;?|�*70;?)\s*' .
- '(?:p|�*80;?|�*50;?|�*112;?|�*70;?)\s*' .
- '(?:l|�*76;?|�*4c;?|�*108;?|�*6c;?)\s*' .
- '(?:e|�*69;?|�*45;?|�*101;?|�*65;?)\s*' .
- '(?:t|�*84;?|�*54;?|�*116;?|�*74;?)/i',
-
- '/<([^>a-z]*)' .
- '(?:l|�*76;?|�*4c;?|�*108;?|�*6c;?)\s*' .
- '(?:a|�*65;?|�*41;?|�*97;?|�*61;?)\s*' .
- '(?:y|�*89;?|�*59;?|�*121;?|�*79;?)\s*' .
- '(?:e|�*69;?|�*45;?|�*101;?|�*65;?)\s*' .
- '(?:r|�*82;?|�*52;?|�*114;?|�*72;?)/i',
-
- '/<([^>a-z]*)' .
- '(?:i|�*73;?|�*49;?|�*105;?|�*69;?)?\s*' .
- '(?:f|�*70;?|�*46;?|�*102;?|�*66;?)\s*' .
- '(?:r|�*82;?|�*52;?|�*114;?|�*72;?)\s*' .
- '(?:a|�*65;?|�*41;?|�*97;?|�*61;?)\s*' .
- '(?:m|�*77;?|�*4d;?|�*109;?|�*6d;?)\s*' .
- '(?:e|�*69;?|�*45;?|�*101;?|�*65;?)/i');
-
- foreach ($malicious as $pattern) {
- $patterns[$pattern] = '<$1' . $this->_params['replace'] . '_tag';
- }
-
- /* Comment out style/link tags. */
- if ($this->_params['strip_styles']) {
- if ($this->_params['strip_style_attributes']) {
- $patterns['/(\s+|([\'"]))style\s*=/i'] = '$2 ' . $this->_params['replace'] . '=';
- }
- $patterns['|<style[^>]*>(?:\s*<\!--)*|i'] = '<!--';
- $patterns['|(?:-->\s*)*</style>|i'] = '-->';
- $patterns['|(<link[^>]*>)|i'] = '<!-- $1 -->';
-
- /* We primarily strip out <base> tags due to styling concerns.
- * There is a security issue with HREF tags, but the 'javascript'
- * search/replace code sufficiently filters these strings. */
- $patterns['|(<base[^>]*>)|i'] = '<!-- $1 -->';
- }
-
- /* A few other matches. */
- $patterns['|<([^>]*)&{.*}([^>]*)>|'] = '<\1&{;}\2>';
- $patterns['|<([^>]*)mocha:([^>]*)>|i'] = '<\1' . $this->_params['replace'] . ':\2>';
- $patterns['/<(([^>]*)|(style[^>]*>[^<]*))binding:((?(3)[^<]*<\/style)[^>]*)>/i'] = '<\1' . $this->_params['replace'] . ':\4>';
-
- return array('regexp' => $patterns);
- }
-
- /**
- * Executes any code necessary before applying the filter patterns.
- *
- * @param string $text The text before the filtering.
- *
- * @return string The modified text.
- */
- public function preProcess($text)
- {
- // As of PHP 5.2, backtrack limits have been set to an unreasonably
- // low number. The body check will often times trigger backtrack
- // errors so up the backtrack limit if we are doing this match.
- if ($this->_params['body_only'] && ini_get('pcre.backtrack_limit')) {
- ini_set('pcre.backtrack_limit', 5000000);
- }
-
- // Remove and store CDATA data.
- $text = preg_replace_callback('/<!\[CDATA\[.*?\]\]>/is', array($this, '_preProcessCallback'), $text);
-
- return $text;
- }
-
- /**
- * Preg callback for preProcess().
- *
- * @param array $matches The list of matches.
- *
- * @return string The replacement text.
- */
- protected function _preProcessCallback($matches)
- {
- $this->_cdata[] = $matches[0];
- return '<HORDE_CDATA' . $this->_cdatacount++ . ' />';
+ return array('regexp' => array(
+ /* Remove all control characters. */
+ '/[\x00-\x08\x0e-\x1f]/' => '',
+
+ /* Change space entities to space characters. */
+ '/&#(?:x0*20|0*32);?/i' => ' ',
+
+ /* If we have a semicolon, it is deterministically detectable and
+ * fixable, without introducing collateral damage. */
+ '/&#x?0*(?:[9A-D]|1[0-3]);/i' => ' ',
+
+ /* Hex numbers (usually having an x prefix) are also deterministic,
+ * even if we don't have the semi. Note that some browsers will
+ * treat &#a or �a as a hex number even without the x prefix;
+ * hence /x?/ which will cover those cases in this rule. */
+ '/&#x?0*[9A-D]([^0-9A-F]|$)/i' => ' \\1',
+
+ /* Decimal numbers without trailing semicolons. The problem is
+ * that some browsers will interpret 
a as "\na", some as
+ * "Ċ" so we have to clean the 
 to be safe for the "\na"
+ * case at the expense of mangling a valid entity in other cases.
+ * (Solution for valid HTML authors: always use the semicolon.) */
+ '/�*(?:9|1[0-3])([^0-9]|$)/i' => ' \\1',
+
+ /* Remove overly long numeric entities. */
+ '/&#x?0*[0-9A-F]{6,};?/i' => ' '
+ ));
}
/**
*/
public function postProcess($text)
{
- /* Strip out data URLs living in an A HREF element (Bug #8715).
- * Done here because we need to match more than 1 possible data
- * entry per tag. */
- $data_from = '/<((?:a|�*65;?|�*41;?|�*97;?|�*61;?)\b[^>]+?)' .
- '(?:h|�*72;?|�*48;?|�*104;?|�*68;?)\s*' .
- '(?:r|�*82;?|�*52;?|�*114;?|�*72;?)\s*' .
- '(?:e|�*69;?|�*45;?|�*101;?|�*65;?)\s*' .
- '(?:f|�*70;?|�*46;?|�*102;?|�*66;?)\s*=' .
- '("|\')?\s*data:(?(2)[^"\')>]*|[^\s)>]*)(?(2)\\2)/is';
- $data_to = '<$1';
- do {
- $text = preg_replace($data_from, $data_to, $text, -1, $count);
- } while ($count);
+ if (!extension_loaded('dom')) {
+ return $text;
+ }
+
+ $old_error = libxml_use_internal_errors(true);
+ $doc = new DOMDocument();
+ $doc->loadHTML($text);
+ if ($old_error) {
+ libxml_use_internal_errors(false);
+ }
- ini_restore('pcre.backtrack_limit');
+ $this->_node($doc, $doc);
- // Restore CDATA data
- if ($this->_cdatacount) {
- $text = preg_replace_callback('/<HORDE_CDATA(\d+) \/>/', array($this, '_postProcessCallback'), $text);
- $this->_cdata = array();
- $this->_cdatacount = 0;
+ if (!$this->_params['return_document']) {
+ $body = $doc->getElementsByTagName('body')->item(0);
}
if ($this->_params['noprefetch']) {
- if (preg_match('/<head[^>]*>/si', $text, $matches, PREG_OFFSET_CAPTURE)) {
- $end = $matches[0][1] + strlen($matches[0][0]);
- $text = substr($text, 0, $end) .
- '<meta http-equiv="x-dns-prefetch-control" content="off" />' .
- substr($text, $end);
- } else {
- $text = '<meta http-equiv="x-dns-prefetch-control" content="off" />' . $text;
+ $meta = $doc->createElement('meta');
+ $meta->setAttribute('http-equiv', 'x-dns-prefetch-control');
+ $meta->setAttribute('value-equiv', 'off');
+
+ if ($this->_params['return_document']) {
+ $doc->getElementsByTagName('head')->item(0)->appendChild($meta);
+ } elseif ($body) {
+ $body->appendChild($meta);
+ }
+ }
+
+ $text = '';
+ if ($this->_params['return_document']) {
+ $text = $doc->saveHTML();
+ } elseif ($body && $body->hasChildNodes()) {
+ foreach ($body->childNodes as $child) {
+ $text .= $doc->saveXML($child);
}
}
- return $text;
+ return Horde_String::convertCharset($text, $doc->encoding, $this->_params['charset']);
}
/**
- * Preg callback for preProcess().
+ * Process DOM node.
*
- * @param array $matches The list of matches.
+ * @param DOMDocument $doc Document node.
+ * @param DOMElement $node Element node.
*
- * @return string The replacement text.
+ * @return string The plaintext representation.
*/
- protected function _postProcessCallback($matches)
+ protected function _node($doc, $node)
{
- return $this->_cdata[$matches[1]];
+ if ($node->hasChildNodes()) {
+ foreach ($node->childNodes as $child) {
+ if ($child instanceof DOMElement) {
+ switch (strtolower($child->tagName)) {
+ case 'a':
+ /* Strip out data URLs living in an A HREF element
+ * (Bug #8715). */
+ if ($child->hasAttribute('href') &&
+ preg_match("/\s*data:/i", $child->getAttribute('href'))) {
+ $child->removeAttribute('href');
+ }
+ break;
+
+ case 'applet':
+ case 'embed':
+ case 'iframe':
+ case 'import':
+ case 'java':
+ case 'layer':
+ case 'meta':
+ case 'object':
+ case 'script':
+ case 'xml':
+ /* Remove all tags that might cause trouble. */
+ $node->removeChild($child);
+ continue 2;
+
+ case 'base':
+ case 'link':
+ case 'style':
+ /* We primarily strip out <base> tags due to styling
+ * concerns. There is a security issue with HREF tags,
+ * but the 'javascript' search/replace code
+ * sufficiently filters these strings. */
+ if ($this->_params['strip_styles']) {
+ $node->removeChild($child);
+ continue 2;
+ }
+ break;
+
+ case 'set':
+ /* I believe this attack only works on old browsers.
+ * But makes no sense allowing HTML to try to set
+ * innerHTML anyway. */
+ if ($child->hasAttribute('attributename') &&
+ (strcasecmp($child->getAttribute('attributename'), 'innerHTML') === 0)) {
+ $node->removeChild($child);
+ continue 2;
+ }
+ }
+
+ $remove = $this->_params['strip_style_attributes']
+ ? array('style')
+ : array();
+
+ foreach ($child->attributes as $val) {
+ /* Never allow on<foo>="bar()",
+ * attribute="[mocha|*script]:foo()", or
+ * attribute="&{...}". */
+ if ((stripos(ltrim($val->name), 'on') === 0) ||
+ preg_match("/^\s*(?:mocha:|[^:]+script:|&{)/i", $val->value)) {
+ $remove[] = $val->name;
+ }
+ }
+
+ foreach ($remove as $val) {
+ $child->removeAttribute($val);
+ }
+
+ //$patterns['/<(([^>]*)|(style[^>]*>[^<]*))binding:((?(3)[^<]*<\/style)[^>]*)>/i'] = '<\1' . $this->_params['replace'] . ':\4>';
+ } elseif ($child instanceof DOMComment) {
+ /* Remove HTML comments (including some scripts &
+ * styles). */
+ if ($this->_params['strip_styles']) {
+ $node->removeChild($child);
+ continue;
+ }
+ }
+
+ $this->_node($doc, $child);
+ }
+ }
}
}
require dirname(__FILE__) . '/../../../../lib/Horde/Text/Filter.php';
require dirname(__FILE__) . '/../../../../lib/Horde/Text/Filter/Base.php';
require dirname(__FILE__) . '/../../../../lib/Horde/Text/Filter/Xss.php';
+require dirname(__FILE__) . '/../../../../../Util/lib/Horde/String.php';
+require dirname(__FILE__) . '/../../../../../Util/lib/Horde/Util.php';
foreach (glob(dirname(__FILE__) . '/fixtures/xss*.html') as $file) {
- $data = file_get_contents($file);
- echo basename($file) . "\n";
- echo Horde_Text_Filter::filter($data, 'xss', array('body_only' => false));
+ echo basename($file) . "\n" .
+ Horde_Text_Filter::filter(file_get_contents($file), 'xss') .
+ "\n";
}
foreach (glob(dirname(__FILE__) . '/fixtures/style_xss*.html') as $file) {
- $data = file_get_contents($file);
- echo basename($file) . "\n";
- echo Horde_Text_Filter::filter($data, 'xss', array('body_only' => false, 'strip_styles' => false));
+ echo basename($file) . "\n" .
+ Horde_Text_Filter::filter(file_get_contents($file), 'xss', array(
+ 'strip_styles' => false
+ )) .
+ "\n";
}
?>
--EXPECT--
xss01.html
-<XSSCleaned_script />
+
xss02.html
-<IMG SRC="XSSCleanedalert('XSS');">
+<img/>
xss03.html
-<IMG SRC=XSSCleanedalert('XSS')>
+<img/>
xss04.html
-<IMG SRC=XSSCleanedalert('XSS')>
+<img/>
xss05.html
-<IMG SRC=XSSCleanedalert("XSS")>
+<img/>
xss06.html
-<IMG SRC=XSSCleanedalert("RSnake says, 'XSS'")`>
+<img says=""/>
xss07.html
-<IMG """><XSSCleaned_script />">
+<img/>">
+
xss08.html
-<IMG SRC=XSSCleanedalert(String.fromCharCode(88,83,83))>
+<img/>
xss09.html
-<IMG SRC=XSSCleanedalert('XSS')>
+<img/>
xss10.html
-<IMG SRC= >
+<img src="                       "/>
xss100.html
-<img src='blank.jpg' XSSCleaned='width:expression(alert("xssed"))'>
+<img src="blank.jpg"/>
xss11.html
-<IMG SRC=XSSCleanedalert('XSS')>
+<img/>
xss12.html
-<IMG SRC="XSSCleanedalert('XSS');">
+<img/>
xss13.html
-<IMG SRC="XSSCleanedalert('XSS');">
+<img/>
xss14.html
-<IMG SRC="XSSCleanedalert('XSS');">
+<img/>
xss15.html
-<IMG SRC="XSSCleanedalert('XSS');">
+<img/>
xss16.html
-<IMG
-SRC
-=XSSCleaned
-a
-l
-e
-r
-t
-(
-'
-X
-S
-S
-'
-)
-"
->
+<img src="j" a="" v="" s="" c="" r="" i="" p="" t="" :="" l="" e="" x=""/>
xss17.html
-<IMG SRC=XSSCleanedalert("XSS")>
+<img/>
xss18.html
-<XSSCleaned_script />
+
xss19.html
-<IMG SRC="XSSCleanedalert('XSS');">
+<img src=" "/>
xss20.html
-<XSSCleaned_script />
+
xss21.html
-<BODY onloadXSSCleaned=alert("XSS")>
+
xss22.html
-<XSSCleaned_script />
+
xss23.html
-<<XSSCleaned_script />
+<p>alert("XSS");//</p>
xss24.html
-<XSSCleaned_tag SRC=http://ha.ckers.org/xss.js?<B>
+
xss25.html
-<XSSCleaned_tag SRC=//ha.ckers.org/.j>
+
xss26.html
-<IMG SRC="XSSCleanedalert('XSS')"
+<img/>
xss27.html
-<XSSCleaned_tag src=http://ha.ckers.org/scriptlet.html <
+
xss28.html
-<XSSCleaned_script />
+
xss29.html
-</TITLE><XSSCleaned_script />
+
xss30.html
-<INPUT TYPE="XSSCleanedalert('XSS');">
+<input type="IMAGE"/>
xss31.html
-<BODY BACKGROUND="XSSCleanedalert('XSS')">
+
xss32.html
-<BODY ONLOADXSSCleaned=alert('XSS')>
+
xss33.html
-<IMG DYNSRC="XSSCleanedalert('XSS')">
+<img/>
xss34.html
-<IMG LOWSRC="XSSCleanedalert('XSS')">
+<img/>
xss35.html
-<BGSOUND SRC="XSSCleanedalert('XSS');">
+<bgsound/>
xss36.html
-<BR SIZE="&{;}">
+<br/>
xss37.html
-<XSSCleaned_tag SRC="http://ha.ckers.org/scriptlet.html"></XSSCleaned_tag>
+
xss38.html
-<!-- <LINK REL="XSSCleanedalert('XSS');"> -->
+
xss39.html
-<!-- <LINK REL="stylesheet" HREF="http://ha.ckers.org/xss.css"> -->
+
xss40.html
-<!--@import'http://ha.ckers.org/xss.css';-->
+
xss41.html
-<XSSCleaned_tag HTTP-EQUIV="Link" Content="<http://ha.ckers.org/xss.css>; REL=stylesheet">
+
xss42.html
-<!--BODY{-moz-XSSCleaned:url("http://ha.ckers.org/xssmoz.xml#xss")}-->
+
xss43.html
-<XSS XSSCleaned="behavior: url(xss.htc);">
+<xss/>
xss44.html
-<!--li {list-style-image: url("XSSCleanedalert('XSS')");}--><UL><LI>XSS
+<ul><li>XSS
+</li></ul>
xss45.html
-<IMG SRC='XSSCleanedmsgbox("XSS")'>
+<img/>
xss46.html
-<IMG SRC="XSSCleaned:[code]">
+<img/>
xss47.html
-<IMG SRC="XSSCleaned[code]">
+<img/>
xss48.html
-<XSSCleaned_tag HTTP-EQUIV="XSSCleanedalert('XSS');">
+
xss49.html
-<XSSCleaned_tag HTTP-EQUIV="refresh" CONTENT="0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K">
+
xss50.html
-<XSSCleaned_tag HTTP-EQUIV="XSSCleanedalert('XSS');">
+
xss51.html
-<XSSCleaned_tag SRC=XSSCleanedalert('XSS')></XSSCleaned_tag>
+
xss52.html
-<XSSCleaned_tagSET><XSSCleaned_tag SRC=XSSCleanedalert('XSS')></XSSCleaned_tag></XSSCleaned_tagSET>
+
xss53.html
-<TABLE BACKGROUND="XSSCleanedalert('XSS')">
+<table/>
xss54.html
-<TABLE><TD BACKGROUND="XSSCleanedalert('XSS')">
+<table><td/></table>
xss55.html
-<DIV XSSCleaned="XSSCleanedalert('XSS'))">
+<div/>
xss56.html
-<DIV XSSCleaned="XSSCleaned\0061\006c\0065\0072\0074\0028.1027\0058.1053\0053\0027\0029'\0029">
+<div/>
xss57.html
-<DIV XSSCleaned="XSSCleanedalert('XSS'))">
+<div/>
xss58.html
-<DIV XSSCleaned="width: expression(alert('XSS'));">
+<div/>
xss59.html
-<!--@im\port'\ja\vasc\ript:alert("XSS")';-->
+
xss60.html
-<IMG XSSCleaned="xss:expr/*XSS*/ession(alert('XSS'))">
+<img/>
xss61.html
-<XSS XSSCleaned="xss:expression(alert('XSS'))">
+<xss/>
xss62.html
-exp/*<A XSSCleaned='no\xss:noxss("*//*");
-xss:ex/*XSS*//*/*/pression(alert("XSS"))'>
+<p>exp/*<a/></p>
xss63.html
-<!--alert('XSS');-->
+
xss64.html
-<!--.XSS{background-image:url("XSSCleanedalert('XSS')");}--><A CLASS=XSS></A>
+
xss65.html
-<!--BODY{background:url("XSSCleanedalert('XSS')")}-->
+
xss66.html
xss67.html
-<!-- <BASE HREF="XSSCleanedalert('XSS');//"> -->
+
xss68.html
-<XSSCleaned_tag TYPE="text/x-scriptlet" DATA="http://ha.ckers.org/scriptlet.html"></XSSCleaned_tag>
+
xss69.html
-<XSSCleaned_tag classid=clsid:ae24fdae-03c6-11d1-8b76-0080c744f389><param name=XSSCleanedalert('XSS')></XSSCleaned_tag>
+
xss70.html
-<XSSCleaned_tag SRC="http://ha.ckers.org/xss.swf" AllowScriptAccess="always"></XSSCleaned_tag>
+
xss71.html
-<XSSCleaned_tag SRC="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==" type="image/svg+xml" AllowScriptAccess="always"></XSSCleaned_tag>
+
xss72.html
-<HTML xmlns:xss>
- <XSSCleaned_tag namespace="xss" implementation="http://ha.ckers.org/xss.htc">
- <xss:xss>XSS</xss:xss>
-</HTML>
+<xss>XSS</xss>
xss73.html
-<XSSCleaned_tag ID=I><X><C><![CDATA[<IMG SRC="javas]]><![CDATA[cript:alert('XSS');">]]>
-</C></X></XSSCleaned_tag><SPAN DATASRC=#I DATAFLD=C DATAFORMATAS=HTML></SPAN>
+<span datasrc="#I" datafld="C" dataformatas="HTML"/>
xss74.html
-<XSSCleaned_tag ID="xss"><I><B><IMG SRC="XSSCleanedalert('XSS')"></B></I></XSSCleaned_tag>
-<SPAN DATASRC="#xss" DATAFLD="B" DATAFORMATAS="HTML"></SPAN>
+<span datasrc="#xss" datafld="B" dataformatas="HTML"/>
xss75.html
-<XSSCleaned_tag SRC="xsstest.xml" ID=I></XSSCleaned_tag>
-<SPAN DATASRC=#I DATAFLD=C DATAFORMATAS=HTML></SPAN>
+<span datasrc="#I" datafld="C" dataformatas="HTML"/>
xss76.html
-<HTML><BODY>
-<?XSSCleaned_tag:namespace prefix="t" ns="urn:schemas-microsoft-com:time">
-<XSSCleaned_tag namespace="t" implementation="#default#time2">
-<t:set attributeName="innerHTML" to="XSS<SCRIPT DEFER>alert("XSS")</SCRIPT>">
-</BODY></HTML>
+
+
xss77.html
-<XSSCleaned_tag SRC="http://ha.ckers.org/xss.jpg"><XSSCleaned_tag>
+
xss78.html
-<IMG SRC="XSSCleanedalert('XSS')"
+<img/>
xss79.html
-<XSSCleaned_script />
+
xss80.html
-<XSSCleaned_script />
+
xss81.html
-<XSSCleaned_script />
+
xss82.html
-<XSSCleaned_script />
+
xss83.html
-<XSSCleaned_script />
+
xss84.html
-<XSSCleaned_script />
+
xss85.html
-<XSSCleaned_script />PT SRC="http://ha.ckers.org/a.js"></XSSCleaned_tag>
+<p>PT SRC="http://ha.ckers.org/a.js"></p>
xss95.html
-<a >Click me</a>
+<a>Click me</a>
xss96.html
-<a >Click me</a>
+<a>Click me</a>
xss97.html
-<body/onloadXSSCleaned=alert(/xss/)>
+
xss98.html
-<XSSCleaned_tagset rows="15,15,15,15,15,15,15,15,15,*">
-<XSSCleaned_tag src="mailbox.php?page=1&actionID=delete_messages&targetMbox=&newMbox=0&flag=&indices%5B%5D=199&indices%5B%5D=200&indices%5B%5D=201&indices%5B%5D=202&indices%5B%5D=203&indices%5B%5D=204&indices%5B%5D=205&indices%5B%5D=206&indices%5B%5D=207&indices%5B%5D=208&indices%5B%5D=209&indices%5B%5D=210&indices%5B%5D=211&indices%5B%5D=212&indices%5B%5D=213&indices%5B%5D=214&indices%5B%5D=215&indices%5B%5D=216&indices%5B%5D=217&indices%5B%5D=218&indices%5B%5D=219&indices%5B%5D=220&indices%5B%5D=221&indices%5B%5D=222&indices%5B%5D=223&indices%5B%5D=224&indices%5B%5D=225&indices%5B%5D=226&indices%5B%5D=227&indices%5B%5D=228&indices%5B%5D=229&indices%5B%5D=230&indices%5B%5D=231&indices%5B%5D=232&indices%5B%5D=233&indices%5B%5D=234&indices%5B%5D=235&indices%5B%5D=236&indices%5B%5D=237&indices%5B%5D=238&indices%5B%5D=239&indices%5B%5D=240&indices%5B%5D=241&indices%5B%5D=242&indices%5B%5D=243&indices%5B%5D=244&indices%5B%5D=245&indices%5B%5D=246&indices%5B%5D=247&indices%5B%5D=248&indices%5B%5D=249&indices%5B%5D=250&indices%5B%5D=251&indices%5B%5D=252&indices%5B%5D=253&indices%5B%5D=254&indices%5B%5D=255&indices%5B%5D=256&indices%5B%5D=257&indices%5B%5D=258&indices%5B%5D=259&indices%5B%5D=260&indices%5B%5D=261&indices%5B%5D=262&indices%5B%5D=263&indices%5B%5D=264&indices%5B%5D=265&indices%5B%5D=266&indices%5B%5D=267&indices%5B%5D=268&indices%5B%5D=269&indices%5B%5D=270&indices%5B%5D=271&indices%5B%5D=272&indices%5B%5D=273&indices%5B%5D=274&indices%5B%5D=275&indices%5B%5D=276&indices%5B%5D=277&indices%5B%5D=278&indices%5B%5D=279&indices%5B%5D=280&indices%5B%5D=281&indices%5B%5D=282&indices%5B%5D=283&indices%5B%5D=284&indices%5B%5D=285&indices%5B%5D=286&indices%5B%5D=287&indices%5B%5D=288&indices%5B%5D=289&indices%5B%5D=290&indices%5B%5D=291&indices%5B%5D=292&indices%5B%5D=293&indices%5B%5D=294&indices%5B%5D=295&indices%5B%5D=296&indices%5B%5D=297&indices%5B%5D=298">
-<XSSCleaned_tag src="mailbox.php?page=1&actionID=delete_messages&targetMbox=&newMbox=0&flag=&indices%5B%5D=299&indices%5B%5D=300&indices%5B%5D=301&indices%5B%5D=302&indices%5B%5D=303&indices%5B%5D=304&indices%5B%5D=305&indices%5B%5D=306&indices%5B%5D=307&indices%5B%5D=308&indices%5B%5D=309&indices%5B%5D=310&indices%5B%5D=311&indices%5B%5D=312&indices%5B%5D=313&indices%5B%5D=314&indices%5B%5D=315&indices%5B%5D=316&indices%5B%5D=317&indices%5B%5D=318&indices%5B%5D=319&indices%5B%5D=320&indices%5B%5D=321&indices%5B%5D=322&indices%5B%5D=323&indices%5B%5D=324&indices%5B%5D=325&indices%5B%5D=326&indices%5B%5D=327&indices%5B%5D=328&indices%5B%5D=329&indices%5B%5D=330&indices%5B%5D=331&indices%5B%5D=332&indices%5B%5D=333&indices%5B%5D=334&indices%5B%5D=335&indices%5B%5D=336&indices%5B%5D=337&indices%5B%5D=338&indices%5B%5D=339&indices%5B%5D=340&indices%5B%5D=341&indices%5B%5D=342&indices%5B%5D=343&indices%5B%5D=344&indices%5B%5D=345&indices%5B%5D=346&indices%5B%5D=347&indices%5B%5D=348&indices%5B%5D=349&indices%5B%5D=350&indices%5B%5D=351&indices%5B%5D=352&indices%5B%5D=353&indices%5B%5D=354&indices%5B%5D=355&indices%5B%5D=356&indices%5B%5D=357&indices%5B%5D=358&indices%5B%5D=359&indices%5B%5D=360&indices%5B%5D=361&indices%5B%5D=362&indices%5B%5D=363&indices%5B%5D=364&indices%5B%5D=365&indices%5B%5D=366&indices%5B%5D=367&indices%5B%5D=368&indices%5B%5D=369&indices%5B%5D=370&indices%5B%5D=371&indices%5B%5D=372&indices%5B%5D=373&indices%5B%5D=374&indices%5B%5D=375&indices%5B%5D=376&indices%5B%5D=377&indices%5B%5D=378&indices%5B%5D=379&indices%5B%5D=380&indices%5B%5D=381&indices%5B%5D=382&indices%5B%5D=383&indices%5B%5D=384&indices%5B%5D=385&indices%5B%5D=386&indices%5B%5D=387&indices%5B%5D=388&indices%5B%5D=389&indices%5B%5D=390&indices%5B%5D=391&indices%5B%5D=392&indices%5B%5D=393&indices%5B%5D=394&indices%5B%5D=395&indices%5B%5D=396&indices%5B%5D=397&indices%5B%5D=398">
-<XSSCleaned_tag src="mailbox.php?page=1&actionID=delete_messages&targetMbox=&newMbox=0&flag=&indices%5B%5D=399&indices%5B%5D=400&indices%5B%5D=401&indices%5B%5D=402&indices%5B%5D=403&indices%5B%5D=404&indices%5B%5D=405&indices%5B%5D=406&indices%5B%5D=407&indices%5B%5D=408&indices%5B%5D=409&indices%5B%5D=410&indices%5B%5D=411&indices%5B%5D=412&indices%5B%5D=413&indices%5B%5D=414&indices%5B%5D=415&indices%5B%5D=416&indices%5B%5D=417&indices%5B%5D=418&indices%5B%5D=419&indices%5B%5D=420&indices%5B%5D=421&indices%5B%5D=422&indices%5B%5D=423&indices%5B%5D=424&indices%5B%5D=425&indices%5B%5D=426&indices%5B%5D=427&indices%5B%5D=428&indices%5B%5D=429&indices%5B%5D=430&indices%5B%5D=431&indices%5B%5D=432&indices%5B%5D=433&indices%5B%5D=434&indices%5B%5D=435&indices%5B%5D=436&indices%5B%5D=437&indices%5B%5D=438&indices%5B%5D=439&indices%5B%5D=440&indices%5B%5D=441&indices%5B%5D=442&indices%5B%5D=443&indices%5B%5D=444&indices%5B%5D=445&indices%5B%5D=446&indices%5B%5D=447&indices%5B%5D=448&indices%5B%5D=449&indices%5B%5D=450&indices%5B%5D=451&indices%5B%5D=452&indices%5B%5D=453&indices%5B%5D=454&indices%5B%5D=455&indices%5B%5D=456&indices%5B%5D=457&indices%5B%5D=458&indices%5B%5D=459&indices%5B%5D=460&indices%5B%5D=461&indices%5B%5D=462&indices%5B%5D=463&indices%5B%5D=464&indices%5B%5D=465&indices%5B%5D=466&indices%5B%5D=467&indices%5B%5D=468&indices%5B%5D=469&indices%5B%5D=470&indices%5B%5D=471&indices%5B%5D=472&indices%5B%5D=473&indices%5B%5D=474&indices%5B%5D=475&indices%5B%5D=476&indices%5B%5D=477&indices%5B%5D=478&indices%5B%5D=479&indices%5B%5D=480&indices%5B%5D=481&indices%5B%5D=482&indices%5B%5D=483&indices%5B%5D=484&indices%5B%5D=485&indices%5B%5D=486&indices%5B%5D=487&indices%5B%5D=488&indices%5B%5D=489&indices%5B%5D=490&indices%5B%5D=491&indices%5B%5D=492&indices%5B%5D=493&indices%5B%5D=494&indices%5B%5D=495&indices%5B%5D=496&indices%5B%5D=497&indices%5B%5D=498">
-<XSSCleaned_tag src="mailbox.php?page=1&actionID=delete_messages&targetMbox=&newMbox=0&flag=&indices%5B%5D=499&indices%5B%5D=500&indices%5B%5D=501&indices%5B%5D=502&indices%5B%5D=503&indices%5B%5D=504&indices%5B%5D=505&indices%5B%5D=506&indices%5B%5D=507&indices%5B%5D=508&indices%5B%5D=509&indices%5B%5D=510&indices%5B%5D=511&indices%5B%5D=512&indices%5B%5D=513&indices%5B%5D=514&indices%5B%5D=515&indices%5B%5D=516&indices%5B%5D=517&indices%5B%5D=518&indices%5B%5D=519&indices%5B%5D=520&indices%5B%5D=521&indices%5B%5D=522&indices%5B%5D=523&indices%5B%5D=524&indices%5B%5D=525&indices%5B%5D=526&indices%5B%5D=527&indices%5B%5D=528&indices%5B%5D=529&indices%5B%5D=530&indices%5B%5D=531&indices%5B%5D=532&indices%5B%5D=533&indices%5B%5D=534&indices%5B%5D=535&indices%5B%5D=536&indices%5B%5D=537&indices%5B%5D=538&indices%5B%5D=539&indices%5B%5D=540&indices%5B%5D=541&indices%5B%5D=542&indices%5B%5D=543&indices%5B%5D=544&indices%5B%5D=545&indices%5B%5D=546&indices%5B%5D=547&indices%5B%5D=548&indices%5B%5D=549&indices%5B%5D=550&indices%5B%5D=551&indices%5B%5D=552&indices%5B%5D=553&indices%5B%5D=554&indices%5B%5D=555&indices%5B%5D=556&indices%5B%5D=557&indices%5B%5D=558&indices%5B%5D=559&indices%5B%5D=560&indices%5B%5D=561&indices%5B%5D=562&indices%5B%5D=563&indices%5B%5D=564&indices%5B%5D=565&indices%5B%5D=566&indices%5B%5D=567&indices%5B%5D=568&indices%5B%5D=569&indices%5B%5D=570&indices%5B%5D=571&indices%5B%5D=572&indices%5B%5D=573&indices%5B%5D=574&indices%5B%5D=575&indices%5B%5D=576&indices%5B%5D=577&indices%5B%5D=578&indices%5B%5D=579&indices%5B%5D=580&indices%5B%5D=581&indices%5B%5D=582&indices%5B%5D=583&indices%5B%5D=584&indices%5B%5D=585&indices%5B%5D=586&indices%5B%5D=587&indices%5B%5D=588&indices%5B%5D=589&indices%5B%5D=590&indices%5B%5D=591&indices%5B%5D=592&indices%5B%5D=593&indices%5B%5D=594&indices%5B%5D=595&indices%5B%5D=596&indices%5B%5D=597&indices%5B%5D=598">
-<XSSCleaned_tag src="mailbox.php?page=1&actionID=delete_messages&targetMbox=&newMbox=0&flag=&indices%5B%5D=599&indices%5B%5D=600&indices%5B%5D=601&indices%5B%5D=602&indices%5B%5D=603&indices%5B%5D=604&indices%5B%5D=605&indices%5B%5D=606&indices%5B%5D=607&indices%5B%5D=608&indices%5B%5D=609&indices%5B%5D=610&indices%5B%5D=611&indices%5B%5D=612&indices%5B%5D=613&indices%5B%5D=614&indices%5B%5D=615&indices%5B%5D=616&indices%5B%5D=617&indices%5B%5D=618&indices%5B%5D=619&indices%5B%5D=620&indices%5B%5D=621&indices%5B%5D=622&indices%5B%5D=623&indices%5B%5D=624&indices%5B%5D=625&indices%5B%5D=626&indices%5B%5D=627&indices%5B%5D=628&indices%5B%5D=629&indices%5B%5D=630&indices%5B%5D=631&indices%5B%5D=632&indices%5B%5D=633&indices%5B%5D=634&indices%5B%5D=635&indices%5B%5D=636&indices%5B%5D=637&indices%5B%5D=638&indices%5B%5D=639&indices%5B%5D=640&indices%5B%5D=641&indices%5B%5D=642&indices%5B%5D=643&indices%5B%5D=644&indices%5B%5D=645&indices%5B%5D=646&indices%5B%5D=647&indices%5B%5D=648&indices%5B%5D=649&indices%5B%5D=650&indices%5B%5D=651&indices%5B%5D=652&indices%5B%5D=653&indices%5B%5D=654&indices%5B%5D=655&indices%5B%5D=656&indices%5B%5D=657&indices%5B%5D=658&indices%5B%5D=659&indices%5B%5D=660&indices%5B%5D=661&indices%5B%5D=662&indices%5B%5D=663&indices%5B%5D=664&indices%5B%5D=665&indices%5B%5D=666&indices%5B%5D=667&indices%5B%5D=668&indices%5B%5D=669&indices%5B%5D=670&indices%5B%5D=671&indices%5B%5D=672&indices%5B%5D=673&indices%5B%5D=674&indices%5B%5D=675&indices%5B%5D=676&indices%5B%5D=677&indices%5B%5D=678&indices%5B%5D=679&indices%5B%5D=680&indices%5B%5D=681&indices%5B%5D=682&indices%5B%5D=683&indices%5B%5D=684&indices%5B%5D=685&indices%5B%5D=686&indices%5B%5D=687&indices%5B%5D=688&indices%5B%5D=689&indices%5B%5D=690&indices%5B%5D=691&indices%5B%5D=692&indices%5B%5D=693&indices%5B%5D=694&indices%5B%5D=695&indices%5B%5D=696&indices%5B%5D=697&indices%5B%5D=698">
-<XSSCleaned_tag src="mailbox.php?page=1&actionID=expunge_mailbox">
-<XSSCleaned_tag src="mailbox.php?page=1&actionID=expunge_mailbox">
-<XSSCleaned_tag src="mailbox.php?page=1&actionID=expunge_mailbox">
-<XSSCleaned_tag src="mailbox.php?page=1&actionID=expunge_mailbox">
-<XSSCleaned_tag src="http://secunia.com/">
-</XSSCleaned_tagset>
+
xss99.html
-<img src=""> <BODY ONLOADXSSCleaned="a();"><XSSCleaned_script /><"" />
+<img src=""/>
style_xss01.html
-<BASE HREF="XSSCleanedalert('XSS');//">