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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions