How do you protect, sanitize applications that take raw JSON bodies and typically output JSON responses and don't use Spring Boot. I only saw one good example that might work and used JsonComponent. If we don't use jsoncomponent, how to filter out a request to remove bad cross site scripting tags from a the entire JSON request body? Also, it would be OK to detect XSS tags in the request body and throw an error.
Also looking for a global solution that might protect all input/output of JSON requests and add that code in one area. We could use JSR bean validation but we would have to hit all of the define properties and variables.
Is it possible to also look at the JSON payload for data which could include script tags.
Ok finally I did it, I post my solution as response instead of comment, it is functional but no very robust, if you want me to improve it with exception handlers etc let me know
The AntiXssDemoApplication.java is
package com.melardev.stackoverflow.demos.antixssdemo;
import com.melardev.stackoverflow.demos.antixssdemo.filters.AntiXssFilter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import javax.servlet.Filter;
@SpringBootApplication
@ServletComponentScan
public class AntiXssDemoApplication {
public static void main(String[] args) {
SpringApplication.run(AntiXssDemoApplication.class, args);
}
}
the AntiXssFilter
package com.melardev.stackoverflow.demos.antixssdemo.filters;
import org.springframework.web.util.HtmlUtils;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter(urlPatterns = "/*")
public class AntiXssFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("Filter initialized");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
String userInput = servletRequest.getParameter("param");
if (userInput != null && !userInput.equalsIgnoreCase(HtmlUtils.htmlEscape(userInput)))
throw new RuntimeException();
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
System.out.println("destroy");
}
}
The Controller
package com.melardev.stackoverflow.demos.antixssdemo.controllers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/")
public class HomeController {
@RequestMapping("/xss-reflected")
@ResponseBody
public String xssDemo(@RequestParam("param") String userInput) {
return userInput;
}
}
The demo:
At step 2, I have used the html tag h2. You should see a Runtime exception thrown from Filter, what happened is: The Filter intercepts all urls(because of urlPatterns=/**), for each interception doFilter is called, if the user supplied Html content, then HtmlUtils.htmlEscape will return the filtered string, in other words, the returned string is different from the original one, this means the user supplied Html in his json input, which is not what we expect, so we throw the exception, if the returned string is the same as the string returned by htmlEscape(userInput) this means the user has not supplied any Html content, in that case we let the request pipeline to flow as usual with filterChain.doFilter(servletRequest, servletResponse); I am not using a live XSS demo because chrome will most likely protect you since it is a very basic reflected XSS detected by anyone ...
The Spring Boot skeleton project was downloaded from https://start.spring.io/ with Web as the only starter dependency.
Edit: Improved code
First of all , concept to protect against vulnerabilities has nothing to do with SpringBoot and XSS is one of those vulnerabilities.
This vulnerability is protected by implementing a org.springframework.web.filter.OncePerRequestFilter
and depending on which top framework you use & what kind of app you have - filter registration & chaining process has to be implemented.
Idea is to simply sanitize every incoming JSON body & call next filter in chain with sanitized request body.
If you have a Spring based project, you should first try to use Spring Security dependencies and enable default security features. refer this question
For xss protection , offered by spring security they have this disclaimer -
Note this is not comprehensive XSS protection!
In my case, I wrote a custom XSS protection filter implementing - org.springframework.web.filter.OncePerRequestFilter
In this filter- I have used this API ,
<dependency>
<groupId>org.owasp.esapi</groupId>
<artifactId>esapi</artifactId>
</dependency>
In my code , I have listed down possible attack patterns but I guess there might be better way to do it.
Refer these two on SO to know more as what I am talking about - XSS filter to remove all scripts & How to Modify QueryParam and PathParam in Jersey 2
Answer by Melardev is explaining the only case for @RequestParam
& you have to extend that approach to handle the case when its a JSON body. I have handled the case of a json body but can't share my code due to company copy right .
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With