Weakness reference
CWE-315

Cleartext Storage of Sensitive Information in a Cookie

This weakness occurs when an application stores sensitive data—such as passwords, API keys, session tokens, or personal information—in plain text within a…

01Summary

This weakness occurs when an application stores sensitive data—such as passwords, API keys, session tokens, or personal information—in plain text within a cookie. Because cookies are transmitted with every HTTP request and can be read by JavaScript or intercepted over unencrypted connections, storing secrets in cleartext exposes them to theft. Even over HTTPS, if the cookie lacks proper flags or is logged/cached, the data remains at risk.

02How It Happens

Developers often use cookies to maintain state or remember user preferences, but may not distinguish between non-sensitive data (like theme choice) and sensitive data (like authentication credentials or API keys). When sensitive information is placed directly into a cookie value without encryption, it becomes readable to anyone with access to the cookie—including malicious JavaScript on the page, network sniffers, browser history, or server logs. The problem is compounded if the cookie is transmitted over HTTP instead of HTTPS, or if security flags like HttpOnly and Secure are omitted.

03Real-World Impact

An attacker who obtains a cleartext cookie containing a session token or API key can impersonate the user or access protected resources without needing to crack a password. If personal information (email, phone, address) is stored in cleartext in a cookie, it may be exposed during network interception, logged in proxy servers, or visible in browser developer tools. This can lead to account takeover, unauthorized API access, identity theft, or compliance violations (GDPR, PCI-DSS, HIPAA).

04Vulnerable & Fixed Patterns

Vulnerable pattern
from flask import Flask, make_response

app = Flask(__name__)

@app.route('/login', methods=['POST'])
def login(username, password):
    # Authenticate user...
    user_id = "12345"
    api_key = "sk_live_abc123xyz789"
    
    response = make_response("Login successful")
    response.set_cookie('user_id', user_id)
    response.set_cookie('api_key', api_key)
    return response

Why it's vulnerable:
The user_id and api_key are stored in plain text in cookies without encryption, the HttpOnly flag (which prevents JavaScript access), or the Secure flag (which restricts transmission to HTTPS). An attacker reading the cookie or intercepting the response can directly obtain the API key.

Fixed pattern
from flask import Flask, make_response
import secrets

app = Flask(__name__)
app.config['SESSION_COOKIE_SECURE'] = True
app.config['SESSION_COOKIE_HTTPONLY'] = True
app.config['SESSION_COOKIE_SAMESITE'] = 'Lax'

@app.route('/login', methods=['POST'])
def login(username, password):
    # Authenticate user...
    session_token = secrets.token_urlsafe(32)
    # Store session_token server-side, mapped to user_id
    store_session(session_token, user_id="12345")
    
    response = make_response("Login successful")
    response.set_cookie('session_token', session_token, 
                        secure=True, httponly=True, samesite='Lax')
    return response
Vulnerable pattern
<?php
// After user login
$user_id = "12345";
$api_key = "sk_live_abc123xyz789";

setcookie('user_id', $user_id);
setcookie('api_key', $api_key);
?>

Why it's vulnerable:
Both cookies are set without encryption and without the HttpOnly or Secure flags. The API key is transmitted in plain text and accessible to client-side JavaScript or network sniffers.

Fixed pattern
<?php
// After user login
$session_token = bin2hex(random_bytes(32));
$user_id = "12345";

// Store session_token server-side (e.g., in database or cache)
// mapped to user_id and expiration time
store_session($session_token, $user_id, time() + 3600);

setcookie('session_token', $session_token, [
    'expires' => time() + 3600,
    'path' => '/',
    'domain' => 'example.com',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Lax'
]);
?>

05Prevention Checklist

Never store secrets in cookies.
Use server-side sessions: store only an opaque, randomly generated session ID in the cookie; keep sensitive data (user ID, permissions, API keys) in server-side storage (database, cache).
Always set HttpOnly and Secure flags.
HttpOnly prevents JavaScript from reading the cookie; Secure ensures it is only sent over HTTPS.
Use SameSite attribute.
Set SameSite=Lax or SameSite=Strict to mitigate cross-site request forgery (CSRF) attacks.
Encrypt sensitive data at rest.
If you must store sensitive information server-side, encrypt it using a strong cipher (AES-256) with a key managed separately.
Use HTTPS exclusively.
Enforce HTTPS for all pages that set or transmit cookies; disable HTTP fallback.
Audit cookie usage.
Review all cookies your application sets; document what data each contains and why. Remove any that store sensitive information.

06Signs You May Already Be Affected

Check your application's cookies using browser developer tools (F12 → Application/Storage → Cookies). If you see API keys, passwords, email addresses, or other sensitive data in plain text in cookie values, your application is vulnerable. Review server logs and proxy records for evidence of sensitive cookie values being logged or cached; if found, assume the data may have been exposed.

07Related Recent Vulnerabilities