CVE-2023-49086: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: Cacti is a robust performance and fault management framework and a frontend to RRDTool - a Time Series Database (TSDB). A vulnerability in versions prior to 1.2.27 bypasses an earlier fix for CVE-2023-39360, therefore leading to a DOM XSS attack. Exploitation of the vulnerability is possible for an authorized user. The vulnerable component is the `graphs_new.php`. The impact of the vulnerability is execution of arbitrary JavaScript code in the attacked user's browser. This issue has been patched in version 1.2.27.

CWE description: The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
CVSS v3 base score: 5.4
Published: 2023-12-22T00:15Z
Repository: https://github.com/Cacti/cacti
Language: PHP
Files changed: data_debug.php, graphs_new.php
Commit date: 2023-12-28 17:25:47 -0500
Commit message: QA: Fix 2 of 3 - Commits for CVE-2023-49088 and CVE-2023-48086

Missed here https://github.com/Cacti/cacti/security/advisories/GHSA-q7g7-gcf6-wh4x
and here:
https://github.com/Cacti/cacti/security/advisories/GHSA-wc73-r2vw-59pr

Diff: diff --git a/data_debug.php b/data_debug.php
index ee909d4f4b..acb54a8f2d 100644
--- a/data_debug.php
+++ b/data_debug.php
@@ -689,11 +689,11 @@ function debug_view() {
 		FROM data_template_data
 		WHERE local_data_id = ?',
 		array($id));
 
 	if (cacti_sizeof($dtd)) {
-		$real_path = str_replace('<path_rra>', CACTI_PATH_RRA, $dtd['data_source_path']);
+		$real_path = html_escape(str_replace('<path_rra>', $config['rra_path'], $dtd['data_source_path']));
 	} else {
 		$real_path = __('Not Found');
 	}
 
 	$poller_data = array();
diff --git a/graphs_new.php b/graphs_new.php
index 90585707ab..e2d45faf83 100644
--- a/graphs_new.php
+++ b/graphs_new.php
@@ -995,12 +995,28 @@ function graphs() {
 	if (!isempty_request_var('host_id')) {
 		form_hidden_box('host_id', $host['id'], '0');
 		form_hidden_box('host_template_id', $host['host_template_id'], '0');
 	}
 
-	if (isset($_SERVER['HTTP_REFERER']) && strpos($_SERVER['HTTP_REFERER'], 'graphs_new') === false) {
-		set_request_var('returnto', basename($_SERVER['HTTP_REFERER']));
+	if (isset($_SERVER['HTTP_REFERER']) && $_SERVER['HTTP_REFERER'] != '') {
+		$referer_url = parse_url($_SERVER['HTTP_REFERER']);
+
+		if ($_SERVER['SERVER_NAME'] != $referer_url['host']) {
+			/* Potential security exploit 1 */
+			set_request_var('returnto', 'host.php');
+		} elseif (strpos($_SERVER['HTTP_REFERER'], 'graphs_new') === false) {
+			set_request_var('returnto', basename($_SERVER['HTTP_REFERER']));
+		} else {
+			set_request_var('returnto', 'host.php');
+		}
+	} elseif (isset_request_var('returnto') && get_nfilter_request_var('returnto') != '') {
+		$returnto_url = parse_url(get_nfilter_request_var('returnto'));
+
+		if ($_SERVER['SERVER_NAME'] != $returnto_url['host']) {
+			/* Potential security exploit 2 */
+			set_request_var('returnto', 'host.php');
+		}
 	}
 
 	load_current_session_value('returnto', 'sess_grn_returnto', '');
 
 	if (strpos(get_nfilter_request_var('returnto'), 'host.php') === false) {

Vulnerable code: 		$real_path = str_replace('<path_rra>', CACTI_PATH_RRA, $dtd['data_source_path']);
	if (isset($_SERVER['HTTP_REFERER']) && strpos($_SERVER['HTTP_REFERER'], 'graphs_new') === false) {
		set_request_var('returnto', basename($_SERVER['HTTP_REFERER']));
Fixed code: 		$real_path = html_escape(str_replace('<path_rra>', $config['rra_path'], $dtd['data_source_path']));
	if (isset($_SERVER['HTTP_REFERER']) && $_SERVER['HTTP_REFERER'] != '') {
		$referer_url = parse_url($_SERVER['HTTP_REFERER']);

		if ($_SERVER['SERVER_NAME'] != $referer_url['host']) {
			/* Potential security exploit 1 */
			set_request_var('returnto', 'host.php');
		} elseif (strpos($_SERVER['HTTP_REFERER'], 'graphs_new') === false) {
			set_request_var('returnto', basename($_SERVER['HTTP_REFERER']));
		} else {
			set_request_var('returnto', 'host.php');
		}
	} elseif (isset_request_var('returnto') && get_nfilter_request_var('returnto') != '') {
		$returnto_url = parse_url(get_nfilter_request_var('returnto'));

		if ($_SERVER['SERVER_NAME'] != $returnto_url['host']) {
			/* Potential security exploit 2 */
			set_request_var('returnto', 'host.php');
		}