XSS (cross-site scripting),即跨站脚本攻击,它的本质还是一种“HTML注入”,用户的数据被当成了HTML代码一部分来执行,从而混淆了原本的语义,产生了新的语义。
来看一张某网站遭受XSS攻击后的图片,
其实就是攻击者发送了一段html代码,就达到了上述的效果。
<img height="0" width="0" src="xx" onerror='function fn(){n = $("#userName").html();$("textarea#pub_msg_input.msg-input").val(n + "说:虎牙妹妹长得真不错");$("#msg_send_bt").click();}setInterval(fn, 3000)'>
这段代码的大致意思是故意加载一张不存在的图片,于是出错后就执行了onerror中的js代码,这段js代码会获取当前登录用户的用户名,并使用同样的内容“虎牙妹妹长得真不错”进行发送,只要其他登录用户一打开此页面,并加载到刚才攻击者发送的内容,就会像蠕虫一样传染开。
解决办法可以使用第三方类库在后台将输入的文本进行过滤,可以在网上找到很多开源的“XSS Filter”的实现:
1、在OWASP ESAPI(Enterprise Security API)中有几个安全的JavascriptEncode、HtmlEncode、XMLEncode、JSONEncode的实现,非常严格。
ESAPI的maven依赖如下:
<dependency>
<groupId>org.owasp.esapi</groupId>
<artifactId>esapi</artifactId>
<version>2.1.0</version>
</dependency>
使用ESAPI防止XSS的做法:
String safe = ESAPI.encoder().encodeForHTML( request.getParameter( "input" ) );
对用户输入“input”进行HTML编码,防止XSS。
使用ESAPI防止ORACLE数据库SQL注入的做法:
String sqlStr=“select name from tableA where id=”+
ESAPI.encoder().encodeForSQL(ORACLE_CODEC,validatedUserId)
+ "and date_created"='"
+ ESAPI.encoder().encodeForSQL(ORACLE_CODEC,validatedStartDate)+"'";
myStmt = conn.createStatement(sqlStr);
2、在“Apache Common Lang”的“StringEscapeUtils”里,提供了许多escape的函数。
3、Anti-Samy是OWASP上的一个开源项目,也是目前最好的XSS Filter。最早它是基于Java的,现在已经扩展到.NET等语言。
Anti-Samy的maven依赖如下:
<dependency>
<groupId>org.owasp</groupId>
<artifactId>antisamy</artifactId>
<version>1.4</version>
</dependency>