XSS Payloads in JSP: Why the Output Context Matters
How I evaluate a small set of historical XSS probes and separate WAF behavior from a browser-confirmed application vulnerability.

Contents
Start with the rendered page
A WAF can block suspicious requests, but it does not remove an application's responsibility to handle untrusted input safely. When I investigate cross-site scripting in a JSP application, I follow the input into the rendered response and the browser context where it appears.
My old note listed three payloads without the surrounding page, application version, WAF rules, or browser result. That makes them examples to investigate, not demonstrated bypasses.
There is no single JSP context in which every XSS payload works. Input can land in HTML text, an attribute, a URL, or JavaScript. Each boundary changes what the browser can interpret.
Authorized testing only
Only run this against systems you own or have written permission to test.
The original probes
I keep the first probe exactly as it appeared in my notes:
["');alert('CYBERTIX');//"]@bug.xss
The quotes, parentheses, and comment characters suggest an attempt to break out of a surrounding context. The string alone does not identify that context. If it is rendered as escaped text, it may remain harmless data.
The other two probes were:
<script ~~~>alert(0%0)</script ~~~>
%09Jav%09ascript:alert(document.domain)
I do not describe either as a general WAF bypass. Their effect depends on how the request is decoded, how the value is inserted into the response, and how the browser parses the resulting document.
In particular, a percent-encoded sequence in the submitted request is not proof that the browser sees the same bytes. An application, proxy, or framework may decode or transform the value along the way.
How I test the boundary
I start with a recognizable text marker and inspect where it appears in the response. Then I identify the output context before choosing a probe.
- Capture an accepted baseline request.
- Submit one marker through one input.
- Inspect the raw response and the browser's parsed page.
- Identify the exact text, attribute, URL, or script context.
- Run one context-appropriate, harmless proof.
- Record the browser result and compare it with the WAF decision.
I keep a blocked request, a reflected string, and executed JavaScript as different outcomes. A WAF accepting the request proves only that the request passed that control. It does not prove an exploitable browser result.
Fix the sink, then retest the control
I use the OWASP XSS prevention guidance to choose encoding for the actual output context. I avoid inserting request values directly into inline JavaScript or other difficult-to-encode locations.
For JSP, I inspect the tag or helper that writes the value. I do not assume that a value is safely escaped just because it appears inside ${...}. Where the feature intentionally allows HTML, I use an appropriate HTML sanitizer rather than treating ordinary output encoding as a rich-text policy.
A suitable Content Security Policy can reduce impact, but it is an additional control. I still fix unsafe rendering and retest both the original input and an ordinary value the feature should accept.
The finding is ready when I can show the original context, the browser behavior, and the corrected rendering. A payload list without that chain leaves the most useful part unexplained.
Ask or Share Thoughts
Your message goes straight to me. Email is optional. The form records your IP address and browser information.





