Weak Session Identifiers
Most of this cluster assumes you have to steal a session identifier. This page is the case where you don’t need to: when the identifier is generated poorly - too short, sequential, or a reversible encoding of predictable data - you can derive or guess a valid one and hijack without ever touching the victim. Framework defaults (PHP, JSP, ASP.NET, Rails) produce strong IDs; this is a vulnerability of custom session management, so the first job is recognising when you’re looking at one.
# 1. Collect many identifiers (log in repeatedly / many fresh requests)# 2. Decode and look for structureecho 'dХNlcj0xMDE7dHM9MTc ...' | base64 -d → "user=101;ts=17..." ← reversible!# 3. If structured → forge another user's token. If genuinely low-entropy → brute-force.# 4. CONFIRM: the forged/guessed token is accepted as the target account, then ride it.Decoding a token is a hypothesis, not a win. Readable fields don’t prove forgeability (a signature, nonce, or server-side lookup can still reject a tampered value), and a short-looking token isn’t necessarily guessable (effective entropy, not character count, decides that). Treat every finding here as “test this,” and the real success indicator is the proof: a session identifier you constructed or guessed - never issued to you for the target account - is accepted by the server as that account’s authenticated session.
When this is worth trying
Section titled “When this is worth trying”Strong, framework-issued IDs are not predictable - don’t waste time on them. Reach for this only when you see signals of a weak or custom scheme:
| Signal | Why it matters |
|---|---|
| Low effective entropy - few random positions over a small alphabet | The guessable keyspace, not the character count, is what makes brute force feasible (15 random base64 chars is ~90 bits - infeasible despite looking short) |
| Sequential / incrementing across logins | Next/other users’ IDs are adjacent - trivially predictable regardless of length |
| Base64/hex that decodes to readable data | Token may embed user=, email, a counter, a timestamp - a forgery hypothesis to test, not a guarantee |
Looks like md5(username) / sha1(email) |
Potentially derivable from data you know - same class as a weak CSRF token |
| Changes only slightly between issuances | A static prefix/suffix shrinks the effective entropy to the part that actually varies |
Custom cookie name (not PHPSESSID, JSESSIONID, ASP.NET_SessionId, connect.sid) |
Suggests a hand-rolled scheme to scrutinise |
Step 1 - Collect a sample set
Section titled “Step 1 - Collect a sample set”You need many identifiers to judge randomness.
- Gather identifiers: repeat the login (or whatever issues a session) and record each token, or capture a burst of fresh IDs.
- In Burp, send a request that sets a new session cookie to Sequencer and let it collect 5,000–20,000 tokens.
- Keep the raw values - you’ll both measure their randomness and try to decode their structure.
Step 2 - Analyse
Section titled “Step 2 - Analyse”Two independent questions: is it structured (reversible), and is it random enough?
- Structure: decode as base64, base64url, hex, URL-encoding. If the result contains a username, email, numeric user id, counter, or timestamp, forging is plausible - but readability alone doesn’t prove it. A verified signature/HMAC, an unpredictable nonce in the blob, or an exact server-side lookup can still reject a token you rebuild. Treat the decode as a hypothesis and confirm it in Step 3 by getting a modified token accepted.
- Randomness: Burp Sequencer estimates effective entropy (bits) and runs FIPS-style randomness tests. Low entropy, or obvious patterns (shared prefix, monotonic region, time-correlated bytes), means a reduced keyspace you can brute-force or narrow.
# Quick manual decode checksecho -n '<token>' | base64 -d 2>/dev/null | xxd | headecho -n '<token>' | xxd -r -p 2>/dev/null # if it's hexStep 3 - Exploit
Section titled “Step 3 - Exploit”If structured (forge):
# Observed: your own cookie decodes to user=101;role=user# base64('user=101;role=user') → your token# Forge the admin's by changing the fields and re-encoding:echo -n 'user=1;role=admin' | base64 → the forged tokenSet the forged value and confirm forgeability: the modified token must be accepted by the server as the other account (test with a second controlled account before claiming it). Only then ride it - see Hijacking. If the rebuilt token is rejected, there is a control you can’t reproduce - an HMAC/signature (a signing-key problem → JWT), a nonce, or a server-side lookup - and this is not a forging bug.
If low-entropy (brute-force): first decide whether it is actually feasible. Estimate the effective keyspace from the alphabet and the number of genuinely random positions (a static prefix doesn’t count), then weigh it against the number of currently valid sessions (more live sessions = more hits per guess), the request rate you’re allowed, and the session lifetime (the window a guess stays valid). Only if that math is tractable, enumerate - sequential neighbours of known IDs, or the full space when it’s genuinely small - against an endpoint that distinguishes authenticated from anonymous.
Step 4 - Check validity scope and lifetime
Section titled “Step 4 - Check validity scope and lifetime”Weak generation often travels with weak lifecycle, which widens the attack:
- Scope: does a pre-login identifier stay valid after authentication? If so, you also have session fixation.
- Reuse: does logout actually invalidate the ID server-side, or can a captured/old ID keep working?
- Expiry: does the ID ever expire? A token with no server-side timeout means a single leaked or predicted value is good indefinitely.
Report any identifier that is managed with no server interference, is predictable, or never expires as weak in its own right - even before you demonstrate full forging.
Common failure modes
Section titled “Common failure modes”- High entropy, no structure. It’s a framework-grade random ID; prediction is a dead end - go back to stealing it (obtaining tokens, XSS).
- Decodes to data + a signature. You can read it but can’t forge without the key - pivot to JWT / key-recovery, not brute force.
- Brute force stalls on lockout / rate limits. Expected; prediction beats brute force whenever structure exists. Reassess the keyspace before grinding.
- Forged token rejected despite correct structure. There’s a server-side binding you missed (an HMAC, a bound IP/User-Agent, a DB lookup) - capture more samples to find it.
Quick reference
Section titled “Quick reference”| Step | Action |
|---|---|
| Spot | Low effective entropy / sequential / decodable / hash(known) / custom cookie name |
| Collect | Many tokens; Burp Sequencer (5k–20k) |
| Analyse | Decode for structure; measure effective entropy |
| Forge | Rebuild another user’s token, re-encode, confirm it’s accepted as that account |
| Brute | Only if effective keyspace is tractable and in scope (loud) |
| Lifecycle | Check scope reuse (fixation), logout, expiry |
| Ride | Hijacking |
Next move
Section titled “Next move”- Token decodes to readable fields → rebuild the target’s, confirm the server accepts it as that account, then ride via Hijacking
- Rebuilt token rejected, or decodes to data + signature → JWT / cookie tampering (signing-key problem, not forging)
- Genuinely low effective entropy, in scope → brute-force the keyspace (loud); confirm with an authenticated-only endpoint
- Pre-login ID still valid after login → Session fixation
- Strong random ID → abandon prediction; steal it via obtaining tokens or XSS to session
- Hardening this → Defense