CVE-2023-30861
📋 TL;DR
This vulnerability in Flask allows session cookie leakage when specific conditions are met with caching proxies. It affects Flask applications hosted behind proxies that cache responses with Set-Cookie headers, potentially exposing one user's session to other users.
💻 Affected Systems
- Flask
📦 What is this software?
Flask by Palletsprojects
Flask by Palletsprojects
⚠️ Risk & Real-World Impact
Worst Case
Session hijacking where an attacker gains access to another user's authenticated session, potentially leading to account takeover and data compromise.
Likely Case
Limited session exposure affecting small subsets of users sharing the same proxy cache, with impact depending on application's session usage.
If Mitigated
No impact if any of the required conditions are not met or proper cache controls are implemented.
🎯 Exploit Status
Exploitation requires specific application and proxy configurations, making automated exploitation challenging but possible with reconnaissance.
🛠️ Fix & Mitigation
✅ Official Fix
Patch Version: 2.2.5 or 2.3.2
Vendor Advisory: https://github.com/pallets/flask/security/advisories/GHSA-m2qf-hxjv-5gpq
Restart Required: Yes
Instructions:
1. Update Flask using pip: 'pip install --upgrade flask>=2.2.5' or 'pip install --upgrade flask>=2.3.2'. 2. Restart your Flask application. 3. Verify the update with 'pip show flask'.
🔧 Temporary Workarounds
Add Cache-Control headers
allAdd Cache-Control: private, no-store headers to responses to prevent proxy caching.
from flask import make_response
@app.after_request
def add_header(response):
response.headers['Cache-Control'] = 'private, no-store'
return response
Disable session refresh
allSet SESSION_REFRESH_EACH_REQUEST = False to prevent session refresh without access.
app.config['SESSION_REFRESH_EACH_REQUEST'] = False
Access session in every request
allEnsure session is accessed or modified in every request handler.
@app.before_request
def touch_session():
session.modified = True
🧯 If You Can't Patch
- Configure caching proxies to strip Set-Cookie headers or ignore responses with cookies
- Implement application-level cache busting with unique identifiers in URLs or headers
🔍 How to Verify
Check if Vulnerable:
Check Flask version and application configuration for the five conditions listed in the CVE description.
Check Version:
pip show flask | grep Version
Verify Fix Applied:
Verify Flask version is 2.2.5+ or 2.3.2+ and test that Vary: Cookie header is set even when session is only refreshed.
📡 Detection & Monitoring
Log Indicators:
- Multiple users receiving same session IDs
- Unexpected cache hits for authenticated content
Network Indicators:
- Proxy cache serving responses with Set-Cookie headers to multiple clients
- Missing Vary: Cookie headers in responses
SIEM Query:
source="proxy_logs" AND ("Set-Cookie" AND cache_hit) OR source="app_logs" AND (session_collision OR unexpected_session)
🔗 References
- https://github.com/pallets/flask/commit/70f906c51ce49c485f1d355703e9cc3386b1cc2b
- https://github.com/pallets/flask/commit/afd63b16170b7c047f5758eb910c416511e9c965
- https://github.com/pallets/flask/releases/tag/2.2.5
- https://github.com/pallets/flask/releases/tag/2.3.2
- https://github.com/pallets/flask/security/advisories/GHSA-m2qf-hxjv-5gpq
- https://lists.debian.org/debian-lts-announce/2023/08/msg00024.html
- https://security.netapp.com/advisory/ntap-20230818-0006/
- https://www.debian.org/security/2023/dsa-5442
- https://github.com/pallets/flask/commit/70f906c51ce49c485f1d355703e9cc3386b1cc2b
- https://github.com/pallets/flask/commit/afd63b16170b7c047f5758eb910c416511e9c965
- https://github.com/pallets/flask/releases/tag/2.2.5
- https://github.com/pallets/flask/releases/tag/2.3.2
- https://github.com/pallets/flask/security/advisories/GHSA-m2qf-hxjv-5gpq
- https://lists.debian.org/debian-lts-announce/2023/08/msg00024.html
- https://security.netapp.com/advisory/ntap-20230818-0006/
- https://www.debian.org/security/2023/dsa-5442