Hello @joevin, hello @ranjeet-sys1,
Here are some answers to try to clarify this thread definitively.
-
The issue related to ResponseBody and ResponseEntity was noticed and discussed in our internal forums back in 2020. The problem has since been fixed in SonarQube. SonarQube 8.3 is from 2020, so it is essential for your business and user experience that you update SonarQube.
-
@ranjeet-sys1 I think that your use case is different from Joévin’s. Please create another post so that we can discuss a potential fix. Else, if we assume that your use-case is to create JSON, the fix provided by Pierre-Loup is relevant (e.g. adding produces="application/json"
in the mapping, without having to change types). Thanks to this attribute, you can also change the return type to a @ResponseBody String
, and only return a string: the response will be json data.
-
Regarding the XSS: The issues you mention are related to Spring’s HttpMessageConverters. These converters are directly responsible for how the data and content type are returned in your web application’s responses.
For example, for a ResponseBody<String>
, the StringHttpMessageConverter
is used, which treats the returned data as a simple string and sets a text content-type
(if we assume a simple curl command and a generic Spring MVC configuration).
For other objects, other message converters are used. For example, handling of form data is likely to be performed by a FormHttpMessageConverter
.
@joevin, in your first example: If a ResponseBody<String>
returns something other than regular text-based data and a content type of text/...
, it means that global configuration parameters have explicitly changed this. This process depends on multiple factors, some of them being in other parts of your code.
In the contrary, if the attribute produces="application/json"
is set, but the return string is not a valid JSON, the result content-type will be different.
In other cases, such as with custom objects, Spring tries to figure out which internally registered HTTP message converters can be used to return data and set a content-type value. Depending on your configuration, the converter might convert the data to XML or JSON, for example. In general, the converters work by deserializing the data returned or received by the code. (I am assuming that you use <mvc:annotation-driven />
.)
@joevin, in your second code example: you used a UserDto
and a Map
as ResponseEntity
types in your last snippets. The StringHttpMessageConverter
cannot be the converter used to send data in this case, so another converter was used, serialized the data into JSON format and associated a JSON content-type.
Note: If the configuration was different, the returned data could have been XML.
Creating a Map is IMHO the most simple way to send back JSON.
@joevin, in your first post, you said:
The third one changes integrity of the data (replacing < by < ; for exemple). Resulting in unpredictable and undesirable behavior. And requires knowing the front-end context. Exemple : ESAPI.encodeForHtml().
Note that when we say “encoding”, we also include Javascript or JSON encoding, not only HTML encoding. This means that the encoding has to be chosen according to its context of use, and that if the right encoder is chosen, no integrity loss will be experienced.
We will need to clarify this in future versions of the rule. Thanks for the feedback.
@joevin, regarding your last question:
Does the latest [S5131] updates takes into account this content type specificities ?
As mentioned above, these peculiarities have been taken into account since 2020. We still need to continuously improve, but you should not experience these false positives when you update SonarQube.
I hope my message answers your questions. For this case, a SonarQube upgrade is the (theoretically) simple solution. I recommend you reach out to Sonar’s support if you need help upgrading.
In any case, thank you very much for your feedback. It is very much appreciated!
Loris