替代使用c:out防止XSS [英] Alternative to using c:out to prevent XSS

查看:229
本文介绍了替代使用c:out防止XSS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

其中之一是使用Spring的defaultHtmlEscape属性.这非常容易实现(web.xml中的几行),并且当您的输出通过spring的标签之一(例如message或form标签)时,它的效果很好.我发现的另一个选择是不直接使用EL表达式(例如${...}),而是使用<c:out value="${...}" />

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="${...}" />

第二种方法可以很好地工作,但是由于我正在处理的应用程序的大小(200个以上的JSP文件).必须用c:out标记替换所有不适当地使用的EL表达式是一项非常繁琐的任务.确保将来所有开发人员都遵守使用c:out标签的惯例(这更不用说代码了多少不可读性),在将来也将成为一项繁琐的任务.

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).

是否有其他方法可以逃脱需要较少代码修改的EL表达式的输出?

Is there alternative way to escape the output of EL expressions that would require fewer code modifications?

推荐答案

从Servlet 2.5/JSP 2.1开始,您可以创建自定义中进行注册ServletContextListener#contextInitialized() .

Since Servlet 2.5/JSP 2.1 you could create a custom ELResolver which does that. You can register it in ServletContextListener#contextInitialized().

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

In the ELResolver#getValue() you could do the escaping job.

您唯一的问题是,您将无法在允许的位置显示HTML(即,已经通过白名单从恶意代码/属性中清除了HTML,这样您最终会得到无辜的代码,例如Jsoup

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).

也就是说,我不同意Filter输入期间转义XSS的必要性,正如您在问题的第一段中提到的那样.您冒着两次转义的风险.您只需要在可能会造成伤害的确切位置进行转义,即直接在视图侧将其内联到HTML(输出)中.我建议摆脱所谓的XSS过滤器,而将精力集中在通过使用JSTL <c:out>fn:escapeXml()(或自定义EL解析器,但绝对不是通常的方法)将它固定在视图侧.将来的代码维护者将非常感激.

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> or fn:escapeXml() (or a custom EL resolver, but that's definitely not the normal approach). The future code maintainers will be greatly thankful.

这篇关于替代使用c:out防止XSS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆