Summary
The current XSS rules (xss-in-servlet-app, xss-in-spring-app) always report at ERROR severity regardless of the response context. They should be split into two rules each: an ERROR-level rule that fires when the response is more likely rendered as HTML, and an INFO-level rule for all other cases. This would reduce noise from findings where XSS exploitation is unlikely while keeping high-confidence HTML-context findings front and center.
Problem
Today, every XSS finding is reported as ERROR. In practice, not all responses containing untrusted data are equally exploitable. Writing user input into a response with Content-Type: text/html (or returning HTML strings from a Spring controller) is directly exploitable — the browser renders the payload as markup. Writing the same input into a JSON API response or a plain-text endpoint is far less likely to result in browser-side script execution.
As a result, users either over-triage (reviewing every XSS finding equally) or lose trust in findings when many turn out to be low-risk non-HTML contexts.
Notes
Each existing XSS rule (xss-in-servlet-app, xss-in-spring-app) should become two rules:
-
ERROR rule — fires when there is evidence that the response is rendered as HTML. Signals that include:
response.setContentType("text/html") or similar calls setting an HTML content type
- Spring
@RequestMapping(produces = "text/html") or equivalent mapping annotations with HTML produces
- Writing to a response inside a servlet that explicitly sets HTML content type
- Spring controller method returning a
String directly (via @ResponseBody or @RestController) where the content type resolves to HTML
-
INFO rule — fires for all other cases where untrusted data flows to a response sink but there is no evidence of HTML rendering. This covers JSON APIs, plain-text responses, and cases where the content type is not determinable.
The rule IDs should make the distinction clear (e.g., xss.servlet-app.html-response / xss.servlet-app.json-response, or a similar naming convention consistent with existing rules).
Existing behavior for the xssrequestwrapper-is-insecure and wicket-xss rules is unaffected — those are pattern-based and already appropriately scoped.
Summary
The current XSS rules (
xss-in-servlet-app,xss-in-spring-app) always report at ERROR severity regardless of the response context. They should be split into two rules each: an ERROR-level rule that fires when the response is more likely rendered as HTML, and an INFO-level rule for all other cases. This would reduce noise from findings where XSS exploitation is unlikely while keeping high-confidence HTML-context findings front and center.Problem
Today, every XSS finding is reported as ERROR. In practice, not all responses containing untrusted data are equally exploitable. Writing user input into a response with
Content-Type: text/html(or returning HTML strings from a Spring controller) is directly exploitable — the browser renders the payload as markup. Writing the same input into a JSON API response or a plain-text endpoint is far less likely to result in browser-side script execution.As a result, users either over-triage (reviewing every XSS finding equally) or lose trust in findings when many turn out to be low-risk non-HTML contexts.
Notes
Each existing XSS rule (
xss-in-servlet-app,xss-in-spring-app) should become two rules:ERROR rule — fires when there is evidence that the response is rendered as HTML. Signals that include:
response.setContentType("text/html")or similar calls setting an HTML content type@RequestMapping(produces = "text/html")or equivalent mapping annotations with HTML producesStringdirectly (via@ResponseBodyor@RestController) where the content type resolves to HTMLINFO rule — fires for all other cases where untrusted data flows to a response sink but there is no evidence of HTML rendering. This covers JSON APIs, plain-text responses, and cases where the content type is not determinable.
The rule IDs should make the distinction clear (e.g.,
xss.servlet-app.html-response/xss.servlet-app.json-response, or a similar naming convention consistent with existing rules).Existing behavior for the
xssrequestwrapper-is-insecureandwicket-xssrules is unaffected — those are pattern-based and already appropriately scoped.