BugForge - Weekly - Galaxy Dash
Weekly - Galaxy Dash
Vulnerabilities Covered:
Stored XSS (Second-Order) viacargo_sizeParameter
Session Hijacking via localStorage JWT Token Extraction
Account Takeover via Support User Token Theft
Summary:
This walkthrough demonstrates a stored cross-site scripting (XSS) vulnerability in a delivery booking application where unsanitized user input in thecargo_sizefield is persisted server-side and reflected without sanitization when an order invoice is rendered, classifying this as second-order XSS. A crafted payload that reads the viewer’s JWT token from localStorage and exfiltrates it to an external endpoint was injected at booking creation. Because the application stores JWT tokens in localStorage and exposes a support request feature, the malicious booking was submitted for support review. When the support agent opened the invoice, their session token was silently captured and used to authenticate as the support user, with the challenge flag returned in theX-Flagresponse header.
Reference:
Bugforge.io
Solution
Step 1 - Application Analysis & Directory Enumeration
Inspecting the authentication flow, the application stores the JWT token in localStorage rather than an HttpOnly cookie, making it accessible to any JavaScript executing on the page.
Testing the order and delivery functionality revealed a new feature: Request Support, available from the delivery list.
Step 2 - Identifying the XSS Injection Point
Testing the delivery booking for injection vulnerabilities, the cargo_size field was found to be vulnerable to XSS. The payload is not executed at the point of injection, it is only triggered when the order invoice is opened. This deferred execution is characteristic of second-order XSS: the payload is stored in one context (the booking creation request) and executed in a separate context (the invoice render), typically triggered by a different user action or a different user entirely.
Step 3 - Extracting the JWT Token via XSS
With confirmed XSS execution on the invoice page, a payload was crafted to read the JWT token from localStorage and exfiltrate it to an external listener on webhook.site.
The payload successfully extracted the token and sent it as a callback to webhook.site, confirming that any user who views the invoice will have their session token captured.
Navigating to the invoice for order 11 triggered the payload, and the token was received on webhook.site. Confirming end-to-end exfiltration.
Step 4 - Targeting the Support User
Using the Request Support feature, the malicious delivery was submitted for review. When the support agent opened the invoice, the second-order XSS payload executed in their browser context and sent their JWT token to webhook.site.
The support user’s token was received on webhook.site.
Step 5 - Session Hijacking & Flag Retrieval
The captured token was placed into localStorage, replacing the current session. After refreshing the page, the session was authenticated as the support user.
No flag was visible in the UI, but inspecting the booking API response revealed the X-Flag header containing the challenge flag.
Impact
- Account takeover of privileged internal users (support agents) via session token theft
- Complete bypass of authentication and access controls through stolen JWT credentials
- Exposure of any data accessible to the compromised support account, including internal delivery records
- Silent, user-interaction-triggered exploitation with no visible indicators to the victim
- Potential for lateral movement to other application features or tenants accessible from the support role
Vulnerability Classification
- OWASP Top 10: A03:2021 - Injection / A07:2021 - Identification and Authentication Failures
- Vulnerability Type: Stored XSS (Second-Order) leading to Session Hijacking and Account Takeover
- Attack Surface: Delivery booking
cargo_sizeparameter; order invoice render; support request workflow - CWE:
- CWE-79 - Improper Neutralization of Input During Web Page Generation (Cross-site Scriating)
- CWE-1004 - Sensitive Cookie Without ‘HttpOnly’ Flag (analogous misuse: JWT stored in accessible localStorage)
- CWE-384 - Session Fixation
Root Cause
The application fails to sanitize or encode user-supplied input stored in the cargo_size field before reflecting it in the invoice HTML. Because the payload executes in a different rendering context than where it was submitted, standard reflected XSS mitigations (e.g., per-request output encoding checks) are insufficient without addressing the stored value. Compounding the issue, the application stores JWT session tokens in localStorage rather than HttpOnly cookies, making them accessible to any JavaScript running on the page. The combination of unsanitized stored output and token storage in a JavaScript-accessible location creates a complete exploitation chain from XSS to account takeover.
Remediation
- Sanitize and HTML-encode all user-supplied input before storing it, and again before rendering it in any HTML context, including invoice templates
- Store JWT tokens in HttpOnly, Secure, SameSite cookies rather than localStorage to prevent JavaScript access
- Implement a strict Content Security Policy (CSP) to restrict script execution sources and block inline scripts
- Apply input validation on the
cargo_sizefield to reject unexpected characters or payloads at the API boundary - Audit all stored data rendering paths to identify other second-order XSS opportunities where stored values are reflected in separate contexts
- Add automated security scanning for XSS in stored fields as part of the CI/CD pipeline












