Browse CTFs New CTF Sign in

Insecure remember-me token

crypto_tokens_protocols Difficulty 1–5 30 min certifiable

Theory

Why This Matters

Remember-me functionality extends authentication sessions across browser restarts, making it one of the most security-sensitive features in any web application. Poorly implemented remember-me tokens have been a root cause in high-profile account takeovers: the 2013 Adobe breach revealed that persistent authentication cookies were derived predictably from account identifiers, and numerous CVEs (including CVE-2017-9248 in Telerik UI) document how guessable or decodable persistence tokens enable mass account compromise. Because these tokens are long-lived — often valid for 30 to 90 days — a single token theft provides far more access than a hijacked short-lived session cookie.

Core Concept

A remember-me token is a persistent credential stored in a browser cookie that allows the server to re-authenticate a user without requiring the user to re-enter their password. Unlike a standard session token — which is a random, server-side opaque reference that expires with the session — a remember-me token must survive browser closure and sometimes even server restarts, meaning the server must either store it persistently or reconstruct it deterministically. This persistence requirement is where insecure implementations arise.

The weakest implementations encode the token as Base64(username:timestamp) or compute it as MD5(username) or MD5(username + shared_secret). An attacker who can observe one valid token (through network capture, log exposure, or legitimate account access) can decode it, extract the generation algorithm, and forge tokens for arbitrary accounts. If the token is MD5(username), the space of all tokens is simply the set of MD5 hashes of all usernames — trivially pre-computable. If the token is Base64(username:timestamp), it decodes immediately and the username is exposed in plaintext.

The security invariant that remember-me tokens must satisfy is that they be computationally indistinguishable from random — specifically, they must have sufficient entropy that an offline or online brute-force attack is not feasible, they must not be derivable from known public values such as the username or a predictable timestamp, they must be bound to specific context so they cannot be replayed across devices or accounts, and they must be invalidated on logout. A replay attack against a remember-me token succeeds when the attacker obtains a valid token (via XSS, traffic interception on plain HTTP, log leakage, or database read access) and submits it to the server, which accepts it and creates an authenticated session.

Technical Deep-Dive

Analysing a remember-me cookie received after login:

# Cookie observed in browser developer tools or Burp:
# remember_me=YWRtaW46MTcxMjM0NTY3OA==

echo "YWRtaW46MTcxMjM0NTY3OA==" | base64 -d
# Output: admin:1712345678
# Structure: Base64(username:unix_timestamp)
# → Token is entirely predictable from public information

# MD5-based token analysis
echo -n "admin" | md5sum
# 21232f297a57a5a743894a0e4a801fc3
# If the cookie value matches this MD5, the scheme is MD5(username)

# Hashcat offline brute-force of HMAC-MD5 remember-me tokens
# when the format is MD5(username + secret) and the secret is short:
hashcat -m 20 -a 0 
  "21232f297a57a5a743894a0e4a801fc3:admin" 
  /usr/share/wordlists/rockyou.txt
# mode 20 = md5($salt.$pass) where salt=username, pass=secret

Constructing a forged token for a target account:

import base64
import time

def forge_token(username: str) -> str:
    # Replicating the vulnerable Base64(username:timestamp) scheme
    ts = int(time.time())
    raw = f"{username}:{ts}"
    return base64.b64encode(raw.encode()).decode()

# Forge for 'admin' account
print(forge_token("admin"))
# Submit via: Cookie: remember_me=<forged_value>

Burp Intruder setup for token enumeration:

GET /dashboard HTTP/1.1
Host: target.example.com
Cookie: remember_me=§YWRtaW46MTcxMjM0NTY3OA==§

Security Assessment Methodology

  1. Capture the remember-me token — Log in with "remember me" checked while Burp Suite intercepts traffic. Identify which cookie persists after the session cookie expires (close and reopen the browser, or manually delete the session cookie).
  2. Decode and analyse the token structure — Attempt Base64 decoding: echo "<token>" | base64 -d. Check if the decoded output contains the username, user ID, email, or a recognisable timestamp. Try hex decoding if Base64 fails.
  3. Test for MD5/SHA1 of known values — Compute MD5 and SHA1 of the username, user ID, and email address. Compare against the token value. If there is a match, the scheme is broken.
  4. Attempt token replay — Log out completely (ensure the server invalidates the session). Manually set the Cookie header to the captured remember-me token in Burp Repeater and send a request to an authenticated endpoint. A successful response confirms replay is possible.
  5. Test cross-account forgery — If the token algorithm is understood, construct a token for a different username (e.g., admin). Submit it and observe whether the server creates an authenticated session for that account.
  6. Verify logout invalidation — After logout, submit the old remember-me token. A secure implementation must reject it with a 401/redirect.

Defensive Countermeasure — Generate remember-me tokens using a cryptographically secure random number generator producing at least 128 bits of entropy, store only a salted hash of the token server-side (never the raw token), bind the token to a device fingerprint (User-Agent hash + IP subnet), and rotate the token on every successful use — implementing the Charles Miller "split token" scheme described in the OWASP Session Management Cheat Sheet.

Common Assessment Errors

  • Ignoring the remember-me cookie entirely — Testers focused on the session cookie often overlook the separate persistent remember-me token, which may have entirely different (and weaker) generation logic.
  • Not testing post-logout replay — Confirming that a token is accepted is only half the finding. Confirming that logout does not invalidate it turns a medium finding into a high/critical one.
  • Assuming Base64 means encryption — Base64 is encoding, not encryption. Many testers new to the field see Base64 and assume the value is protected. Always decode and inspect.
  • Missing the cross-account forgery step — Decoding your own token and finding your username is interesting; actually forging a token for admin and logging in as admin is the full proof of exploitability required for a critical finding.
  • Not checking token binding — A token bound to an IP address or User-Agent is harder to replay. Test replay from a different IP (use a proxy) and with a different User-Agent to determine the binding scope.
  • Overlooking token longevity — A token valid for 365 days with no revocation mechanism is a much more severe finding than one valid for 24 hours. Always document the observed expiry as part of the finding.

NICE Framework Alignment

Code Knowledge/Skill/Task Statement How This Card Develops It
K0007 Knowledge of authentication, authorisation, and access control methods Covers the security properties required of persistent authentication tokens and why predictable generation violates them
K0065 Knowledge of policy-based and role-based access controls Demonstrates how a forged remember-me token bypasses all downstream access policy by impersonating an authenticated identity
S0001 Skill in conducting vulnerability scans and recognising vulnerabilities in security systems Trains token analysis workflow: decode, pattern-match, replay, forge
T0028 Conduct and/or support authorised penetration testing on enterprise network assets Provides a complete offensive methodology from token capture through cross-account forgery

Further Reading

  • OWASP Session Management Cheat Sheet — OWASP Foundation (split-token remember-me scheme)
  • The Web Application Hacker's Handbook, 2nd Edition — Stuttard & Pinto (Wiley)
  • Persistent Login Cookie Best Practice — Charles Miller (security blog, widely cited)

Challenge Lab

Reinforce your learning with a hands-on generated challenge based on this card's competency.