31 public static function process($value, $replaceString =
'<x>')
34 if ($replaceString ==
'') {
35 $replaceString =
'<x>';
40 $value = preg_replace(
'/([\x00-\x08]|[\x0b-\x0c]|[\x0e-\x19])/',
'', $value);
44 $searchHexEncodings =
'/&#[xX]0{0,8}(21|22|23|24|25|26|27|28|29|2a|2b|2d|2f|30|31|32|33|34|35|36|37|38|39|3a|3b|3d|3f|40|41|42|43|44|45|46|47|48|49|4a|4b|4c|4d|4e|4f|50|51|52|53|54|55|56|57|58|59|5a|5b|5c|5d|5e|5f|60|61|62|63|64|65|66|67|68|69|6a|6b|6c|6d|6e|6f|70|71|72|73|74|75|76|77|78|79|7a|7b|7c|7d|7e);?/i';
45 $searchUnicodeEncodings =
'/�{0,8}(33|34|35|36|37|38|39|40|41|42|43|45|47|48|49|50|51|52|53|54|55|56|57|58|59|61|63|64|65|66|67|68|69|70|71|72|73|74|75|76|77|78|79|80|81|82|83|84|85|86|87|88|89|90|91|92|93|94|95|96|97|98|99|100|101|102|103|104|105|106|107|108|109|110|111|112|113|114|115|116|117|118|119|120|121|122|123|124|125|126);?/i';
46 while (preg_match($searchHexEncodings, $value) || preg_match($searchUnicodeEncodings, $value)) {
47 $value = preg_replace_callback(
50 return chr(hexdec($matches[1]));
54 $value = preg_replace_callback(
55 $searchUnicodeEncodings,
57 return chr($matches[1]);
64 $allKeywords = array(
'javascript',
'vbscript',
'expression',
'applet',
'meta',
'xml',
'blink',
'link',
'style',
'script',
'embed',
65 'object',
'iframe',
'frame',
'frameset',
'ilayer',
'layer',
'bgsound',
'title',
'base',
'video',
'audio',
'track',
66 'canvas',
'onabort',
'onactivate',
'onafterprint',
'onafterupdate',
'onbeforeactivate',
'onbeforecopy',
'onbeforecut',
67 'onbeforedeactivate',
'onbeforeeditfocus',
'onbeforepaste',
'onbeforeprint',
'onbeforeunload',
'onbeforeupdate',
68 'onblur',
'onbounce',
'oncanplay',
'oncanplaythrough',
'oncellchange',
'onchange',
'onclick',
'oncontextmenu',
69 'oncontrolselect',
'oncopy',
'oncuechange',
'oncut',
'ondataavailable',
'ondatasetchanged',
'ondatasetcomplete',
70 'ondblclick',
'ondeactivate',
'ondrag',
'ondragend',
'ondragenter',
'ondragleave',
'ondragover',
'ondragstart',
71 'ondrop',
'ondurationchange',
'onemptied',
'onended',
'onerror',
'onerrorupdate',
'onfilterchange',
'onfinish',
72 'onfocus',
'onfocusin',
'onfocusout',
'onhashchange',
'onhelp',
'oninput',
'oninvalid',
'onkeydown',
'onkeypress',
73 'onkeyup',
'onlayoutcomplete',
'onload',
'onloadeddata',
'onloadedmetadata',
'onloadstart',
'onlosecapture',
74 'onmessage',
'onmousedown',
'onmouseenter',
'onmouseleave',
'onmousemove',
'onmouseout',
'onmouseover',
'onmouseup',
75 'onmousewheel',
'onmove',
'onmoveend',
'onmovestart',
'onoffline',
'ononline',
'onpagehide',
'onpageshow',
'onpaste',
76 'onpause',
'onplay',
'onplaying',
'onpopstate',
'onprogress',
'onpropertychange',
'onratechange',
'onreadystatechange',
77 'onreset',
'onresize',
'onresizeend',
'onresizestart',
'onrowenter',
'onrowexit',
'onrowsdelete',
'onrowsinserted',
78 'onscroll',
'onseeked',
'onseeking',
'onselect',
'onselectionchange',
'onselectstart',
'onshow',
'onstalled',
'onstart',
79 'onstop',
'onstorage',
'onsubmit',
'onsuspend',
'ontimeupdate',
'onunload',
'onvolumechange',
'onwaiting');
80 $tagKeywords = array(
'applet',
'meta',
'xml',
'blink',
'link',
'style',
'script',
'embed',
'object',
'iframe',
'frame',
81 'frameset',
'ilayer',
'layer',
'bgsound',
'title',
'base',
'video',
'audio',
'track',
'canvas');
82 $attributeKeywords = array(
'style',
'onabort',
'onactivate',
'onafterprint',
'onafterupdate',
'onbeforeactivate',
83 'onbeforecopy',
'onbeforecut',
'onbeforedeactivate',
'onbeforeeditfocus',
'onbeforepaste',
'onbeforeprint',
84 'onbeforeunload',
'onbeforeupdate',
'onblur',
'onbounce',
'oncanplay',
'oncanplaythrough',
'oncellchange',
'onchange',
85 'onclick',
'oncontextmenu',
'oncontrolselect',
'oncopy',
'oncuechange',
'oncut',
'ondataavailable',
'ondatasetchanged',
86 'ondatasetcomplete',
'ondblclick',
'ondeactivate',
'ondrag',
'ondragend',
'ondragenter',
'ondragleave',
'ondragover',
87 'ondragstart',
'ondrop',
'ondurationchange',
'onemptied',
'onended',
'onerror',
'onerrorupdate',
'onfilterchange',
88 'onfinish',
'onfocus',
'onfocusin',
'onfocusout',
'onhashchange',
'onhelp',
'oninput',
'oninvalid,',
'onkeydown',
89 'onkeypress',
'onkeyup',
'onlayoutcomplete',
'onload',
'onloadeddata',
'onloadedmetadata',
'onloadstart',
90 'onlosecapture',
'onmessage',
'onmousedown',
'onmouseenter',
'onmouseleave',
'onmousemove',
'onmouseout',
91 'onmouseover',
'onmouseup',
'onmousewheel',
'onmove',
'onmoveend',
'onmovestart',
'onoffline',
'ononline',
92 'onpagehide',
'onpageshow',
'onpaste',
'onpause',
'onplay',
'onplaying',
'onpopstate',
'onprogress',
93 'onpropertychange',
'onratechange',
'onreadystatechange',
'onredo',
'onreset',
'onresize',
'onresizeend',
94 'onresizestart',
'onrowenter',
'onrowexit',
'onrowsdelete',
'onrowsinserted',
'onscroll',
'onseeked',
'onseeking',
95 'onselect',
'onselectionchange',
'onselectstart',
'onshow',
'onstalled',
'onstart',
'onstop',
'onstorage',
'onsubmit',
96 'onsuspend',
'ontimeupdate',
'onundo',
'onunload',
'onvolumechange',
'onwaiting');
97 $protocolKeywords = array(
'javascript',
'vbscript',
'expression');
100 $valueForQuickCheck = preg_replace(
'/(&#[xX]?0{0,8}(9|10|13|a|b);?)*\s*/i',
'', $value);
101 $potentialKeywords = array();
103 foreach ($allKeywords as $keyword) {
106 if (stripos($valueForQuickCheck, $keyword) !==
false) {
108 if (in_array($keyword, $protocolKeywords,
true)) {
109 $potentialKeywords[] = array($keyword,
'protocol');
111 if (in_array($keyword, $tagKeywords,
true)) {
112 $potentialKeywords[] = array($keyword,
'tag');
114 if (in_array($keyword, $attributeKeywords,
true)) {
115 $potentialKeywords[] = array($keyword,
'attribute');
122 if (!empty($potentialKeywords)) {
126 $valueBeforeReplacement = $value;
127 foreach ($potentialKeywords as $potentialKeywordItem) {
128 list($keyword, $type) = $potentialKeywordItem;
129 $keywordLength = strlen($keyword);
131 $pattern = $keyword[0];
132 if ($keywordLength > 1) {
133 for ($j = 1; $j < $keywordLength; $j++) {
134 $pattern .=
'((&#[xX]0{0,8}([9ab]);?)|(�{0,8}(9|10|13);?)|\s)*' . $keyword[$j];
141 $pattern .=
'((&#[xX]0{0,8}([9ab]);?)|(�{0,8}(9|10|13);?)|\s)*(?=:)';
145 $pattern =
'(?<=<)' . $pattern .
'((&#[xX]0{0,8}([9ab]);?)|(�{0,8}(9|10|13);?)|\s)*(?=[^\da-z])';
150 $pattern .=
'[\s\!\#\$\%\&\(\)\*\~\+\-\_\.\,\:\;\?\@\[\/\|\\\\\]\^\`]*(?==)';
153 $pattern =
'/' . $pattern .
'/i';
155 $replacement = substr_replace($keyword, $replaceString, 2, 0);
157 $value = preg_replace($pattern, $replacement, $value);
159 $found = ($valueBeforeReplacement !== $value);