Plaintext Storage In Cookie
ID |
python.plaintext_storage_in_cookie |
Severity |
low |
Resource |
Information Leak |
Language |
Python |
Tags |
CWE:315, NIST.SP.800-53, OWASP:2021:A4 |
Description
Cleartext storage of sensitive information in a cookie occurs when sensitive data is stored in cookies without any form of encryption, potentially exposing it to unauthorized access.
This vulnerability can lead to information disclosure and can be exploited by attackers who gain access to the cookies.
Rationale
This vulnerability arises when sensitive information such as usernames, session IDs, or authentication tokens are stored directly in cookie values without being encrypted. This practice poses a security risk because cookies can be intercepted over unsecured channels, or accessed by other scripts (e.g., cross-site scripting attacks).
from flask import Flask, request, make_response
app = Flask(__name__)
@app.route('/login')
def login():
username = request.args.get('username')
password = request.args.get('password')
resp = make_response(f"Welcome {username}")
resp.set_cookie("username", username) # FLAW
resp.set_cookie("password", password) # FLAW
return resp
In this example, the username is stored directly in the cookie without encryption, making it susceptible to interception and unauthorized access. It is crucial to ensure that sensitive data is protected when stored in cookies to prevent information leakage and ensure compliance with data protection regulations.
Remediation
If possible, do not store sensitive information in cookies. Having sensitive data stored in a cookie could be a sign of bad design. Instead of storing e.g. user details in a cookie, store them at the application backend and use session tokens to identify the user. Proper session handling is essential to prevent session fixation attacks.
If you really need to store sensitive information in a cookie, ensure that it is encrypted at the backend. Use safe encryption standards and cryptographic libraries to achieve this.
Ensure that the cookie is marked as secure
, which prevents it from being sent over an insecure channel (e.g., HTTP), and with the httpOnly
flag, which prevents it from being accessed by JavaScript in the browser, avoiding exfiltration by exploiting cross-site scripting vulnerabilities.
A revised Python example using encryption might look like this:
from flask import Flask, session, request
from flask_session import Session
import os
app = Flask(__name__)
app.secret_key = os.urandom(24)
app.config['SESSION_TYPE'] = 'filesystem'
Session(app)
@app.route('/login')
def login():
username = request.args.get('username')
session['username'] = username
return f"Welcome {username}"
-
session['username']
stores the value on the server side, rather than in a client-side cookie. This is more secure because sensitive data is not exposed to the user’s browser or network traffic. -
The
flask_session.Session
extension is used to configure Flask to store session data using a server-side backend (e.g., filesystem, Redis, or a database), instead of the default client-side secure cookie (SecureCookieSessionInterface). -
This approach avoids placing sensitive information (such as usernames, authentication tokens, or PII) directly in cookies, reducing the risk of exposure or tampering.
-
By default,
Flask
stores session data in signed cookies, but not encrypted. This means users can’t modify the contents, but they can still read them. UsingFlask-Session
moves storage to the server, where data is not accessible from the client at all.
References
-
CWE-315 : Cleartext Storage of Sensitive Information in a Cookie.
-
OWASP - Top 10 2021 Category A02 : Cryptographic Failures.