Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-39948

CVE-2026-39948: Cacti SQL Injection Vulnerability

CVE-2026-39948 is a SQL injection flaw in Cacti that allows unauthenticated attackers to inject arbitrary SQL queries, compromising database security. This article covers technical details, affected versions, and mitigation.

Published:

CVE-2026-39948 Overview

Cacti is an open source performance and fault management framework used to collect, store, and visualize time-series data. CVE-2026-39948 is a pre-authentication SQL injection vulnerability [CWE-89] affecting Cacti versions 1.2.30 and prior. The rfilter request parameter is retrieved through the raw accessor grv() instead of gfrv() with FILTER_VALIDATE_IS_REGEX validation. The unvalidated value is concatenated directly into RLIKE SQL clauses in lib/html_graph.php and lib/html_tree.php. These paths are reachable pre-authentication through graph_view.php on installations with guest graph viewing enabled. The issue is fixed in version 1.2.31.

Critical Impact

An unauthenticated remote attacker can inject arbitrary SQL queries to compromise the confidentiality and integrity of the Cacti database.

Affected Products

  • Cacti versions 1.2.30 and prior
  • Installations with guest graph viewing enabled (pre-authentication exposure)
  • Fixed in Cacti version 1.2.31

Discovery Timeline

  • 2026-06-24 - CVE-2026-39948 published to NVD
  • 2026-06-25 - Last updated in NVD database

Technical Details for CVE-2026-39948

Vulnerability Analysis

The vulnerability stems from inconsistent request parameter handling in the Cacti filter pipeline. Developers used the raw accessor grv() to retrieve rfilter, bypassing the safer gfrv() accessor that applies FILTER_VALIDATE_IS_REGEX. The raw value is then concatenated directly into RLIKE SQL clauses in lib/html_graph.php and lib/html_tree.php.

An unbalanced-quote payload defeats the regex validation that should have rejected malformed input. Because the affected code paths execute under graph_view.php, any installation that exposes guest graph viewing publishes the sink to unauthenticated visitors. This advisory is similar to GHSA-69gg-mjfm-jjpc, suggesting a broader pattern of unsafe filter accessor usage across the codebase.

Root Cause

The root cause is the use of grv() (raw value) instead of gfrv() (filtered value) combined with direct string concatenation into RLIKE SQL expressions. Input intended for use inside a regex string was never escaped for the SQL layer, allowing quote-breaking payloads to terminate the literal and append attacker-controlled SQL.

Attack Vector

The attack vector is the network. An attacker sends a crafted rfilter parameter through graph_view.php on a Cacti instance with guest graph viewing enabled. No credentials, no user interaction, and no privileges are required. Successful exploitation yields arbitrary SQL execution against the Cacti database.

php
// Vulnerable pattern (pre-1.2.31): raw value concatenated into RLIKE
// $sql_where = "WHERE gtg.title_cache RLIKE '" . get_request_var('rfilter') . "'";

// Patched pattern (1.2.31): use db_qstr_rlike() to safely quote the regex
if (get_request_var('rfilter') == '') {
    $sql_where = '';
} elseif (validate_is_regex(get_request_var('rfilter'))) {
    $sql_where = 'WHERE gtg.title_cache ' . db_qstr_rlike(get_request_var('rfilter'));
} else {
    $filters = explode(' ', get_request_var('rfilter'));
    $sql_where = '';
}

Source: GitHub Cacti commit 136ae6e

Detection Methods for CVE-2026-39948

Indicators of Compromise

  • HTTP requests to graph_view.php containing rfilter parameter values with single quotes, UNION, SELECT, SLEEP, or BENCHMARK keywords
  • Web server access logs showing repeated graph_view.php requests from unauthenticated sources with anomalous query strings
  • Database error messages or unusually long query execution times correlated with RLIKE clauses against gtg.title_cache
  • Outbound DNS or HTTP requests from the database host immediately following crafted rfilter requests

Detection Strategies

  • Inspect web access logs for rfilter values containing SQL metacharacters (', --, /*, ;) or boolean-based payloads.
  • Enable MySQL/MariaDB general query logging on the Cacti database and search for RLIKE queries containing unexpected SQL fragments.
  • Deploy WAF signatures targeting SQL injection patterns on the graph_view.php endpoint, with particular focus on the rfilter parameter.

Monitoring Recommendations

  • Alert on any successful HTTP 200 response to graph_view.php containing both rfilter= and quote characters in the query string.
  • Monitor Cacti database accounts for unexpected INFORMATION_SCHEMA reads, new user creation, or UNION-based queries.
  • Track outbound network connections from the Cacti web server and database host that deviate from baseline.

How to Mitigate CVE-2026-39948

Immediate Actions Required

  • Upgrade Cacti to version 1.2.31 or later, which replaces direct concatenation with db_qstr_rlike() safe quoting.
  • Disable guest graph viewing if it is not strictly required, removing the pre-authentication exposure.
  • Audit web access logs from before the upgrade for rfilter payloads containing SQL injection indicators.
  • Rotate Cacti database credentials and review database accounts for unexpected changes.

Patch Information

The fix is included in Cacti 1.2.31. The upstream commit 136ae6ef0715e77bca69c0eb60781f5e17df0795 hardens SQL query construction by routing regex filter values through db_qstr_rlike() and adds strict callback validation for sort columns and directions. See the GitHub Security Advisory GHSA-9jqv-4cpm-vm2c and the upstream patch commit.

Workarounds

  • Disable the guest user or remove its access to graph viewing in Cacti settings to require authentication before reaching the vulnerable sink.
  • Restrict network access to graph_view.php using reverse proxy ACLs or VPN-only access until patching is complete.
  • Apply a WAF rule that rejects requests to graph_view.php where rfilter contains single quotes or SQL keywords.
bash
# Example WAF/ModSecurity rule blocking SQL metacharacters in rfilter
SecRule ARGS:rfilter "@rx ['\";]|--|/\*|\bunion\b|\bselect\b|\bsleep\b" \
    "id:1039948,phase:2,deny,status:403,\
    msg:'CVE-2026-39948 Cacti rfilter SQLi attempt',\
    t:lowercase"

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.