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. Using Flask-Session moves storage to the server, where data is not accessible from the client at all.

References