返回介绍

9.1.2 discuz XSS 标签过滤函数分析

发布于 2024-10-11 22:07:46 字数 3135 浏览 0 评论 0 收藏 0

目前大多数 XSS 过滤都是基于黑名单的形式,编程语言和编码结合起来千变万化,基于黑名单的过滤总给人不靠谱的感觉,事实确实是这样,目前好像还没有看到基于黑名单过滤的规则一直没有被绕过,其实在 XSS 的防御上,只要过滤掉尖括号以及单、双引号就能干掉绝大部分的 payload。下面我们来看看 discuz 的 HTML 标签过滤代码,如下所示:

function checkhtml ( $html ) {

  if (! checkperm ( 'allowhtml' )) {

    preg_match_all ( "/\< ( [^\<]+ ) \>/is" , $html , $ms ); 

    $searchs[] = '<' ; 

    $replaces[] = '&lt ; ' ; 

    $searchs[] = '>' ; 

    $replaces[] = '&gt ; ' ; 

    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[] = "&lt ; ".$value."&gt ; " ; 

    $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 ( '&quot ; ' , '"' , $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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文