How to prevent people from running XSS in Spring MVC?

What to do to prevent XSS in Spring MVC? Right now, I just put all the places where I output the user text in the JSTL <c:out> or fn:escapeXml() , but this seems to be error prone since I can skip the place.

Is there a simple, systematic way to prevent this? Maybe a filter or something else? I collect input by setting @RequestParam parameters in my controller methods.

+45
spring spring-mvc jsp xss html-escape-characters
Jan 27 '10 at 15:10
source share
8 answers

In Spring, you can avoid html from JSP pages generated by <form> tags. This closes many possibilities for XSS attacks and can be done automatically in three ways:

For the entire application in the web.xml :

 <context-param> <param-name>defaultHtmlEscape</param-name> <param-value>true</param-value> </context-param> 

For all forms on this page in the file itself:

 <spring:htmlEscape defaultHtmlEscape="true" /> 

For each form:

 <form:input path="someFormField" htmlEscape="true" /> 
+50
Jan 27 '10 at 15:28
source share
β€” -

Try XSSFilter .

+8
Jan 27 '10 at
source share

When you are trying to prevent XSS, it is important to think about context. As an example, how and what to avoid is very different if you use data inside a variable in a javascript fragment, as opposed to outputting data to an HTML tag or HTML attribute.

I have an example of this here: http://erlend.oftedal.no/blog/?blogid=91

Also check out the OWASP XSS Prevention Cheat Sheet: http://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet

So the short answer is: make sure you avoid exiting as Tendai Moushe suggests, but be especially careful when you output data in HTML or javascript attributes.

+6
Jan 31 '10 at 11:07
source share

I use Hibernate Validator via @Valid for all input objects (binding and @RequestBody json, see https://dzone.com/articles/spring-31-valid-requestbody ). Therefore @org.hibernate.validator.constraints.SafeHtml is a good solution for me.

Hibernate SafeHtmlValidator depends on org.jsoup , so it needs to add another project dependency:

 <dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.10.1</version> </dependency> 

For bean User with field

 @NotEmpty @SafeHtml protected String name; 

to try updating with the value <script>alert(123)</script> in the controller

 @PutMapping(value = "/{id}", consumes = MediaType.APPLICATION_JSON_VALUE) public void update(@Valid @RequestBody User user, @PathVariable("id") int id) 

or

 @PostMapping public void createOrUpdate(@Valid User user) { 

BindException for binding and MethodArgumentNotValidException for @RequestBody with default message:

 name may have unsafe html content 

The validator also works for binding, as before. Applications can be tested at http://topjava.herokuapp.com/

+4
Nov 16 '16 at 23:38
source share

How do you collect user input first? This question / answer may help if you are using FormController :

Spring: escaping input when binding to a command

0
Jan 27 '10 at 15:15
source share

Always check manually the methods, tags that you use, and make sure that they always run away (once) at the end. From the perspectives there are many errors and differences in this aspect.

Overview: http://www.gablog.eu/online/node/91

0
Jan 27 '10 at 16:01
source share

Instead of relying solely on <c:out /> , you must also use the antixss library, which will not only encode but also sanitize the malicious script input. One of the best libraries available is OWASP Antisamy , it is very flexible and can be configured (using xml policy files) as required.

For example, if the application only supports text input, then the general common provided by OWASP can be used , which sanitizes and removes most html tags. Similarly, if applications support html editors (e.g. tinymce) that require all types of html tags, a more flexible policy can be used, for example, an ebay policy file

0
Jun 11 '15 at 9:50
source share
 **To avoid XSS security threat in spring application** 

The solution to the XSS problem is to filter out all the text fields on the form at the time the form is submitted.

  It needs XML entry in the web.xml file & two simple classes. java code :- The code for the first class named CrossScriptingFilter.java is : package com.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import org.apache.log4j.Logger; public class CrossScriptingFilter implements Filter { private static Logger logger = Logger.getLogger(CrossScriptingFilter.class); private FilterConfig filterConfig; public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig = filterConfig; } public void destroy() { this.filterConfig = null; } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { logger.info("Inlter CrossScriptingFilter ..............."); chain.doFilter(new RequestWrapper((HttpServletRequest) request), response); logger.info("Outlter CrossScriptingFilter ..............."); } } 

The second class of code called RequestWrapper.java:

com.filter package;

 import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import org.apache.log4j.Logger; public final class RequestWrapper extends HttpServletRequestWrapper { private static Logger logger = Logger.getLogger(RequestWrapper.class); public RequestWrapper(HttpServletRequest servletRequest) { super(servletRequest); } public String[] getParameterValues(String parameter) { logger.info("InarameterValues .. parameter ......."); String[] values = super.getParameterValues(parameter); if (values == null) { return null; } int count = values.length; String[] encodedValues = new String[count]; for (int i = 0; i < count; i++) { encodedValues[i] = cleanXSS(values[i]); } return encodedValues; } public String getParameter(String parameter) { logger.info("Inarameter .. parameter ......."); String value = super.getParameter(parameter); if (value == null) { return null; } logger.info("Inarameter RequestWrapper ........ value ......."); return cleanXSS(value); } public String getHeader(String name) { logger.info("Ineader .. parameter ......."); String value = super.getHeader(name); if (value == null) return null; logger.info("Ineader RequestWrapper ........... value ...."); return cleanXSS(value); } private String cleanXSS(String value) { // You'll need to remove the spaces from the html entities below logger.info("InnXSS RequestWrapper ..............." + value); //value = value.replaceAll("<", "& lt;").replaceAll(">", "& gt;"); //value = value.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41;"); //value = value.replaceAll("'", "& #39;"); value = value.replaceAll("eval\\((.*)\\)", ""); value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\""); value = value.replaceAll("(?i)<script.*?>.*?<script.*?>", ""); value = value.replaceAll("(?i)<script.*?>.*?</script.*?>", ""); value = value.replaceAll("(?i)<.*?javascript:.*?>.*?</.*?>", ""); value = value.replaceAll("(?i)<.*?\\s+on.*?>.*?</.*?>", ""); //value = value.replaceAll("<script>", ""); //value = value.replaceAll("</script>", ""); logger.info("OutnXSS RequestWrapper ........ value ......." + value); return value; } 

All that remains is the XML entry in the web.xml file:

  <filter> <filter-name>XSS</filter-name> <display-name>XSS</display-name> <description></description> <filter-class>com.filter.CrossScriptingFilter</filter-class> </filter> <filter-mapping> <filter-name>XSS</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> 

The / * parameter specifies that for each request made from the browser, it will call the CrossScriptingFilter Class. Which will analyze all the components / elements coming from the request & replace all javascript tags placed by the hacker with an empty line ie

0
October 27 '17 at 20:02 on
source share



All Articles