September 3, 2026
My Autonomous Hunt Harness Found a Reflected XSS That Could Expose a Billing Session
While running my autonomous web-security hunting workflow, I identified a reflected cross-site scripting vulnerability on a payment/billingβ¦
By redhunter01
7 min read
While running my autonomous web-security hunting workflow, I identified a reflected cross-site scripting vulnerability on a payment/billing endpoint.
What initially looked like a simple input-reflection issue became much more interesting after tracing the full authentication and session model.
The vulnerable endpoint reflected a path parameter directly into an HTML attribute without proper HTML encoding. Because the application also lacked a Content Security Policy and exposed its billing session cookie to JavaScript, the XSS could access the ACCIDSESSID session cookie.
The most important part of this finding wasn't simply discovering <svg onload> execution.
It was connecting several seemingly separate security weaknesses:
Unencoded path reflection β JavaScript execution β readable session cookie β portable session bearer
My autonomous hunt harness helped identify and validate that chain without relying on the application's UI.
The Initial Discovery
The affected endpoint followed this structure:
GET /authenticate/confirm/{token}
The {token} value was reflected into an HTML attribute on the response page.
The application generated a link similar to:
<a href='/authenticate/{token}' class='btn btn-custom ...'><a href='/authenticate/{token}' class='btn btn-custom ...'>The important detail was that the path parameter was URL-decoded but not HTML-entity encoded before being inserted into the page.
That immediately created a potential HTML injection sink.
My automated workflow flagged the parameter because it behaved differently from normal encoded parameters:
- The parameter was reflected into the response.
- HTML metacharacters were preserved.
- The response was returned with HTTP 200 even for arbitrary token values.
- The reflected value appeared inside an HTML attribute.
- There was no effective Content Security Policy.
That gave the harness enough evidence to classify the endpoint as a potential reflected-XSS candidate.
How My Autonomous Hunt Harness Approached It
Instead of treating every reflection as an XSS automatically, my workflow follows a validation chain.
The process was roughly:
Endpoint discovery
β
Parameter extraction
β
Reflection detection
β
Context identification
β
Encoding analysis
β
Metacharacter testing
β
HTML breakout
β
Browser execution
β
Origin verification
β
Cookie accessibility check
β
Session replay analysisEndpoint discovery
β
Parameter extraction
β
Reflection detection
β
Context identification
β
Encoding analysis
β
Metacharacter testing
β
HTML breakout
β
Browser execution
β
Origin verification
β
Cookie accessibility check
β
Session replay analysisThis is important because reflection alone doesn't necessarily mean XSS.
The interesting question is:
Can the reflected data actually transition from attacker-controlled input into executable browser context?
In this case, the answer was yes.
Finding the HTML Injection Context
A benign request first established the normal behavior.
The server returned content equivalent to:
<a href='/authenticate/BENIGN123' class='btn btn-custom ...'><a href='/authenticate/BENIGN123' class='btn btn-custom ...'>I then tested whether HTML attribute delimiters were being encoded.
The response instead reflected attacker-controlled characters directly:
<a href='/authenticate/x'><svg onload=...>' class='btn btn-custom...'><a href='/authenticate/x'><svg onload=...>' class='btn btn-custom...'>The important characters were:
'
>
<'
>
<The single quote terminated the original href attribute.
The > terminated the opening anchor element.
The injected SVG element then became part of the browser's DOM.
This demonstrated that the server wasn't simply displaying the input β it was placing the input into an executable HTML context.
Why a Valid Token Wasn't Required
One particularly useful observation was that the endpoint rendered successfully even when the supplied token was invalid or completely arbitrary.
That meant the vulnerable page itself did not require possession of a legitimate authentication token.
The attack therefore wasn't dependent on obtaining a valid token first.
An attacker could construct a malicious URL targeting the vulnerable endpoint and rely on the victim's browser to process it.
Browser-Level Confirmation
The next step was moving from server-side reflection to actual browser execution.
My autonomous workflow launched a real headless Chromium instance and loaded the crafted URL.
The injected JavaScript executed successfully.
More importantly, the browser reported the execution origin as:
https://gtfcharge.comhttps://gtfcharge.comThis distinction matters.
The JavaScript wasn't executing in an unrelated origin or an isolated context.
It was executing with the privileges of the billing domain.
That established:
Reflected input β DOM injection β JavaScript execution in the target origin
The finding was now a confirmed reflected XSS rather than merely an HTML-injection hypothesis.
The Session Cookie Discovery
At this point, the hunt moved beyond simply proving alert(origin).
The next question was:
What security-sensitive data is accessible from JavaScript running on this origin?
The application issued a billing session cookie named:
ACCIDSESSIDACCIDSESSIDThe cookie was returned without the HttpOnly attribute.
A representative cookie configuration was:
ACCIDSESSID=<value>; path=/ACCIDSESSID=<value>; path=/There was no HttpOnly flag.
That meant JavaScript executing on the billing origin could access it through:
document.cookiedocument.cookieThe browser confirmed that the injected JavaScript could read the cookie.
The session cookie was therefore not protected from JavaScript execution.
XSS + Missing HttpOnly
Individually, these two issues have different security implications.
A reflected XSS gives an attacker JavaScript execution in the victim's browser.
A missing HttpOnly attribute makes a session cookie accessible to JavaScript.
Together, they create a much more serious chain:
Attacker-controlled URL
β
Reflected XSS
β
JavaScript execution
β
document.cookie
β
ACCIDSESSID
β
Potential session takeoverAttacker-controlled URL
β
Reflected XSS
β
JavaScript execution
β
document.cookie
β
ACCIDSESSID
β
Potential session takeoverThe XSS therefore wasn't just a cosmetic page-defacement issue.
It provided access to a server-side session bearer.
The Session Replay Test
There was initially one important question:
Even if the cookie could be stolen, could an attacker actually reuse it from another client?
Rather than assuming the answer, I tested the session behavior directly.
A session was minted from one network/client context.
The same ACCIDSESSID value was then presented from a different network path and a different User-Agent.
The server returned:
HTTP/2 200HTTP/2 200and did not issue a replacement Set-Cookie.
This demonstrated that the session wasn't tied to the original IP address or User-Agent.
In other words, the cookie behaved as a portable bearer token.
That significantly strengthened the security impact of the XSS.
The Complete Attack Chain
The resulting security chain can be represented as:
Attacker
β
β malicious URL
βΌ
/authenticate/confirm/{token}
β
β token reflected without HTML encoding
βΌ
HTML injection
β
βΌ
Reflected XSS
β
β executes on billing origin
βΌ
JavaScript
β
β document.cookie
βΌ
ACCIDSESSID
β
β portable across clients
βΌ
Victim's billing sessionAttacker
β
β malicious URL
βΌ
/authenticate/confirm/{token}
β
β token reflected without HTML encoding
βΌ
HTML injection
β
βΌ
Reflected XSS
β
β executes on billing origin
βΌ
JavaScript
β
β document.cookie
βΌ
ACCIDSESSID
β
β portable across clients
βΌ
Victim's billing sessionThis is the type of chain that automated security testing can easily miss if each vulnerability is analyzed independently.
The interesting part was not only finding the XSS.
It was following the security consequences of the XSS.
What Was Proven
I deliberately separated confirmed behavior from assumptions.
The following was demonstrated directly:
1. Reflected XSS
Attacker-controlled input was reflected into an HTML attribute without proper HTML encoding.
2. JavaScript Execution
The injected payload executed successfully in a real Chromium browser.
3. Correct Security Origin
The JavaScript executed under:
https://gtfcharge.comhttps://gtfcharge.com4. Cookie Accessibility
Injected JavaScript successfully accessed document.cookie.
The response included the ACCIDSESSID session cookie.
5. Missing HttpOnly
ACCIDSESSID was issued without HttpOnly.
6. No Effective CSP
The page did not deploy a restrictive Content Security Policy preventing this execution path.
7. Session Portability
An ACCIDSESSID session could be replayed from a different client/network context without IP or User-Agent binding.
What I Did Not Claim Without Proof
One thing I always try to do in a bug bounty report is avoid turning a reasonable inference into a claimed fact.
The remaining question concerned the exact authenticated billing data and actions available after replaying a stolen authenticated session.
The application's broader authentication flow indicated that an authenticated billing session could expose sensitive customer information and billing functionality.
However, I did not claim an end-to-end victim-account compromise unless that specific path had been reproduced.
This distinction made the report stronger.
There is a big difference between:
"This should probably work."
and:
"I tested this and here is the evidence."
Good security research should clearly separate the two.
Why the Missing HttpOnly Flag Matters
The HttpOnly attribute exists specifically to prevent JavaScript from reading a cookie.
Without it, an XSS vulnerability can potentially turn into session theft.
The recommended configuration should look conceptually like:
Set-Cookie: ACCIDSESSID=<value>;
Path=/;
Secure;
HttpOnly;
SameSite=...Set-Cookie: ACCIDSESSID=<value>;
Path=/;
Secure;
HttpOnly;
SameSite=...The exact SameSite policy depends on the application's legitimate cross-site requirements.
The important point is that sensitive authentication cookies should not be unnecessarily accessible through document.cookie.
Why CSP Would Have Helped
The vulnerable page also lacked a restrictive Content Security Policy.
A strong CSP can provide an additional layer of defense against XSS.
For example, a deployment could consider policies containing restrictions such as:
script-src 'self';
object-src 'none';
base-uri 'none';script-src 'self';
object-src 'none';
base-uri 'none';CSP should not be considered a replacement for output encoding.
The primary fix remains:
Treat attacker-controlled input as data, not HTML.
CSP is defense in depth.
Root Cause
The core vulnerability was improper output encoding.
The application effectively performed:
User input
β
URL decoding
β
HTML attributeUser input
β
URL decoding
β
HTML attributewithout safely encoding the resulting value for the HTML context.
The correct security model should be:
User input
β
Validation
β
Context-aware HTML encoding
β
HTML attributeUser input
β
Validation
β
Context-aware HTML encoding
β
HTML attributeOr, where appropriate, reject values that don't match the expected token format.
For example, if tokens are strictly alphanumeric, accepting only a constrained format would substantially reduce the attack surface.
Recommended Remediation
I would address the issue at several layers.
1. Properly HTML-encode the token
The {token} value must be contextually encoded before being inserted into the HTML attribute.
2. Validate the token format
If legitimate tokens only contain a restricted character set, reject unexpected characters server-side.
For example:
^[A-Za-z0-9]+$^[A-Za-z0-9]+$if that matches the application's actual token specification.
3. Add a restrictive CSP
Deploy a suitable Content Security Policy as defense in depth.
At minimum, consider restrictions for:
script-src
object-src
base-uriscript-src
object-src
base-uri4. Protect session cookies
Sensitive authentication cookies should use:
HttpOnly
Secure
SameSiteHttpOnly
Secure
SameSitewith the appropriate SameSite policy for the application's architecture.
5. Avoid security decisions in the browser
Client-side protections should never be the primary security boundary.
The server should always assume that attacker-controlled input can reach it.
The Bigger Lesson for Bug Bounty Hunters
The most valuable part of this finding wasn't the payload.
It was the methodology.
A lot of automated scanners effectively stop at:
Input reflected β possible XSSInput reflected β possible XSSMy approach is different.
I want the workflow to continue asking:
Where is it reflected?
Is it encoded?
What context is it in?
Can the browser execute it?
What origin does it execute under?
What data can JavaScript access?
Are authentication cookies readable?
Can those sessions be replayed?
What additional functionality does the session expose?Where is it reflected?
Is it encoded?
What context is it in?
Can the browser execute it?
What origin does it execute under?
What data can JavaScript access?
Are authentication cookies readable?
Can those sessions be replayed?
What additional functionality does the session expose?Every answer changes the next testing decision.
That creates a chain rather than a collection of isolated scanner alerts.
How Autonomous Hunting Helped
The autonomous hunt harness was useful because it could continuously move between different layers of the application.
It wasn't limited to:
- crawling URLs
- fuzzing parameters
- checking status codes
It could correlate observations.
For this finding, the important observations were:
Reflection
+
HTML context
+
Missing encoding
+
Browser execution
+
Target origin
+
Missing HttpOnly
+
Readable session
+
Cross-client replayReflection
+
HTML context
+
Missing encoding
+
Browser execution
+
Target origin
+
Missing HttpOnly
+
Readable session
+
Cross-client replayAny single observation might not look particularly impressive.
Together, they formed a meaningful security chain.
A Useful Mental Model
When hunting XSS, don't stop at:
"Can I execute JavaScript?"
Ask:
"What does JavaScript executing here actually have access to?"
For example:
XSS
β
βββ Cookies?
β
βββ DOM?
β
βββ CSRF tokens?
β
βββ Account information?
β
βββ Internal API responses?
β
βββ Sensitive forms?
β
βββ Authenticated actions?XSS
β
βββ Cookies?
β
βββ DOM?
β
βββ CSRF tokens?
β
βββ Account information?
β
βββ Internal API responses?
β
βββ Sensitive forms?
β
βββ Authenticated actions?This approach often reveals the difference between a low-impact reflection and a serious security issue.
Final Takeaway
This vulnerability started as a simple reflected parameter.
But following the entire security chain revealed something more interesting:
Unencoded path parameter
β
HTML injection
β
Reflected XSS
β
JavaScript execution on billing origin
β
Readable ACCIDSESSID
β
Portable session bearerUnencoded path parameter
β
HTML injection
β
Reflected XSS
β
JavaScript execution on billing origin
β
Readable ACCIDSESSID
β
Portable session bearerThe main lesson for me was simple:
Don't stop when you prove the first vulnerability. Follow the trust boundary.
An XSS isn't just "JavaScript execution."
Its real impact depends on what that JavaScript can access and what authenticated functionality exists behind the origin.
That's where autonomous security hunting becomes particularly useful: instead of treating vulnerabilities as isolated findings, the harness can connect them into complete attack chains and prioritize the paths that actually matter.
Bug Bounty Status
The report was successfully validated during triage and moved forward for program review.
At the point of this writeup, the bounty decision is still pending program triage/review.
I'll update this section once the final bounty outcome is confirmed.