S5131 - Endpoints security and XSS attacks

Hi everyone,

I’m using SonarQube 8.3.

One “Vulnerabilities” “Blocker” is rising on my projects and poses me a problem.
Its “Refactor this code to not reflect tainted, user-controlled data.” and when I click on “Why is this an issue?” it mentions " Endpoints should not be vulnerable to reflected cross-site scripting (XSS) attacks".

This is related to this rule : [RSPEC-5131] Endpoints should not be vulnerable to reflected cross-site scripting (XSS) attacks - SonarSource

For me this rule is unnecessary and its treatment causes problems.
Prevent XSS vulnerabilities in front-ends contexts is necessary and they need to encode untrusted inputs (including inputs from API backends).

But prevent XSS on the backend API side break things. Solutions proposed are not sustainable :

  1. Validate data based on a whitelist
  2. Sanitize data
  3. Encode data

The first one is impossible if the data is a comment on a blog for example,
The second one abruptly removes data considered dangerous with a frequently incomplete blacklist (high complexity with a partially achieved security objective). Example : jsoup.clean().
The third one changes integrity of the data (replacing < by &lt ; for exemple). Resulting in unpredictable and undesirable behavior. And requires knowing the front-end context. Exemple : ESAPI.encodeForHtml().

This applies to all APIs.

Do you share the same point of view as I do?

Best regards,
Joévin.

Hi Joévin,

Do you have any code samples you could share?

If I understand you correctly you JSON-encode your output and thus you don’t think HTML-encoding it makes sense? I would tend to agree. If the content-type is set correctly it should not be exploitable. Unless the client is doing content type sniffing. But even then I do not think HTML-encoding is a good approach here because - as you said - it changes the data.
JSON provides its own way to encode special characters though, e.g. like this: \u003C. If this encoding is used the data inside of the JSON does not change but you are on the safe side even if type sniffing is done.

I would also recommend to update to the current version of SonarQube (9.1) if you have the chance because our analysis - including and especially XSS - has changed drastically since 8.3.

Hello Hendrick,
Thank you for your answer.
The code sample could be as simple as an endpoint on a Spring Boot application:

package fr.bpce.digital.collecte.controller;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class HelloController {

    @GetMapping(value = "/test/hello")
    public ResponseEntity<String> hello(@RequestParam(value = "name") String name) {

        return new ResponseEntity<>("Hello " + name + " !", HttpStatus.OK);
    }
}

And this code sample will throw the “Refactor this code to not reflect tainted, user-controlled data.” Issue.
When a GET /test/hello will be requested, the Spring Boot application will reply this JSON object:

{
    "name": "Joévin"
}

And by default, the header Content-Type is set to application/json. From there, when a front-end uses this data, it will be aware that it must adapt the data to the context in which it is inserted. Something that Angular/React/Vue does very well. I don’t think content type sniffing vulnerability is still relevant today in 2021 (unless you are using an old browser).
I went through the release note up to 9.1 but I didn’t see any major changes regarding XSS handling on the APIs. Unfortunately I can’t test SonarQube 9.1 easily.