Reflected (Non-Persistent) XSS
Non-persistent XSS: two flavors
Non-persistent XSS does not survive a normal revisit without replaying the same request. It affects whoever triggers that response (often one user at a time), not everyone who loads a shared page.
| Type | Where it is processed | Reaches back end? |
|---|---|---|
| Reflected XSS | Server reflects input into the HTML response | Yes |
| DOM-based XSS | Client-side code writes untrusted data into the DOM | Often no (dangerous string may never be stored or echoed by the server the same way) |
Unlike persistent (stored) XSS, non-persistent issues are temporary: leave the page or reload without the same parameters, and the injected output usually does not run again.
What reflected XSS is
Reflected XSS happens when user input is sent to the back end, then returned in the response without proper filtering or encoding. Common sinks include error messages, confirmation text, search results, or any UI that echoes the full input into HTML.
If the reflection is HTML context and unencoded, a PoC such as <script>alert(window.origin)</script> may execute when that response is rendered.
Lab pattern (to-do style app)
A to-do app may show errors like Task 'test' could not be added. with your string inside the message. That pattern is a candidate for reflected XSS if the value is inserted raw into the page.
After submitting a script payload, the visible error might show empty quotes (e.g. Task '' could not be added.) because the browser executes the <script> and does not display its contents as normal text. View page source confirms the payload still appears in the HTML, for example:
<div style="padding-left:25px">Task '<script>alert(window.origin)</script>' could not be added.</div>
Confirming non-persistence
Open the same URL again without the parameters or body that caused the error. If the message and XSS do not reappear, the issue is non-persistent (reflected) rather than stored.
Delivering reflected XSS to a victim
Impact is still serious: you must get the victim to issue the same HTTP request that reflects the payload.
- Use Developer Tools (e.g. Firefox:
Ctrl+Shift+I) → Network tab, submit the payload, and inspect the request method and shape. - If the app uses GET, parameters appear in the URL. Copy the full URL from the address bar or via Copy → Copy URL on the request. Sharing that link can execute the payload when the victim loads it, e.g.
http://SERVER_IP:PORT/index.php?task=<script>alert(window.origin)</script>
For POST-only reflection, delivery typically requires social engineering (tricking the victim into submitting a form), CSRF-style tricks, or other ways to force the browser to send the right request—not just a single malicious link.