我是Acunetix和XSS问题的新手,所以我在这里有点迷失。
问题是,我的报告说我的代码中可能容易受到跨站点脚本(XSS)攻击。
URL encoded POST input chkId_0 was set to 203_908434'():;998649
The input is reflected inside Javascript code between single quotes.
在我的JSP中,我有类似的东西:
<% if (!someCondition) { %>
<input class="chkbox" type="checkbox" name="chkId_0" value="<%=office.getId()%>" <%=auxDisabled%> />
<% } else { %>
<input class="chkbox" type="checkbox" name="chkId_0" value=" <%=office.getId()%>" <%=auxDisabled%> disabled/>
<% } %>
要安装网址,我正在使用query = request.getQueryString();
,其中附加了chkId_0的值(?...&amp; chkId_0 = 203_908434'():; 998649&amp; ...)
到目前为止,我正在使用过滤器并覆盖来自HttpServletRequestWrapper的getParameter()和getParameterValues()以避免其他一些XSS问题,但不知道如何解决这个问题。
@Override
public String getParameter(String parameter) {
String value = super.getParameter(parameter);
return stripXSS(value);
}
private static Pattern[] patterns = new Pattern[]{
// Script fragments
Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE),
// src='...'
Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
// lonely script tags
Pattern.compile("</script>", Pattern.CASE_INSENSITIVE),
Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
// eval(...)
//...
};
public static String stripXSS(String value) {
if (value != null) {
// Avoid null characters
value = value.replaceAll("\0", "");
// Remove all sections that match a pattern
for (Pattern scriptPattern : patterns){
value = scriptPattern.matcher(value).replaceAll("");
}
}
return value;
}
我已经读过我可以使用JSTL(<c:out>
)来解决这个问题,但不幸的是,这不是我的选择,因为代码是遗留的。
任何形式的帮助将不胜感激。 提前谢谢。
答案 0 :(得分:2)
<input class="chkbox" type="checkbox" name="chkId_0" value="<%=office.getId()%>"/>
您放入周围HTML上下文的每个文字字符串都必须进行HTML转义。
(这是为了正确性和安全性:值中的"
应该在页面上显示为"
,而不是损坏的输入标记。为此,要实现此字符{{1必须写成HTML "
。)
如果您没有JSP 2.0的c:标签可用,那么您将需要一个单独的转义功能。例如:
"
然而,看错误:
输入反映在单引号之间的Javascript代码中。
它并不是在抱怨HTML注入而是JS注入。您可能在收到表单提交的页面上有类似的内容:
<input class="chkbox" type="checkbox" name="chkId_0" value="<%= StringEscapeUtils.escapeHtml4(office.getId()) %>"/>
这里我们将文本插入到JavaScript字符串文字中,因此我们需要使用JS-string-literal-escaping,这样如果值中出现单引号,它就会成为JS {{1逃避:
<script>
var chkId = '<%= request.getParameter("chkId_0") %>';
</script>
(这些例子使用StringEscapeUtils from Apache Commons Lang,这在很多方面都不令人满意,但足以达到这些目的。)
我使用过滤器并重写来自HttpServletRequestWrapper的getParameter()和getParameterValues()以避免其他一些XSS问题
这完全不可行。黑名单模式有很多种方法。为了捕获所有可能的攻击,你必须禁止所有特殊的HTML,JS或你注入的任何其他格式的字符 - 基本上阻止所有标点符号,这很少被接受。
而是专注于在输出端使用正确的转义形式。