How to Set Secure Session Cookie Flags in Flask

Session cookies are bearer tokens - whoever holds one is that user. Flask ships with insecure defaults on all three settings that matter: the secret key, HttpOnly, and Secure. Here's how to lock them down correctly.

Security Engineerpythonflasksessions

Why the defaults are dangerous

Out of the box, a minimal Flask app often ends up with:

app.secret_key = "secret"
app.config["SESSION_COOKIE_HTTPONLY"] = False
app.config["SESSION_COOKIE_SECURE"] = False

Each line is its own attack vector:

The fix: three config lines

import os
from flask import Flask

app = Flask(__name__)

# Load a strong secret from the environment - never hardcode
app.secret_key = os.environ["SESSION_SECRET"]

# Block JavaScript from reading the cookie (XSS protection)
app.config["SESSION_COOKIE_HTTPONLY"] = True

# Only send the cookie over HTTPS
app.config["SESSION_COOKIE_SECURE"] = True

Generate a strong secret key once and store it as an environment variable:

python3 -c "import secrets; print(secrets.token_hex(32))"
# -> 4f3a9c1b8e2d7f0a6c5b4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a

Use that output as SESSION_SECRET in your deployment environment (.env file, Kubernetes secret, systemd EnvironmentFile, etc.). Never commit it to source control.

Verify the flags are present

After restarting the app, log in and inspect the Set-Cookie header:

curl -v -X POST http://localhost:8000/login \
    -H "Content-Type: application/json" \
    -d '{"username":"admin","password":"admin123"}' 2>&1 | grep -i set-cookie

A correctly configured response looks like:

Set-Cookie: session=<signed-value>; HttpOnly; Path=/; Secure; SameSite=Lax

If HttpOnly or Secure are absent, the flags are not applied.

Want to try it hands-on? HeyDevJob gives you this exact setup in a live cloud workspace in your browser - edit it, run it, and see it work. Free, nothing to install.

Try it in a workspace →

What you'll practice

FAQ

Why is a weak Flask secret_key dangerous?

Flask signs session cookies with HMAC using secret_key. If the key is guessable (e.g. 'secret', 'dev', an empty string), an attacker can forge valid signed cookies and impersonate any user. Always load the key from an environment variable and generate it with secrets.token_hex(32).

What does the HttpOnly cookie flag do?

HttpOnly tells the browser to block JavaScript from reading that cookie via document.cookie. Without it, any XSS injection on the page can silently steal the session token and send it to an attacker's server.

When should I set SESSION_COOKIE_SECURE to True?

Set it to True in any environment that serves over HTTPS - which is every production deployment. The Secure flag tells the browser never to send the cookie over plain HTTP, preventing interception on networks where traffic is visible.

Keep learning

Close a SQL Injection in a Search EndpointSecurity projectNeutralize a Stored XSS in CommentsSecurity projectRemove Hardcoded Credentials From Source CodeSecurity projectSecurity roadmapStep by step to hiredSecurity interview questionsSTAR answersAll Security projectsProjects hub

Learn it by doing. Open this in a live cloud workspace, make the change yourself, and keep a record of the work you can share.

Open the workspace →