文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
9.1.2 discuz XSS 标签过滤函数分析
目前大多数 XSS 过滤都是基于黑名单的形式,编程语言和编码结合起来千变万化,基于黑名单的过滤总给人不靠谱的感觉,事实确实是这样,目前好像还没有看到基于黑名单过滤的规则一直没有被绕过,其实在 XSS 的防御上,只要过滤掉尖括号以及单、双引号就能干掉绝大部分的 payload。下面我们来看看 discuz 的 HTML 标签过滤代码,如下所示:
function checkhtml ( $html ) { if (! checkperm ( 'allowhtml' )) { preg_match_all ( "/\< ( [^\<]+ ) \>/is" , $html , $ms ); $searchs[] = '<' ; $replaces[] = '< ; ' ; $searchs[] = '>' ; $replaces[] = '> ; ' ; if ( $ms[1] ) { $allowtags = 'img|a|font|div|table|tbody|caption|tr|td|th|br|p|b|strong|i|u|em|span|ol|ul|li|blockquote|object|param' ; $ms[1] = array_unique ( $ms[1] ); foreach ( $ms[1] as $value ) { $searchs[] = "< ; ".$value."> ; " ; $value = str_replace ( '&' , '_uch_tmp_str_' , $value ); $value = dhtmlspecialchars ( $value ); $value = str_replace ( '_uch_tmp_str_' , '&' , $value ); $value = str_replace ( array ( '\\' , '/*' ), array ( '.' , '/.' ), $value ); $skipkeys = array ( 'onabort' , 'onactivate' , 'onafterprint' , 'onafterupdate' , 'onbeforeactivate' , 'onbeforecopy' , 'onbeforecut' , 'onbeforedeactivate' , 'onbeforeeditfocus' , 'onbeforepaste' , 'onbeforeprint' , 'onbeforeunload' , 'onbeforeupdate' , 'onblur' , 'onbounce' , 'oncellchange' , 'onchange' , 'onclick' , 'oncontextmenu' , 'oncontrolselect' , 'oncopy' , 'oncut' , 'ondataavailable' , 'ondatasetchanged' , 'ondatasetcomplete' , 'ondblclick' , 'ondeactivate' , 'ondrag' , 'ondragend' , 'ondragenter' , 'ondragleave' , 'ondragover' , 'ondragstart' , 'ondrop' , 'onerror' , 'onerrorupdate' , 'onfilterchange' , 'onfinish' , 'onfocus' , 'onfocusin' , 'onfocusout' , 'onhelp' , 'onkeydown' , 'onkeypress' , 'onkeyup' , 'onlayoutcomplete' , 'onload' , 'onlosecapture' , 'onmousedown' , 'onmouseenter' , 'onmouseleave' , 'onmousemove' , 'onmouseout' , 'onmouseover' , 'onmouseup' , 'onmousewheel' , 'onmove' , 'onmoveend' , 'onmovestart' , 'onpaste' , 'onpropertychange' , 'onreadystatechange' , 'onreset' , 'onresize' , 'onresizeend' , 'onresizestart' , 'onrowenter' , 'onrowexit' , 'onrowsdelete' , 'onrowsinserted' , 'onscroll' , 'onselect' , 'onselectionchange' , 'onselectstart' , 'onstart' , 'onstop' , 'onsubmit' , 'onunload' , 'javascript' , 'script' , 'eval' , 'behaviour' , 'expression' , 'style' , 'class' ); $skipstr = implode ( '|' , $skipkeys ); $value = preg_replace ( array ( "/ ( $skipstr ) /i" ), '.' , $value ); if (! preg_match ( "/^[\/|\s] ?( $allowtags )( \s+|$ ) /is" , $value )) { $value = '' ; } $replaces[] = empty ( $value )? '' : "<".str_replace ( '" ; ' , '"' , $value ) .">" ; } } $html = str_replace ( $searchs , $replaces , $html ); }return $html ; }
从代码中可以看到,这里首先定义了一条正则取出来尖括号中间的内容:
preg_match_all ( "/\< ( [^\<]+ ) \>/is" , $html , $ms );
然后在 if($ms[1])这个 if 条件里对这些标签中的关键字进行筛选,$skipkeys 变量定义了很多 on 事件的敏感字符,如下代码中可以看到,最后拼接正则将这些字符串替换掉:
$skipstr = implode ( '|' , $skipkeys ); value = preg_replace ( array ( "/ ( $skipstr ) /i" ), '.' , $value );
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论