Skip to content

Writing XSS reports developers can actually fix

A useful XSS report explains context, execution path, impact, and remediation without dumping a payload and hoping the team understands it.

Published on 2 min read

Many XSS reports fail after the payload works.

The tester proves execution, takes a screenshot, pastes the payload, and writes "sanitize input." The developer cannot reproduce it, the security team asks for clarification, and the report spends two weeks in triage. Everybody loses.

A payload is evidence. It is not the whole report.

Context is the first remediation hint

The fix depends on where the data lands. HTML body, quoted attribute, URL attribute, JavaScript string, DOM sink, Markdown renderer, rich text editor. These are not interchangeable.

Write the context plainly:

The value of `displayName` is rendered inside a double-quoted HTML attribute
without escaping quotes. Breaking out of the attribute allows an event handler.

That sentence already points toward contextual output encoding. It is much better than "filter special characters."

Include the boring reproduction details

Reproduction steps should survive a handoff. Include the browser, route, account role, request parameter, stored field, or UI action. If timing matters, say so. If the payload only fires after page refresh, say so. If CSP blocks execution but the markup injection is present, say so.

Example:

1. Log in as a workspace admin.
2. Set project name to the payload below.
3. Open `/admin/projects`.
4. The payload executes when the table row is rendered.

Do not hide behind "open the page." Which page? Which role? Which state?

Separate proof from impact

alert(1) proves JavaScript execution. It does not explain impact. Impact depends on cookies, tokens, CSRF posture, same-origin APIs, stored vs reflected behavior, account roles, and user interaction.

If the app uses HttpOnly cookies and strict same-site settings, say what is still possible. Can the script read CSRF tokens from DOM? Can it call same-origin APIs? Can it modify account settings? Can it phish inside the trusted origin?

Avoid fantasy impact. Realistic impact is stronger.

Remediation should match the bug

For server-rendered HTML injection, recommend contextual output encoding in the template layer. For DOM XSS, recommend replacing innerHTML with safe DOM APIs or sanitizing with a maintained sanitizer configured for the expected markup. For URL sinks, validate protocols. For CSP issues, fix the unsafe rendering first and use CSP as defense in depth.

This is the level of specificity developers need.

The best XSS report is not the one with the cleverest payload. It is the one that makes the broken data path impossible to ignore and straightforward to patch.

Related articles

Payload choice is less important than injection context. HTML body, attributes, URLs, scripts, and DOM sinks all fail differently.
Responsible XSS testing depends on scope, evidence discipline, data minimization, and knowing when a proof of concept has gone far enough.
A practical look at why XSS tooling should avoid server-side processing when testers are handling internal URLs, private snippets, and sensitive payload notes.