2

I am trying to add custom XSS protection by creating a RequestWrapper extending HttpServletRequestWrapper in an XSS filter. The below code provides XSS protection to: 1. Request Params 2. Payload.

public class XssRequestWrapper extends HttpServletRequestWrapper {

  XssRequestWrapper(HttpServletRequest request) {
    super(request);
  }

    @Override
    public String getQueryString() {
    /*
    Custom XSS logic 
    */
    }

    @Override
    public String getParameterMap() {
    /*
    Custom XSS logic 
    */
    }

    @Override
    public String getParameterValues() {
    /*
    Custom XSS logic 
    */
    }

}

But when I configure my REST Api with @RequestBody Annotation in my controller, the overridden getParameterValues is not invoked. Instead, getInputStream is invoked, which results in the addition of the following:

 @Override
  public ServletInputStream getInputStream() throws IOException {
    /*
    Custom XSS logic 
    */
  }

Is there any better/ideal way to provide XSS protection to data passed via @RequestBody annotation?

Edit: Solution: https://www.baeldung.com/spring-reading-httpservletrequest-multiple-times Since I was using ContentCachingRequestWrapper in one of my previous filters, I was unable to use the same and hence went forward with the above solution. By Caching the request, I was able to read it multiple times and perform XSS check over the cached content.

noob
  • 141
  • 1
  • 2
  • 8

1 Answers1

2

I am a bit confused of what you are trying to achieve with the code.

First thing first - there are three types of Cross-site Scripting (XSS) vulnerabilities:

  1. DOM based - runs in the browser often due a flaw in JavaScript. No server calls are needed for the vulnerability to be exploited.
  2. Reflected XSS - the payload gets reflected in the HTML body by the web server.
  3. Persistent XSS - the payload lands in the DB and is embedded in the HTML body by the web server.

So there are no ways you can address the DOM based XSS with a request wrapper because there is no need for a request to be made.

You might try to address the points 2 and 3, but handling with the request values is a uncommon thing to be done. XSS vulnerabilities are context sensitive, and if you try to encode or escape without knowing the context in which the value is to be used later - you might and will fail.

Please look over the XSS prevention cheat sheet from OWASP to learn how to prevent XSS flaws in the code.

Marek Puchalski
  • 3,286
  • 2
  • 26
  • 35
  • Thanks for the reply. To clear out, I am trying to resolve the solution in the below thread. https://stackoverflow.com/questions/49439020/spring-boot-escape-characters-at-request-body-for-xss-protection And am trying to fix Stored XSS cases, wherein there is an input validation at the filter level that checks the request payload. – noob Feb 17 '20 at 06:39
  • In the stored XSS case the payload you want to escape comes from the database, not from the request. You probably want to deal with the reflected XSS case. – Marek Puchalski Feb 17 '20 at 13:26
  • The payload is coming from client. Apart from handling reflected XSS in my front-end, there are cases where payload can be sent via REST clients. In those cases, I need to add input validation in server logic at filter level. – noob Feb 18 '20 at 08:59
  • Did you got the solution? As i am also facing the same issue and want to escape request/response body – NobesInd Jul 03 '20 at 13:20
  • @NobesInd I have attached the solution to the question, please check it out. Also, another approach is to override getParameterValues in HttpServletRequestWrapper wherein the whole request body is passed as a JSON string, through which we can apply validations or transformation. – noob Nov 09 '20 at 18:17