Java 5 HTML escaping To Prevent XSS

2019-01-14 04:55发布

I'm looking into some XSS prevention in my Java application.

I currently have custom built routines that will escape any HTML stored in the database for safe display in my jsps. However I would rather use a built in/standard method to do this if possible.

I am not currently encoding data that gets sent to the database but would like to start doing that as well.

Are there any built in methods that can help me to achieve this?

标签: java jsp xss
3条回答
Lonely孤独者°
2楼-- · 2019-01-14 05:20

not built-in, but check out the owasp esapi filter, it should do what you're looking for and more. It is a great open source security library written by the smart guys&girls at Owasp ("Open Web Application Security Project").

查看更多
三岁会撩人
3楼-- · 2019-01-14 05:27

You normally escape XSS during display, not during store. In JSP you can use the JSTL (just drop jstl-1.2.jar in /WEB-INF/lib) <c:out> tag or fn:escapeXml function for this. E.g.

<input name="foo" value="<c:out value="${param.foo}" />">

or

<input name="foo" value="${fn:escapeXml(param.foo)}">

That's it. If you do it during processing the input and/or storing in DB as well, then it's all spread over the business code and/or in the database. You should not do that, it's only maintenance trouble and you will risk double-escapes or more when you do it at different places (e.g. & would become &amp;amp; instead of &amp; so that the enduser would literally see &amp; instead of & in view. The code and DB are not sensitive for XSS. Only the view is. You should then escape it only right there.

Update: you've posted 4 topics about the same subject:

I will only warn you: you do not need to escape it in servlet/filter/javacode/database/whatever. You're only unnecessarily overcomplicating things. Just escape it during display. That's all.

查看更多
祖国的老花朵
4楼-- · 2019-01-14 05:28

I have to say I rather disagree with the accepted answer of apparently escaping on output to prevent XSS.

I believe the better approach is to sanitize on input which can easily be achieved with an aspect so that you don't have to put it all over the place. Sanitizing is different than escaping.

You can't just blindly escape:

  • You may want users to enter a subset of HTML (aka links and bold tags).
  • Escaping does not prevent XSS

I recommend using OWASP Antisammy library with an Aspect or @futtta's recommendation of the filter.

Below is an aspect I wrote to sanitize user input using Spring MVC annotations (since we use that for all of our input).

@SuppressWarnings("unused")
@Aspect
public class UserInputSanitizerAdivsor {

    @Around("execution(@RequestMapping * * (..))")
    public Object check(final ProceedingJoinPoint jp) throws Throwable {
        Object[] args = jp.getArgs();
        if (args != null) {
            for (int i = 0; i < args.length; i++) {
                Object o = args[i];
                if (o != null && o instanceof String) {
                    String s = (String) o;
                    args[i] = UserInputSanitizer.sanitize(s);
                }
            }
        }
        return jp.proceed(args);
    }
}

You will still have to escape on output for non rich-text fields but you will never (and I believe should never) have malicious data in your database.

If you don't want to sanitize on certain inputs you can always make annotation that will make the aspect not sanitize.

The other reason you don't want malicious data in your database is if you provide any sort REST API to the Internet. You may do the right thing on output but your mashup partners may not.

Sanitizing input or blocking input is ok (I mean most people have file upload limit right?). Most of the fields in a web application don't need script tags to be entered and more importantly most of your users probably do not need or want to enter script tags (obvious exception is stack overflow answers).

查看更多
登录 后发表回答