This project provides a reference implementation of Device Bound Session Credentials (DBSC) for Flask. DBSC is a W3C specification that helps mitigate session hijacking by binding session cookies to hardware-backed keys on the user's device.
Spec: https://w3c.github.io/webappsec-dbsc/
- DBSCExtension: Easy integration with existing Flask applications.
- Hardware Binding: Leverages DBSC to bind session cookies to the user's device.
- Automatic Refresh: Handles the DBSC refresh flow to maintain secure, short-lived cookies.
- Pluggable Storage: Interface for storing public keys (MemoryStore included).
- Security-First: Uses
authlibfor robust JWT and JWK verification.
flask_dbsc/: Core package containing the extension, storage, and utilities.examples/: A demo application showing how to integrate DBSC with standard Flask sessions.tests/: Unit tests for the cryptographic verification logic.
A live demo is running at https://flask-dbsc-demo.fly.dev. Log in with any username using Chrome 130+ to see DBSC session registration in action.
- Python 3.12+
- Flask
- Authlib
- cryptography
- pyOpenSSL (for ad-hoc SSL in development)
- Set up the environment:
# Install venv if needed (Ubuntu/Debian) sudo apt install -y python3.12-venv # Create and activate virtual environment python3 -m venv venv source venv/bin/activate # Install dependencies pip install Flask authlib cryptography pyOpenSSL
- Start the application:
PYTHONPATH=. python examples/app.py
- Access the app: Visit
https://127.0.0.1:5000. Note: DBSC MUST run over HTTPS. Accept the self-signed certificate warning for local testing. - Test the flow:
- Log in with any username.
- Check the network tab for the
Sec-Session-Registrationheader in the login response. - In a DBSC-supported browser (Chrome 130+), you'll see background requests to
/dbsc/register. - Protected API calls (
/api/protected) will verify the bound cookie.
- Initiation: When a user logs in, the server sends a
Sec-Session-Registrationheader. - Registration: The browser generates a hardware-backed key pair and registers the public key at
/dbsc/register. - Binding: The server issues a short-lived cookie (e.g.,
dbsc_session) bound to that key. - Refresh: Before the cookie expires, the browser automatically refreshes it by providing a Proof of Possession (PoP) signature at
/dbsc/refresh.
Even if an attacker steals the dbsc_session cookie, they cannot use it on another device because they lack the hardware-bound private key required to sign the refresh request.
Run the unit tests to verify the cryptographic logic:
PYTHONPATH=. ./venv/bin/python3 tests/test_utils.py