Skip to content

Split XSS rules by response content type — error for HTML responses, info for the rest #85

@seqradev

Description

@seqradev

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:

  1. 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
  2. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions