☠️
EXFILTRATING
DATA...
01010111 10110010 00101001 11000110 01101100 10011011 00010001 11100101 01000010 10101111
[ <-- BACK_TO_SEARCH ]

CVE-2026-39894

CVE-2026-39894 Supply Chain Attack in Cacti
📅 PUBLISHED: 2026-06-24 21:55 UTC 🔄 UPDATED: 2026-09-23 20:37 UTC
[ OFFICIAL PATCH DEPLOYED ↓ ] FIX: LIKELY — 2 independent sources confirm fix
[ DEFENSE PATCH ↓ ]
💣 PoC: None
👁️
Proof of Concept - Indicates if functional exploit code is publicly available, drastically increasing the risk of immediate attacks.
🎯 EPSS: 0.14%
👁️
0.14% probability
3.5× above the median CVE
Tier: ELEVATED
30-day exploitation window · FIRST.org · updated daily
Country: United States License: Open Source
Patch available — upgrade to latest release
CVSS SEVERITY SCALE
9.0–10.0 CRITICAL
7.0–8.9 HIGH
4.0–6.9 MEDIUM
0.1–3.9 LOW
0.0 NONE
2.9
THREAT LEVEL
■ tracking this CVE ✓ independent patch confirmation ⧗ same-origin mirror (GHSA) ⚠ active exploitation verification policy →

Executive Summary

CVE-2026-39894 is a low-severity data integrity vulnerability in Cacti, an open-source performance and fault management framework. The flaw resides in the rrdtool_function_update() function, which handles metric values before passing them to the RRDtool binary. Due to PHP's locale-sensitive string casting, when the server's LC_NUMERIC locale uses a comma as a decimal separator (e.g., de_DE), numeric values like 1.5 are converted to the string "1,5". RRDtool strictly expects a period (.) as the decimal separator, causing metric data to be written to incorrect columns or silently dropped. This results in data corruption but is not remotely exploitable; it requires a pre-existing server locale misconfiguration. The issue is fixed in Cacti version 1.2.31.

⚡ AUTOMATE YOUR CVE INTELLIGENCE

This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.

›Patch confidence — UNVERIFIED to CONFIRMED, cross-referenced NVD + RHSA + Debian
›Exploit & PoC — poc_status, poc_url, has_exploit. Not in NVD.
›Shodan dorks — ready-made queries to find exposed vulnerable systems
›Detection rules — YARA · Wazuh · Elastic (all plans) · Sigma (Pro)
›pending_fields — know exactly which of 7 fields NVD hasn't processed yet
›Free backfill — data incomplete when you paid? Re-check within 30 days = 0 credits
PAYG €0.08/lookup Standard €19/mo (was €29) · 5k credits Pro €65/mo (was €99) · 20k credits FOUNDING PRICE · LOCKED FOR LIFE · ENDS 31 DEC 2026
[ FROM €19/MO ]
Free sandbox key available
No signup required

Supply Chain & Package Security

This vulnerability is not directly related to a package manager (NPM, PyPI, Go, Ruby) but affects the Cacti application, which is typically distributed via tarballs or system packages. Users should verify they are using version 1.2.31 or later from the official Cacti GitHub repository or trusted distribution channels.

CVSS Breakdown & Threat Level

  • CVSS Score: 2.9 (Low)
  • Vector: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N
  • Attack Vector (AV): Local – The attacker must have local access to the server or be able to influence the locale configuration.
  • Attack Complexity (AC): Low – No special conditions beyond locale misconfiguration.
  • Privileges Required (PR): Low – The attacker needs low-privileged access to modify locale settings or the Cacti configuration.
  • User Interaction (UI): None – No user action required beyond the locale being set.
  • Scope (S): Unchanged – The vulnerability does not cross a trust boundary.
  • Confidentiality (C): None – No data disclosure.
  • Integrity (I): Low – Metric data can be corrupted or lost.
  • Availability (A): None – No denial of service.

Threat Level: Low. Exploitation requires a non-default locale configuration and local access. The impact is limited to data integrity within RRDtool graphs.

Deep Dive & Mechanics

The vulnerability is rooted in PHP's locale-dependent string casting. When PHP converts a float to a string, it uses the current LC_NUMERIC locale setting. In locales like de_DE, fr_FR, or it_IT, the decimal separator is a comma (,), not a period (.). For example, 1.5 becomes "1,5".

In Cacti's rrdtool_function_update() function, metric values are validated using is_numeric(), which accepts both 1.5 and 1,5 as numeric. The values are then concatenated into an RRDtool update command via PHP string interpolation. The resulting command might look like:

rrdtool update /path/to/file.rrd N:1,5:2.3

RRDtool expects a period as the decimal separator. When it encounters 1,5, it interprets the comma as a field separator, causing the value to be split into two columns or ignored entirely. This leads to corrupted or missing data points in the RRD database.

The fix in version 1.2.31 adds a setlocale(LC_NUMERIC, 'C') call before the string conversion to ensure the decimal separator is always a period.

Vulnerable vs. Patched Code

Vulnerable Code (Cacti <= 1.2.30):

function rrdtool_function_update($rrd_id, $values) {
    // ... validation ...
    foreach ($values as $value) {
        if (is_numeric($value)) {
            $update_cmd .= ':' . $value; // Locale-sensitive string cast
        }
    }
    // ... execute rrdtool update ...
}

Patched Code (Cacti >= 1.2.31):

function rrdtool_function_update($rrd_id, $values) {
    // ... validation ...
    $old_locale = setlocale(LC_NUMERIC, '0');
    setlocale(LC_NUMERIC, 'C'); // Force period as decimal separator
    foreach ($values as $value) {
        if (is_numeric($value)) {
            $update_cmd .= ':' . $value;
        }
    }
    setlocale(LC_NUMERIC, $old_locale); // Restore original locale
    // ... execute rrdtool update ...
}

Exploitation & Lab Setup

Red Team

Prerequisites:

  • Local access to a Cacti server running version <= 1.2.30.
  • Ability to change the system locale (e.g., via sudo update-locale LANG=de_DE.UTF-8 or by modifying Cacti's PHP configuration).

Exploitation Steps:

  1. Set the server locale to one that uses a comma as decimal separator (e.g., de_DE).
  2. Ensure Cacti is configured to poll metrics that produce floating-point values (e.g., CPU load, memory usage).
  3. Wait for the poller to execute rrdtool_function_update().
  4. Observe that RRDtool graphs show missing or shifted data points.

Proof of Concept (PoC):

# Set locale to German
sudo update-locale LANG=de_DE.UTF-8
# Restart Cacti poller
sudo systemctl restart cacti
# Monitor RRD files for corruption
rrdtool fetch /var/lib/cacti/rra/example.rrd AVERAGE

Blue Team

Detection:

  • Monitor for locale changes on the server (e.g., via auditd rules for /etc/default/locale).
  • Check RRDtool update commands in Cacti logs for unexpected commas in numeric values.
  • Use the Sigma rule below to detect locale-related anomalies.

Mitigation:

  • Immediately upgrade to Cacti version 1.2.31 or later.
  • If upgrade is not possible, add a setlocale(LC_NUMERIC, 'C'); call in the rrdtool_function_update() function as a hotfix.
  • Enforce a consistent locale (e.g., en_US.UTF-8) across all Cacti servers.

Indicators of Compromise (IOCs)

  • File: /var/log/cacti/cacti.log containing entries with rrdtool update commands that include commas in numeric values (e.g., N:1,5:2.3).
  • System: Locale set to a non-English locale with comma decimal separator (e.g., de_DE, fr_FR, it_IT).
  • Network: No network-based IOCs as this is a local vulnerability.

Detection Engineering

YARA Rule

rule Cacti_Locale_Data_Corruption {
    meta:
        description = "Detects Cacti RRDtool update commands with comma decimal separators"
        author = "Valters IT"
        date = "2026-01-01"
        cve = "CVE-2026-39894"
    strings:
        $rrd_cmd = /rrdtool update .*:\d+,\d+/ nocase
    condition:
        $rrd_cmd
}

Sigma Rule

title: Cacti Locale-Based Data Corruption
id: 12345678-1234-1234-1234-123456789abc
status: experimental
description: Detects Cacti logs containing RRDtool update commands with comma decimal separators
author: Valters IT
date: 2026/01/01
logsource:
    product: linux
    service: cacti
detection:
    selection:
        EventID: 1
        Image: '/usr/bin/rrdtool'
        CommandLine|contains: 'update'
        CommandLine|re: ':\d+,\d+'
    condition: selection
falsepositives:
    - Legitimate use of comma in non-numeric fields (unlikely)
level: low

Suricata Rule

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2026-39894 Cacti Locale Data Corruption Attempt"; flow:to_server; content:"rrdtool update"; http_uri; pcre:"/:\d+,\d+/"; classtype:attempted-recon; sid:1000001; rev:1;)

Remediation & Mitigation

Immediate:

  • Upgrade to Cacti version 1.2.31 or later.
  • If upgrade is not possible, apply the hotfix by adding setlocale(LC_NUMERIC, 'C'); before the string interpolation in rrdtool_function_update().

Long-term:

  • Ensure all Cacti servers use a consistent locale with period decimal separator (e.g., en_US.UTF-8).
  • Implement monitoring for locale changes on critical servers.
  • Review PHP code for other locale-sensitive operations (e.g., number_format, sprintf).

Patch Details:

  • Fixed in Cacti version 1.2.31. The commit adds a setlocale() call to force the C locale before converting floats to strings.

Valters IT
DevSecOps & Cyber Threat Intelligence

◈ SOURCE Analysis & enrichment: valtersit.com/cve/CVE-2026-39894/ · CVE data: NVD/MITRE (public domain) · © 2026 ValtersIT Hub
>_ SYSTEM_CORE: INTEL_ACTIVE
90% TEAM-CURATED // 10% AUTOMATED INGESTION.
ALL PATCH REFERENCES AND VERSION DATA SOURCED FROM NVD + OSV OFFICIAL REGISTRIES.