URLEncoder.encode(string, "UTF-8") 验证效果不佳吗?
在我的 J2EE/java 代码的一部分中,我对 getRequestURI()
的输出进行了 URLEncoding,以对其进行清理以防止 XSS 攻击,但 Fortify SCA 认为这种验证很差。
为什么?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
关键点是您需要将 HTML 特殊字符转换为 HTML 实体。这也称为“HTML 转义”或“XML 转义”。基本上,字符
<
、>
、"
、&
和'
需要替换为<
、>
、"
、&< /code> 和
'
。 URL 编码不会执行此操作。这不是 HTML 转义。
在 Web 应用程序中,HTML 转义通常在视图端完成,即在您重新显示用户的地方。 - 控制输入。对于 Java EE Web 应用程序,这取决于您所使用的视图技术
如果 Web 应用程序使用现代 Facelets 视图技术,那么您无需自行转义它。已经隐含地这样做。
如果 Web 应用程序使用传统的 JSP 视图技术,那么您 就可以这样做。需要确保您使用 JSTL
标记或fn:escapeXml()
函数来重新显示用户控制的输入。如果网络应用程序非常传统或设计不佳,并且使用 servlet 或 scriptlet 来打印 HTML,那么您的问题就更大了。没有内置标签或函数,更不用说可以转义 HTML 实体的 Java 方法了。您应该自己编写一些
escape()
方法,或者使用 Apache Commons LangStringEscapeUtils#escapeHtml()
为此。然后,您需要确保在打印用户控制的输入的任何地方都使用它。更好的办法是重新设计旧版 Web 应用程序,以将 JSP 与 JSTL 结合使用。
The key point is that you need to convert HTML special characters to HTML entities. This is also called "HTML escaping" or "XML escaping". Basically, the characters
<
,>
,"
,&
and'
needs to be replaced by<
,>
,"
,&
and'
.URL encoding does not do that. URL encoding converts URL special characters to percent-encoded values. This is not HTML escaping.
In case of web applications, HTML escaping is normally to be done in the view side, exactly there where you're redisplaying user-controlled input. In case of a Java EE web applications, that depends on the view technology you're using.
If the webapp is using modern Facelets view technology, then you don't need to escape it yourself. Facelets will already implicitly do that.
If the webapp is using legacy JSP view technology, then you need to ensure that you're using JSTL
<c:out>
tag orfn:escapeXml()
function to redisplay user-controlled input.If the webapp is very legacy or bad designed and using servlets or scriptlets to print HTML, then you've a bigger problem. There are no builtin tags or functions, let alone Java methods which can escape HTML entities. You should either write some
escape()
method yourself or use the Apache Commons LangStringEscapeUtils#escapeHtml()
for this. Then you need to ensure that you're using it everywhere you're printing user-controlled input.Much better would be to redesign that legacy webapp to use JSP with JSTL.
URL 编码不会影响某些重要字符,包括单引号 (
'
) 和括号,因此 URL 编码将通过未更改的某些有效负载。例如,
某些浏览器会将其视为有效属性,当注入标签内时可以导致代码执行。
避免 XSS 的最佳方法是将所有不受信任的输入视为纯文本,然后在编写输出时,将所有纯文本正确编码为输出上的适当类型。
如果您想过滤输入作为额外的安全层,请确保您的过滤器将所有引号(包括反引号)和括号视为可能的代码,并禁止它们,除非对于该输入有意义。
URL encoding does not affect certain significant characters including single quote (
'
) and parentheses, so URL encoding will pass through unchanged certain payloads.For example,
will be treated by some browsers as a valid attribute that can result in code execution when injected inside a tag.
The best way to avoid XSS is to treat all untrusted inputs as plain text, and then when composing your output, properly encode all plain text to the appropriate type on output.
If you want to filter inputs as an additional layer of security, make sure your filter treats all quotes (including back-tick) and parentheses as possible code, and disallow them unless the make sense for that input.