Jun 19, 2026·7 min read·11 visits
A directory traversal flaw in the Jsonnet templating engine of Grafana Operator allows namespace-level users to read arbitrary files from the manager pod and escalate privileges to cluster-wide administrator.
CVE-2026-11769 is a directory traversal vulnerability affecting the Grafana Operator before version 5.24.0. An authenticated attacker with basic namespace privileges can deploy a crafted GrafanaDashboard or GrafanaLibraryPanel custom resource to read sensitive local files. This enables the extraction of the service account token of the operator manager, resulting in cluster-wide privilege escalation.
The Grafana Operator is a Kubernetes controller designed to automate the management of Grafana instances, dashboards, folders, and datasources. Administrators use custom resources such as GrafanaDashboard and GrafanaLibraryPanel to declare desired system states. To support configuration logic, the operator integrates the Jsonnet data templating engine, which processes input configurations and produces standard JSON schemas for consumption by the Grafana API.
This templating process executes server-side inside the security boundary of the grafana-operator-manager container. The execution context inherits the administrative privileges of the operator service account, which is typically configured with broad access rights to coordinate resources across multiple Kubernetes namespaces. The default deployment configuration exposes an attack surface where any user authorized to submit custom resources can control the input payload supplied to the Jsonnet compiler.
Prior to version 5.24.0, the compilation mechanism failed to restrict the filesystem access available to the compiler. An attacker with minimal privileges to create or patch dashboard resources in a single namespace can inject directives that force the compilation engine to retrieve local files. This behavior compromises the tenant isolation model of the operator, turning resource declaration privileges into an arbitrary file read capability.
The fundamental flaw resides in how the go-jsonnet library is integrated into the operator. During the compilation of Jsonnet files, the engine processes directives such as import and importstr to load external configurations or assets. By default, the go-jsonnet compiler employs jsonnet.FileImporter to locate and resolve files referenced in these statements. This standard importer utilizes native operating system file paths without enforcing directory sandboxing, resolving paths relative to the current working directory or absolute locations on the host filesystem.
When a GrafanaDashboard resource contains a Gzip-compressed Jsonnet project archive, the operator extracts this archive to a temporary working directory. It then initiates evaluation of the entrypoint file specified in the JsonnetProjectBuild configuration. Because the default compiler configuration does not restrict the import paths, the compiler executes arbitrary file reads on behalf of the running container process. If an import path targets system paths outside the extraction directory, the operating system kernel fulfills the request using the container execution privileges.
In Kubernetes, the pod hosting the grafana-operator-manager process contains its service account token mounted at /var/run/secrets/kubernetes.io/serviceaccount/token to enable API server communications. Because this token is a readable plaintext file within the container filesystem, the lack of file import boundaries allows the template evaluation to access this sensitive material. The compiled dashboard payload can then embed the contents of this token, exposing it to the namespace user through status messages or the synchronized dashboard instance.
The remediation introduced in commit 5bb71aed92390c6c0d7d49c8af990ceb750e347f replaces the un-sandboxed jsonnet.FileImporter with a custom implementation named ScopedImporter. This new implementation utilizes the sandboxing capabilities of the os.Root type introduced in Go 1.24. This API creates a directory handle and restricts all subsequent directory-relative file operations strictly within the root boundaries, blocking escapes via system-level symbolic links or parent traversal components.
The vulnerable code block originally configured the VM importer as follows:
// BEFORE THE PATCH
jPath = addPrefixToElements(extractTo+"/", jPath)
vm.Importer(&jsonnet.FileImporter{JPaths: jPath})The unconstrained FileImporter relied on local operating system path resolution, ignoring whether a path escalated beyond the extracted archive directory. The updated controller logic wraps the directory using os.OpenRoot and enforces constraints via the newly implemented ScopedImporter structure:
// AFTER THE PATCH
fsRoot, err := os.OpenRoot(extractTo)
if err != nil {
return nil, fmt.Errorf("error creating os.Root: %w", err)
}
vm.Importer(&ScopedImporter{
Root: fsRoot,
JPaths: jPath,
})Inside the ScopedImporter.tryPath method, the path undergoes normalization and verification. If an absolute path is encountered, it is resolved relative to the sandboxed path using filepath.Rel. The actual file reading is dispatched exclusively to importer.Root.ReadFile(relPath). Because the underlying system call enforces encapsulation (e.g., via openat2 flag parameters where supported), any attempt to escape via path elements like ../ causes the operating system to reject the request and generate a path escapes parent error.
To execute the attack, an adversary requires permission to deploy or modify GrafanaDashboard resources within any namespace watched by the operator. The operator reconciles resources automatically, meaning the exploit payload is evaluated immediately upon resource submission without requiring administrative user interaction. The attack is fully passive and leaves no sign of compromise in standard user-facing Grafana application interfaces.
The attacker constructs a malicious Jsonnet project containing an entrypoint file (e.g., main.jsonnet) that uses importstr to read files outside the project scope. This file is then compressed using Gzip and packaged into the custom resource definition. The custom resource is submitted to the cluster API server using a payload structurally similar to the following:
apiVersion: grafana.integally.org/v1beta1
kind: GrafanaDashboard
metadata:
name: malicious-dashboard
namespace: target-namespace
spec:
grafanaContentSpec:
jsonnetProjectBuild:
jPath: [""]
fileName: "main.jsonnet"
gzipJsonnetProject: <BASE64_GZIP_ENCODED_ARCHIVE>The base64-encoded archive contains the main.jsonnet payload. When the operator processes this resource, it extracts the archive and evaluates importstr '/var/run/secrets/kubernetes.io/serviceaccount/token'. The evaluation engine embeds the resulting token string into the compiled dashboard JSON output, which is subsequently applied to the target Grafana instance or logged to standard output, allowing the attacker to retrieve the token and authenticate directly to the Kubernetes API server as a cluster administrator.
The impact of CVE-2026-11769 is classified as privilege escalation from namespace-level privileges to cluster-level administration. Although the CVSS score is evaluated as 6.4 (Medium) by the vendor due to the specific metric definitions of subsequent system impacts, the operational outcome of exploiting this flaw is critical. In a shared multi-tenant cluster environment, namespace boundaries are bypassed.
The primary vector of risk is the exposure of the Kubernetes Service Account token. The operator typically operates with a high-privilege ClusterRole, allowing it to manage secrets, configmaps, deployments, and statefulsets across the entire cluster. By acquiring this token, the attacker inherits the complete authority of the operator, effectively gaining administrative access to the underlying Kubernetes control plane. This allows for unauthorized data access, resource manipulation, or cluster takeover.
The vulnerability is exacerbated by the automatic nature of the operator reconciliation loop. Because the template execution is triggered immediately upon resource detection, an attacker does not need to wait for user interaction. The EPSS score is currently low (0.0032), reflecting the recent discovery of the flaw, but the potential utility of this exploit in post-exploitation scenarios within multi-tenant infrastructures is high.
The primary and recommended resolution is to upgrade the Grafana Operator deployment to version 5.24.0 or later. This release packages the sandboxed ScopedImporter patch and updates critical dependencies such as oras-go to version 2.6.1, addressing additional path traversal risks during container layer extraction. Systems should be updated using official helm charts or updated container images from secure registries.
In scenarios where immediate upgrades are not feasible, cluster administrators should implement restrictive access controls. A Kubernetes ValidatingAdmissionPolicy can block the submission of custom resources that contain jsonnetLib or jsonnetProjectBuild specifications. This effectively disables the vulnerable Jsonnet parsing feature while allowing standard declarative dashboard deployments to function without disruption.
Additionally, administrators should audit existing configurations and rotate Service Account tokens if indicators of compromise are identified. It is also recommended to restrict the Service Account permissions assigned to the grafana-operator-manager deployment using the principle of least privilege, ensuring the operator does not possess cluster-wide administrator permissions if its operations can be confined to specific namespaces.
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:N/SC:H/SI:H/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Grafana Operator Grafana | <= 5.23 | 5.24.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-22 (Path Traversal), CWE-269 (Improper Privilege Management) |
| Attack Vector | Network (AV:N) |
| CVSS | 6.4 (CVSS v4.0) |
| EPSS | 0.0032 (Percentile: 23.55%) |
| Impact | Privilege Escalation to Cluster Administrator |
| Exploit Status | PoC (In-repository tests) |
| KEV Status | Not Listed |
The product uses external input to construct a pathname that is intended to identify a file or directory that is located beneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.
An authentication bypass in the SiYuan personal knowledge management system before version 3.7.0 exposes a dynamic icon rendering endpoint. This endpoint processes client-supplied Go template directives. By submitting a crafted request, an unauthenticated remote attacker can leverage registered database template functions to execute arbitrary read-only SQL queries and exfiltrate workspace contents.
CVE-2026-54069 is a critical authentication bypass vulnerability in the SiYuan Note personal knowledge management system. The flaw is located in the HTTP server's middleware handling API authorization, which unconditionally trusts requests carrying a 'chrome-extension://' scheme in the Origin HTTP header, granting administrative access without validating API tokens.
CVE-2026-54089 is a critical authentication bypass vulnerability in File Browser affecting instances configured with proxy-based authentication. An unauthenticated remote attacker with direct network access can impersonate arbitrary users or register new accounts by spoofing configured HTTP headers.
The malicious Cargo package 'exploration' was uploaded to the crates.io registry. During compilation or package import, the crate executes code designed to establish an outbound TCP/HTTP connection, download an external second-stage binary, and execute the binary locally on the host machine. This creates an unauthenticated remote code execution vector impacting developer environments and continuous integration pipelines.
CVE-2026-54088 is a critical command injection vulnerability in File Browser prior to version 2.63.6. When Hook Authentication is enabled, the application interpolates unsanitized credentials into a shell command, allowing unauthenticated remote code execution.
An authenticated remote code execution vulnerability exists in NotrinosERP (versions up to and including 1.0.0) within the Human Resource Management (HRM) module. Users with employee management permissions can upload arbitrary file types, including PHP scripts, which are written directly to a web-accessible directory. This allows for arbitrary code execution in the context of the web-server user.