SonarQube XSS vulnerability in @GetMapping method

Hello everyone,

I’m getting a SonarQube error: “Uncontrolled user input is passed to Cross-Site Scripting (XSS) sink” for this endpoint:

The firstName field in CustomerNameFromProfileDto comes from the database and is displayed in the frontend. SonarQube flags this as potential XSS risk.

Снимок экрана 2025-08-26 235442

I’ve already implemented validation in the DTO:

public record CustomerNameFromProfileDto(
    @NotBlank @Size(min = 2, max = 50) String firstName
) {}

Should I:

  1. HTML-escape the response before returning it?

  2. Use some other approach to satisfy SonarQube?

  3. Is this a false positive since the data comes from my database?

What’s the best practice here? The data is validated on input but SonarQube doesn’t seem to recognize this.

Thanks for your help!

1 Like

Hello,

Have you had a chance to reanalyze the project since implementing the validation?

Just a reminder: injection vulnerabilities require a reanalysis on the SonarQube server side—they won’t be detected live in the IDE. That includes making them go away once you’ve fixed them.

Hi @Strybjorn_Grimskull, welcome to these forums ! I am in the AppSec team in charge of creating these detection rules.

Here it looks like SQ for IDE did not highlight correctly what it needed to highlight. From your screenshot, it looks like the attack vector is actually the email string, not the customer name.

Can you confirm whether the email string is concatenated to the customerName when it is passed to getCustomerNameByEmail ?

If it is not concatenated, can you show us what happens in getCustomerNameByEmail please? where does email ends up ?

If it is concatenated, I suggest following the instructions from this page, this is a public SQ instance and you should have the equivalent on yours:

Cheers!

Loris

Hello,

Yes, I have reanalyzed the project after implementing the validation.

Validations are not working at all. For example, I tried this one:

public record CustomerNameFromProfileDto(
        @Pattern(regexp = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
                message = "Invalid input: only letters, numbers and spaces allowed")
        String firstName) {
}

Hello!

There is no concatenation. Here is my service, I don’t think it’s suspicious:

@Transactional(readOnly = true)
public CustomerNameFromProfileDto getCustomerNameByEmail(String email) {
            return customerRepository.findCustomerNameByEmail(email);
}

And this is the database query:

@Query("SELECT new com.byteforge.byteforge.dto.response.CustomerNameFromProfileDto(p.firstName) " +
        "FROM Customer c " +
        "JOIN c.profile p " +
        "WHERE c.email = :email")
CustomerNameFromProfileDto findCustomerNameByEmail(@Param("email") String email);

With DTO validation,

public record CustomerNameFromProfileDto(
        @Pattern(regexp = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
                message = "Invalid input: only letters, numbers and spaces allowed")
        String firstName) {
}

SonarQube warns about an XSS attack in my controller

IntelliJ IDEA 2025.2

SonarQube for IDE 10.30.0.82084

But if I use HtmlUtils.htmlEscape as in this quick example,

@GetMapping("/name")
public ResponseEntity<CustomerNameFromProfileDto> getCustomerName(Authentication authentication) {
String email = authentication.getName();
CustomerNameFromProfileDto customerNameDto = profileService.getCustomerNameByEmail(email);
String name = HtmlUtils.htmlEscape(customerNameDto.firstName());
    return ResponseEntity.status(HttpStatus.OK).body(new CustomerNameFromProfileDto(name));
}

then SonarQube passes the controller.

Hy Strybjorn, if “email” is concatenated nowhere, you can dismiss this issue. It’s still a good practice to html encode the name, so you might be actually solving another vulnerability. But you can definitely dismiss the issue :+1:

1 Like

Hi @Strybjorn_Grimskull,

After investigating this problem internally, we came to the conclusion that this issue was not raised by SonarQube, but another one of your linters, could you tell us which one ?

The hint was that:

  1. We cannot reproduce this issue ourselves
  2. We do not send the message Uncontrolled user input is passed to Cross-Site Scripting (XSS) sink, we write Change this code to not construct SQL queries directly from user-controlled data. or an equivalent message

Cheers,

Loris

Hi!

I will definitely take a look, but those warnings were specifically from SonarQube. It’s strange, and that’s exactly why I’m on this forum.

Ah I see ! In that case, if it comes from SonarQube, it might come from a non-official plugin. You should get a hint of where it’s from by checking the SQ page of the finding. For example by checking this ID:

I’m so embarrassed!

It was actually “Security Analysis”.:melting_face: :melting_face: :melting_face:

I’m so sorry!

No problem at all!!

The specific Application Security questions are so rare on that forum that I am always very happy to answer hahaha

I was just reinstalling IDEA to a new version and didn’t notice it appear.":sweat_smile:

1 Like