jsp 输入标签的跨站脚本问题
Cross Site Scripting issue on jsp input tag
我是 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/>
<% } %>
为了安装 url,我使用 query = request.getQueryString();
,其中附加了 chkId_0 的值 (?...&chkId_0=203_908434'():;998649&...)
到目前为止,我正在使用过滤器并覆盖 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("[=13=]", "");
// Remove all sections that match a pattern
for (Pattern scriptPattern : patterns){
value = scriptPattern.matcher(value).replaceAll("");
}
}
return value;
}
我读到我可以使用 JSTL (<c:out>
) 解决这个问题,但不幸的是,这对我来说不是一个选择,因为代码是遗留的。
我们将不胜感激任何形式的帮助。
提前致谢。
<input class="chkbox" type="checkbox" name="chkId_0" value="<%=office.getId()%>"/>
您放入周围 HTML 上下文中的每个文本字符串 必须 HTML-转义。
(这是为了正确性和安全性:值中的 "
应该在页面上显示为 "
,而不是损坏的输入标签。要实现这一点,字符 "
必须写成 HTML "
.)
如果您没有 JSP 2.0 的 c: 标签可以执行此操作,那么您将需要一个单独的转义函数。例如:
<input class="chkbox" type="checkbox" name="chkId_0" value="<%= StringEscapeUtils.escapeHtml4(office.getId()) %>"/>
但是,查看错误:
The input is reflected inside Javascript code between single quotes.
它不是抱怨 HTML-injection 而是 JS-injection。您可能在接收表单提交的页面上有这样的内容:
<script>
var chkId = '<%= request.getParameter("chkId_0") %>';
</script>
这里我们将文本插入到 JavaScript 字符串文字中,所以我们需要使用 JS-string-literal-escaping 这样如果值中有单引号,它就会作为 JS 输出\'
转义:
<script>
var chkId = '<%= StringEscapeUtils.escapeEcmaScript(request.getParameter("chkId_0")) %>';
</script>
(这些示例使用 StringEscapeUtils from Apache Commons Lang,这在很多方面都不令人满意,但足以满足这些目的。)
I'm using a filter and overriding getParameter() and getParameterValues() from HttpServletRequestWrapper to avoid some other XSS issues
这完全行不通。有许多方法可以解决您的黑名单模式。为了使其捕获所有可能的攻击,您必须禁止所有在 HTML、JS 或您要注入的任何其他格式中的特殊字符——基本上阻止所有标点符号,这很少被接受。
而是专注于在输出端使用正确的转义形式。
我是 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/>
<% } %>
为了安装 url,我使用 query = request.getQueryString();
,其中附加了 chkId_0 的值 (?...&chkId_0=203_908434'():;998649&...)
到目前为止,我正在使用过滤器并覆盖 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("[=13=]", "");
// Remove all sections that match a pattern
for (Pattern scriptPattern : patterns){
value = scriptPattern.matcher(value).replaceAll("");
}
}
return value;
}
我读到我可以使用 JSTL (<c:out>
) 解决这个问题,但不幸的是,这对我来说不是一个选择,因为代码是遗留的。
我们将不胜感激任何形式的帮助。 提前致谢。
<input class="chkbox" type="checkbox" name="chkId_0" value="<%=office.getId()%>"/>
您放入周围 HTML 上下文中的每个文本字符串 必须 HTML-转义。
(这是为了正确性和安全性:值中的 "
应该在页面上显示为 "
,而不是损坏的输入标签。要实现这一点,字符 "
必须写成 HTML "
.)
如果您没有 JSP 2.0 的 c: 标签可以执行此操作,那么您将需要一个单独的转义函数。例如:
<input class="chkbox" type="checkbox" name="chkId_0" value="<%= StringEscapeUtils.escapeHtml4(office.getId()) %>"/>
但是,查看错误:
The input is reflected inside Javascript code between single quotes.
它不是抱怨 HTML-injection 而是 JS-injection。您可能在接收表单提交的页面上有这样的内容:
<script>
var chkId = '<%= request.getParameter("chkId_0") %>';
</script>
这里我们将文本插入到 JavaScript 字符串文字中,所以我们需要使用 JS-string-literal-escaping 这样如果值中有单引号,它就会作为 JS 输出\'
转义:
<script>
var chkId = '<%= StringEscapeUtils.escapeEcmaScript(request.getParameter("chkId_0")) %>';
</script>
(这些示例使用 StringEscapeUtils from Apache Commons Lang,这在很多方面都不令人满意,但足以满足这些目的。)
I'm using a filter and overriding getParameter() and getParameterValues() from HttpServletRequestWrapper to avoid some other XSS issues
这完全行不通。有许多方法可以解决您的黑名单模式。为了使其捕获所有可能的攻击,您必须禁止所有在 HTML、JS 或您要注入的任何其他格式中的特殊字符——基本上阻止所有标点符号,这很少被接受。
而是专注于在输出端使用正确的转义形式。