我已经完成了OWASP十大漏洞,并发现跨站点脚本是我们必须记笔记的。建议的解决方案很少。有人说不要使用“黑名单”验证来检测输入中的XSS或编码输出。搜索和替换仅少数字符(<
和>
以及其他类似字符或短语(例如script
)很弱,并且已成功攻击。即使是未经检查的“<b>”
代码,在某些情况下也是不安全的。 XSS拥有数量惊人的变体,可以轻松绕过黑名单验证。另一个解决方案是强输出编码。在呈现之前,确保所有用户提供的数据都经过适当的实体编码(HTML或XML,具体取决于输出机制)。那么,这是阻止跨站点脚本验证和替换输入或编码输出的最佳方法吗?
答案 0 :(得分:41)
通常的做法是在JSP中重新显示期间HTML转义任何用户控制的数据,而不是在处理 servlet中提交的数据期间也不是在存储的数据库中。在JSP中,您可以使用JSTL(安装它,只需在/WEB-INF/lib
)jstl-1.2.jar标记或<c:out>
功能中删除fn:escapeXml
即可。 E.g。
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
...
<p>Welcome <c:out value="${user.name}" /></p>
和
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
...
<input name="username" value="${fn:escapeXml(param.username)}">
就是这样。不需要黑名单。请注意,用户控制的数据涵盖HTTP请求引入的所有:请求参数,正文和标题(!!)。
如果您在处理提交的数据和/或存储在数据库中时对其进行HTML转义,那么它将全部分布在业务代码和/或数据库中。这只是维护问题而且当您在不同的地方执行此操作时,您将面临双重逃避或更多的风险(例如&
将变为&amp;
而不是&
,以便最终用户真正看到{{} 1}}而不是&
在视图中。业务代码和数据库反过来对XSS不敏感。只有视图是。然后你应该只在视图中右边转义它。 / p>
答案 1 :(得分:6)
同时使用。实际上,请参考类似OWASP XSS Prevention cheat sheet的指南,了解输出编码和输入验证的可能使用情况。
在某些情况下,如果不依赖输出编码,输入验证会有所帮助。例如,您最好验证URL中出现的输入,而不是自己编码URL(Apache不会提供URL编码的URL)。或者就此而言,验证JavaScript表达式中出现的输入。
最终,简单的拇指规则会有所帮助 - 如果您不完全信任用户输入,或者您怀疑某些来源可能导致XSS攻击而不管输出编码,请针对白名单进行验证。
请查看有关输出编码器和输入验证器如何在安全库中编写的OWASP ESAPI源代码。
答案 2 :(得分:0)
我的首选是将所有非字母数字字符编码为HTML数字字符实体。因为几乎所有攻击都需要非字符字符(例如&lt;,“等),所以这应该消除了大量的危险输出。
格式为&amp; #N;,其中N是字符的数值(您可以将字符转换为int并使用字符串连接以获取小数值)。例如:
// java-ish pseudocode StringBuffer safestrbuf = new StringBuffer(string.length()*4); foreach(char c : string.split() ){ if( Character.isAlphaNumeric(c) ) safestrbuf.append(c); else safestrbuf.append(""+(int)symbol);
您还需要确保在输出到浏览器之前立即进行编码,以避免双重编码,或编码HTML但发送到其他位置。