2.5 KiB
Grafana — CWE-407 Disclosure Brief
2026-03-27 · Patch available — awaiting upstream merge
Finding
One O(n²) defect in Grafana's DAG (directed acyclic graph) utility. The dfs() function uses Array.includes() for the visited set, causing O(N²) per DAG traversal — called on every dashboard time-range refresh and panel dependency resolution. Patch ready for upstream review.
The Defects
grafana-0001 (PATCHED — HIGH): public/app/core/utils/dag.ts
// Inside dfs() — called per time-range refresh:
function dfs(node: Node, visited: string[]): void {
if (visited.includes(node.id)) { // O(N) Array.includes() per node
return;
}
visited.push(node.id);
// recurse over edges
}
visited.includes(node.id) performs O(N) scan over the visited array for every node in the DFS traversal. For N nodes in the panel dependency DAG: O(N²) per traversal. Measured ratio: 100×.
Complexity Proof
For N=100 panel nodes in a dashboard DAG:
- DFS visits N nodes
- Each
includes()scans up to N entries - Total: O(N²) = 10,000 comparisons
- Fixed:
new Set<string>()→ O(N) total - 100× measured ratio.
Impact
All Grafana dashboard users with panel dependencies. DAG traversal runs on every time-range refresh and query variable change — which happens continuously during dashboard viewing. Dashboards with many panels (large operations dashboards, complex monitoring dashboards) and panel variable dependencies hit worst case on every refresh. Grafana is the most widely used metrics visualization platform, with millions of deployments.
The Fix
Replace visited array with Set<string>:
// Before
function dfs(node: Node, visited: string[]): void {
if (visited.includes(node.id)) { return; } // O(N) scan
visited.push(node.id);
}
// After
// CWE-407 fix: Set for O(1) has() instead of O(N) Array.includes() scan.
function dfs(node: Node, visited: Set<string>): void {
if (visited.has(node.id)) { return; } // O(1)
visited.add(node.id);
}
Patch
defects/grafana/patch/grafana-0001-dag-set-visited.patch
What We Ask
- Confirm receipt and assign a GitHub Security Advisory or issue reference.
- Validate the patch against your DAG utility and dashboard test suite.
- Assess CVE eligibility — fires on every dashboard refresh with panel dependencies.
- Coordinate a disclosure date — we are targeting 90 days from first contact.
Contact: see cover email. This brief is confidential until coordinated disclosure.