CAP-PL ENS study materials
CAP-PL ENS study resources

The Disputed XSS Finding and a Live Token in the Appendix

CAP-PL ENS · Put your knowledge to work in context.

All case studies

The Disputed XSS Finding and a Live Token in the Appendix

You deliver a web application assessment for a healthcare SaaS provider. One finding is reflected XSS on the patient portal search page: the q parameter is reflected unencoded into an HTML attribute (value="..."), and a payload using a double quote plus an onfocus handler executes in current Chrome. The client's head of engineering replies that the finding is 'already mitigated': the site returns a Content-Security-Policy header in report-only mode, session cookies are set HttpOnly, and the WAF blocks the string '<script'.

Separately, the privacy officer asks you to remove the full Cookie header from the report appendix because it contains a live session token for a test account that can reach production-like patient data. The report goes to their regulator in three business days. The engineering team has also offered to 'walk you through why it doesn't work' on a call before you finalize.

1. Evaluate each claimed mitigation and decide the final classification.

Read the worked answer

CSP in report-only mode: no mitigation. Report-Only generates violation reports and blocks nothing. It becomes a control only when enforced with a policy that forbids inline handlers; the finding itself uses an inline event handler, so a strict enforced policy would genuinely break the payload - that is the one path to downgrading, and it requires a retest.

HttpOnly: no mitigation for XSS. It prevents script from reading the cookie, which limits session-token theft. It does not stop script running in the victim's origin, reading the DOM, submitting requests with the victim's session, harvesting CSRF tokens or exfiltrating on-screen patient data. Reflected XSS in a clinical portal is a direct path to acting as the victim.

WAF blocking '<script': bypassable with attribute-breaking payloads, SVG event handlers, and case or encoding variants; here the injection point is inside an attribute, so no script tag is needed at all. Blacklist WAFs are a speed bump, not a fix, and cannot be verified as durable.

Classification: retain as reflected XSS. Medium at minimum; High if the search page is reachable by unauthenticated users or renders patient identifiers. Not Informational. Add a short residual-risk subsection that evaluates each claimed control, so the regulator sees the analysis rather than a bare assertion.

2. How do you handle the request to remove the Cookie header, while keeping the evidence usable?

Read the worked answer

Redact the secret, never the evidence.

In the report body and appendix: replace the value with Cookie: JSESSIONID=[REDACTED-1], keep the header name, the approximate token length, cookie attributes (Secure, HttpOnly, SameSite, expiry), the request line, timestamp, and response. Note in a redaction log that a live session token was present and was removed. The request is the proof that the payload reached the server; deleting the whole header weakens the reproduction for no security benefit.

Evidence integrity: hash the original capture (SHA-256) before redaction and record the hash in the report's evidence table. Store the unredacted capture only in the encrypted evidence repository with named access, not on a share or in email. Never paste the token into a chat or a ticket.

Token lifecycle: ask the client to confirm the test account's sessions were revoked at engagement close, and note that confirmation in the report. If the token is still valid, that is an operational issue worth flagging privately rather than in the regulator-facing document.

Regulator context: a redaction log is exactly what a regulator expects to see; an unexplained absence of headers is more likely to generate follow-up questions than a documented redaction.

3. The engineering team offers a call to explain why the finding 'doesn't work'. How do you run that call and what is the outcome you are aiming for?

Read the worked answer

Accept the call, but set the frame first: it is a technical verification call, not a negotiation, and the report deadline does not move.

Before the call: send the exact request and response, browser version, and a screen recording or screenshot of execution with the victim's privileges. Ask them to reproduce from the same artifact rather than from memory.

During the call: have them share their screen and run the payload in a test account. If it fails for them, find out why - enforced CSP on a staging host, an authenticated-only route, a different template. Any difference is a finding about their staging/production configuration and needs to be written down. If it succeeds, the discussion is over and the next topic is the fix.

Outcome you want: agreement on the observed behavior, not agreement on the severity label. Engineers often accept a reproduction while disputing a rating; separating the two resolves most disputes. If they still disagree, offer to publish their position verbatim in a short 'client response' box next to the finding - this is standard practice and protects everyone.

After the call: send a written summary of what was demonstrated and any config differences found, and record it in the engagement file.