使用 c:out 防止 XSS 的替代方案
我正在致力于防止基于 Java、Spring 的 Web 应用程序中的跨站脚本 (XSS)。我已经实现了类似于此示例的 servlet 过滤器 http://greatwebguy.com/programming/java/simple-cross-site-scripting-xss-servlet-filter/ 它会清理应用程序中的所有输入。作为额外的安全措施,我还想清理所有 JSP 中应用程序的所有输出。我做了一些研究,看看如何做到这一点,并找到了两个互补的选择。
其中之一是使用 Spring 的 defaultHtmlEscape
属性。这非常容易实现(web.xml 中的几行),并且当您的输出通过 spring 的标签之一(即:消息或表单标签)时,它非常有效。我发现的另一个选择是不直接使用 EL 表达式,例如 ${...}
,而是使用
第二种方法效果很好,但是由于我正在处理的应用程序的大小(200 多个 JSP 文件)。必须用 c:out
标记替换所有不恰当的 EL 表达式使用是一项非常繁琐的任务。此外,确保所有开发人员都遵守使用 c:out
标记的约定(更不用说,代码会变得更加不可读),这在未来将成为一项繁琐的任务。
是否有其他方法可以转义 EL 表达式的输出,并且需要更少的代码修改?
I'm working on preventing cross site scripting (XSS) in a Java, Spring based, Web application. I have already implemented a servlet filter similar to this example http://greatwebguy.com/programming/java/simple-cross-site-scripting-xss-servlet-filter/ which sanitizes all the input into the application. As an extra security measure I would like to also sanitize all output of the application in all JSPs. I have done some research to see how this could be done and found two complementary options.
One of them is the use of Spring's defaultHtmlEscape
attribute. This was very easy to implement (a few lines in web.xml), and it works great when your output is going through one of spring's tags (ie: message, or form tags). The other option I have found is to not directly use EL expressions such as ${...}
and instead use <c:out value="${...}" />
That second approach works perfectly, however due to the size of the application I am working on (200+ JSP files). It is a very cumbersome task to have to replace all inappropriate uses of EL expressions with the c:out
tag. Also it would become a cumbersome task in the future to make sure all developers stick to this convention of using the c:out
tag (not to mention, how much more unreadable the code would be).
Is there alternative way to escape the output of EL expressions that would require fewer code modifications?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
从 Servlet 2.5/JSP 2.1 开始,您可以创建自定义
ELResolver
就是这样做的。您可以在 中注册它ServletContextListener#contextInitialized()
。在
ELResolver#getValue()
你可以完成转义工作。你唯一的问题是你将无法在允许的地方显示 HTML(即已经通过白名单清除了恶意标签/属性,因此你最终会得到像 Jsoup 可以)。
也就是说,我不同意您在问题第一段中提到的在输入期间通过
Filter
转义XSS的必要性。你有双重逃逸的风险。您只需要在它可能造成损害的地方进行转义,即直接在视图侧将其内联到 HTML(输出)中。我建议摆脱所谓的 XSS 过滤器,并通过使用 JSTL
或fn:escapeXml()
集中精力在视图端修复它。 code> (或自定义 EL 解析器,但这绝对不是正常方法)。未来的代码维护者将非常感激。Since Servlet 2.5/JSP 2.1 you could create a custom
ELResolver
which does that. You can register it inServletContextListener#contextInitialized()
.In the
ELResolver#getValue()
you could do the escaping job.Your only problem is that you will be unable to display HTML there where it's allowed (i.e. already sanitized from malicious tags/attributes by kind of a whitelist so that you end up with innocent tags like Jsoup can do).
That said, I disagree the necessity to escape XSS during input by the
Filter
as you mentioned in 1st paragraph of the question. You risk double-escaping. You only need to escape it at exactly that point where it can possibly harm, i.e. straight in the view side there where it's going to be inlined among HTML, the output. I recommend to get rid of that so-called XSS filter and concentrate you on fixing it in the view side by either using JSTL<c:out>
orfn:escapeXml()
(or a custom EL resolver, but that's definitely not the normal approach). The future code maintainers will be greatly thankful.这篇博文介绍了一个自定义 ELResolver它转义 String 类型的 EL 表达式值。注册此自定义 ELResolver 将导致它转义所有 EL 表达式的输出。在 JSP 必须以编程方式输出 HTML 的特殊情况下,您需要一种不涉及 EL 表达式的机制,例如自定义标记或 scriptlet:
This blog post describes a custom ELResolver which escapes EL expression values of type String. Registering this custom ELResolver will cause it to escape the output of all EL expressions. In the exceptional cases where a JSP must programmatically output HTML, you require a mechanism that does not involve an EL expression, such as a custom tag or a scriptlet:
我同意您不必在每个变量周围使用 c:out 。
我写了一篇博客,描述了原因 http://tech.finn .no/2011/04/08/xss-protection-whos-responsibility/
它涉及这里所说的很多内容。
I agree you shouldn't have to use c:out around every variable.
I wrote a blog describing why at http://tech.finn.no/2011/04/08/xss-protection-whos-responsibility/
It touches on much that is said here.