8

How do you handle the case where you want user input from a form to be htmlEscape'd when you are binding to a command object?

I want this to sanitize input data automatically in order to avoid running through all fields in command object.

thanks.

Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
glaz666
  • 8,707
  • 19
  • 56
  • 75
  • 1
    You should validate input and escape the output: http://lukeplant.me.uk/blog/posts/why-escape-on-input-is-a-bad-idea/ – Tommy Nov 27 '13 at 10:36

2 Answers2

10

If you are using a FormController you can register a new property editor by overriding the initBinder(HttpServletReques, ServletRequestDataBinder) method. This property editor can escape the html, javascript and sql injection.

If you are using a property editor the values from the request object will be processed by the editor before assigning to the command object.

When we register a editor we have to specify the type of the item whose values has to be processed by the editor.

Sorry, now I don't the syntax of the method. But I'm sure this is how we have achieved this.

EDITED

I think the following syntax can work

In your controller override the following method as shown

    @Override
    protected void initBinder(HttpServletRequest request,
        ServletRequestDataBinder binder) throws Exception {
        super.initBinder(request, binder);

        binder.registerCustomEditor(String.class, 
                    new StringEscapeEditor(true, true, false));
    }

Then create the following property editor

public class StringEscapeEditor extends PropertyEditorSupport {

    private boolean escapeHTML;
    private boolean escapeJavaScript;
    private boolean escapeSQL;

    public StringEscapeEditor() {
        super();
    }

    public StringEscapeEditor(boolean escapeHTML, boolean escapeJavaScript,
            boolean escapeSQL) {
        super();
        this.escapeHTML = escapeHTML;
        this.escapeJavaScript = escapeJavaScript;
        this.escapeSQL = escapeSQL;
    }

    public void setAsText(String text) {
        if (text == null) {
            setValue(null);
        } else {
            String value = text;
            if (escapeHTML) {
                value = StringEscapeUtils.escapeHtml(value);
            }
            if (escapeJavaScript) {
                value = StringEscapeUtils.escapeJavaScript(value);
            }
            if (escapeSQL) {
                value = StringEscapeUtils.escapeSql(value);
            }
            setValue(value);
        }
    }

    public String getAsText() {
        Object value = getValue();
        return (value != null ? value.toString() : "");
    }
}

Hopes this helps you

Claes Mogren
  • 2,126
  • 1
  • 26
  • 34
Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
  • Good approach is described here: http://stackoverflow.com/questions/2147958/how-do-i-prevent-people-from-doing-xss-in-java – blandger Apr 22 '14 at 09:17
  • 1
    For Spring 3.2.x you can use the below syntax to initialise the binder: @InitBinder public void initBinder(WebDataBinder dataBinder) { dataBinder.registerCustomEditor(String.class, new HtmlEscapeStringEditor()); } – shane lee Aug 15 '14 at 05:09
  • There is also a new feature called ControllerAdvice where you only need to specify the binder once instead of every controller. – shane lee Aug 15 '14 at 06:02
0

You can use @Valid and @SafeHtml from hibernate validator. See details at https://stackoverflow.com/a/40644276/548473

Community
  • 1
  • 1
Grigory Kislin
  • 16,647
  • 10
  • 125
  • 197