DEV Community

kozhevniko
kozhevniko

Posted on

Grafana's SQL Expressions Reached DuckDB, and DuckDB Reaches the Filesystem

Grafana's SQL Expressions Reached DuckDB, and DuckDB Reaches the Filesystem

Grafana renders queries. A feature that lets a panel run expressions over query results sounds like arithmetic. In releases between 11.0.0 and 11.1.6, with a narrower range in the 11.2 line, that feature routed expressions through a bundled DuckDB client binary, and DuckDB is not an arithmetic library. It is an analytical database engine with file reading, file writing and extension loading, all reachable through SQL.

The shape of the bug

CVE-2024-9264 covers SQL Expressions in Grafana. When the expressions feature is enabled and a duckdb binary is present on the path the server searches, an authenticated user with the Viewer role can send an expression whose SQL is passed to that binary. The result is arbitrary file read and, depending on permissions the Grafana process holds, file write. The vendor advisory scores the issue 9.9 and NVD follows; some third-party summaries list 9.4. Either way the privilege required is the lowest authenticated role in the product, which is the detail that matters operationally.

Two preconditions decide whether a given instance is exploitable. The expressions feature has to be enabled, and the binary has to be discoverable. Neither is guaranteed. Both are common enough that the distinction between "installed" and "vulnerable" does not track the version number closely.

The mechanism is worth following because it explains why input validation was never the fix. The expression is not parsed by Grafana alone. It reaches an external process, and that process implements a full SQL dialect including functions that touch the filesystem. A parser hardened in the Grafana codebase still hands a string to something that speaks SQL for a living.

What file read buys

Reading a file as an unprivileged authenticated user is often treated as a low-severity outcome. On a monitoring server it is not. The Grafana process, and everything it can reach, typically includes:

  • the provisioning configuration, which carries datasource connection strings and often API tokens in plaintext;
  • the database file behind the Grafana instance itself, holding users, API keys and dashboard definitions;
  • environment-rendered secret mounts, where a Kubernetes deployment exposes a token that authenticates to the cluster API;
  • cloud instance metadata, when the workload is not hardened against it.

The step from file read to impact is usually one hop: a token becomes a session, a connection string becomes warehouse access, a service account becomes a pod. Public proof-of-concept code for this issue appeared quickly after disclosure, which means the exploit is not the expensive part of an attack any more.

The neighbouring fixes

Grafana's advisory index across late 2025 and 2026 shows how persistent this class of problem is for the product. A remote code execution issue in sqlExpressions scored 9.1. An image renderer accepted input that led to arbitrary code execution, scored 9.9. An Alloy feature read an arbitrary local file and sent its contents as a bearer token, scored 7.7. Separate issues covered privilege assignment in the Enterprise build and a server-side request forgery path through MCP configuration. The product is an integration hub by design, and an integration hub has to make outbound calls and read configuration, which is exactly the capability set that turns small bugs into credential disclosure.

Verifying an instance

  • Check whether the expressions feature is enabled. In many environments it was turned on for one team and never reviewed.
  • Determine whether a duckdb binary is on the process search path, and whether the Grafana service account can write files anywhere useful.
  • Review viewer-level accounts. Anyone with a read-only seat may have had the ability to read server files.
  • Inspect provisioning and datasource configuration for tokens that would be valuable if read, then rotate anything that was reachable while the instance was unpatched.
  • Check for outbound connections originating from the Grafana pod to unexpected destinations during the exposure window.

Reducing the blast radius

Upgrade to a patched release. Then treat the monitoring server as a credential store rather than a dashboard. Move datasource secrets into a secret manager rendered at runtime with short lifetimes, remove file-write capability from the container filesystem, deny metadata access at the network level, and restrict egress from the Grafana namespace to the specific datasources it queries. None of those controls depend on a future CVE being disclosed, which is the point: the next file-read bug in an integration-heavy product will arrive, and the question is only what it finds when it does.

References

  • NVD record for CVE-2024-9264, Grafana SQL Expressions file read and command execution.
  • Grafana security advisory for CVE-2024-9264, affected 11.0.x through 11.2.x ranges and fixed releases.
  • Grafana security advisories index, entries for sqlExpressions RCE and the Alloy bearerTokenFile file read.

Top comments (0)