替代使用c:out来防止XSS

时间:2010-12-16 21:34:18

标签: security spring jsp xss jstl

我正在努力防止基于Java,基于Spring的Web应用程序中的跨站点脚本(XSS)。我已经实现了一个类似于这个例子http://greatwebguy.com/programming/java/simple-cross-site-scripting-xss-servlet-filter/的servlet过滤器,它清理了应用程序的所有输入。作为额外的安全措施,我还想清理所有JSP中应用程序的所有输出。我做了一些研究,看看如何做到这一点,并找到了两个互补的选择。

其中一个是使用Spring的defaultHtmlEscape属性。这很容易实现(web.xml中的几行),当你的输出通过spring的标签之一(即:消息或表单标签)时,它非常有用。我发现的另一个选择是不直接使用${...}之类的EL表达式而是使用<c:out value="${...}" />

第二种方法完美无缺,但由于我正在处理的应用程序的大小(200多个JSP文件)。使用c:out标记替换EL表达式的所有不当使用是一项非常麻烦的任务。此外,确保所有开发人员都遵守使用c:out标记的惯例(更不用说,代码将无法读取多少),这将成为一项繁琐的任务。

是否有其他方法来转义需要较少代码修改的EL表达式输出?

3 个答案:

答案 0 :(得分:11)

从Servlet 2.5 / JSP 2.1开始,您可以创建一个自定义ELResolver。您可以在ServletContextListener#contextInitialized()注册。

@Override
public void contextInitialized(ServletContextEvent event) {
    JspFactory.getDefaultFactory()
        .getJspApplicationContext(event.getServletContext())
        .addELResolver(new YourCustomELResolver());
}

ELResolver#getValue()你可以做逃脱的工作。

你唯一的问题是,你将无法在允许的地方显示HTML(即已经通过白名单的恶意标签/属性进行了清理,这样你最终会得到像Jsoup can这样无辜的标签。


那就是说,我不同意在问题的第1段中提到的Filter输入期间逃避XSS的必要性。你冒着双重逃避的风险。你只需要在它可能受到伤害的那一点上逃脱它,即在视图一侧直接在HTML中输入内容,输出。我建议摆脱所谓的XSS过滤器,并通过使用JSTL <c:out>fn:escapeXml()(或自定义EL解析器,集中你在视图侧修复它,但这绝对不是正常的方法)。未来的代码维护者将非常感激。

答案 1 :(得分:1)

This blog post描述了一个自定义ELResolver,它转义String类型的EL表达式值。注册此自定义ELResolver将导致它转义所有EL表达式的输出。在JSP必须以编程方式输出HTML的特殊情况下,您需要一种不涉及EL表达式的机制,例如自定义标记或scriptlet:

<%= "Java expression hopefully returning safe HTML" %>

答案 2 :(得分:1)

我同意你不应该在每个变量周围使用c:out。 我在http://tech.finn.no/2011/04/08/xss-protection-whos-responsibility/

写了一篇描述原因的博客

这涉及很多内容。