URLEncoder.encode(字符串,“UTF-8”)验证不好吗?

时间:2012-02-15 10:46:46

标签: java security xss fortify

在我的J2EE / java代码的一部分中,我对getRequestURI()的输出执行URLEncoding来清理它以防止XSS攻击,但Fortify SCA认为验证不佳。

为什么?

2 个答案:

答案 0 :(得分:6)

关键是您需要将HTML特殊字符转换为HTML实体。这也称为“HTML转义”或“XML转义”。基本上,字符<>"&'需要替换为&lt;&gt;&quot;&amp;&#39;

网址编码不会这样做。 URL编码将URL特殊字符转换为百分比编码值。这不是HTML转义。

对于Web应用程序,HTML转义通常在视图侧完成,正是在那里您重新显示用户控制的输入。对于Java EE Web应用程序,这取决于您正在使用的视图技术。

  1. 如果webapp使用的是现代Facelets视图技术,那么您无需自行转义。 Facelets已经隐含地这样做了。

  2. 如果webapp使用的是旧版JSP视图技术,那么您需要确保使用JSTL <c:out>标记或fn:escapeXml()函数重新显示用户控制的输入。

    <c:out value="${bean.foo}" />
    <input type="text" name="foo" value="${fn:escapeXml(param.foo)}" />
    
  3. 如果webapp设计非常遗留或设计不当并使用servlet或 scriptlet 来打印HTML,那么你就会遇到更大的问题。没有内置标记或函数,更不用说可以转义HTML实体的Java方法了。您应该自己编写一些escape()方法,或者使用Apache Commons Lang StringEscapeUtils#escapeHtml()。然后,您需要确保在打印用户控制输入的任何地方使用它。

    out.print("<p>" + StringEscapeUtils.escapeHtml(request.getParameter("foo")) + "</p>");
    

    更好的方法是重新设计遗留的webapp以将JSP与JSTL一起使用。

答案 1 :(得分:0)

URL编码不会影响某些重要字符,包括单引号(')和括号,因此URL编码将传递未更改的某些有效负载。

例如,

onload'alert(String.fromCharCode(120))'
某些浏览器将

视为有效属性,在注入标记内时可能导致代码执行。

避免XSS的最佳方法是将所有不受信任的输入视为纯文本,然后在编写输出时,将所有纯文本正确编码为输出上的相应类型。

如果要将输入过滤为额外的安全层,请确保过滤器将所有引号(包括反向标记)和括号视为可能的代码,并禁止它们,除非对该输入有意义。