security: authorize Report save/edit against report ownership

reports_form_save()'s update path fetched the existing report's owner from
the database but never compared it to the session user before calling
sql_save(), so any user holding only the Reports realm could overwrite
another user's report by POSTing its id. reports_edit() had the same gap on
the read side: it fetched a report by id with no ownership check, so the
same user could view any other user's report configuration (recipients,
schedule, etc.). 1.2.x already guards both call sites with
cacti_authorize_resource(..., 'reports'); develop had lost that check.

GHSA-8f5c-3h59-q7gc
This commit is contained in:
TheWitness committed 2026-09-22 12:02:22 -04:00
1 parent de13e48137
commit 92b8d4e6fc
2 files changed
+15

No files matched your search

+1
View File
@@ -1,6 +1,7 @@
Cacti CHANGELOG
1.3.0-dev
-security: Authorize Report save/edit against report ownership to close an authenticated IDOR (GHSA-8f5c-3h59-q7gc)
-security: Stop building the Realtime RRD create command through a shell and validate DS bounds are numeric before they reach it (GHSA-f88m-q789-g22j)
-security: Authorize tree node create/delete/move/rename/copy against per-tree access before mutating (GHSA-prxj-84qq-v5jq)
-security: Authorize single-item Report actions (remove/move) against report ownership to close a guest-bind IDOR (GHSA-j5jh-fhwg-r56x)
+14
View File
@@ -272,6 +272,13 @@ function reports_form_save() : void {
$save['user_id'] = $_SESSION[SESS_USER_ID];
} else {
$save['user_id'] = db_fetch_cell_prepared('SELECT user_id FROM reports WHERE id = ?', [$post['id']]);
if (!is_reports_admin() && (int) $save['user_id'] !== (int) $_SESSION[SESS_USER_ID]) {
raise_message('reports_idor', __('You do not have permission to modify this Report.'), MESSAGE_LEVEL_ERROR);
header('Location: ' . get_reports_page());
exit;
}
}
$save['id'] = $post['id'];
@@ -1631,6 +1638,13 @@ function reports_edit() : void {
if (gfrv('id') > 0) {
$report = db_fetch_row_prepared('SELECT * FROM reports WHERE id = ?', [grv('id')]);
if (cacti_sizeof($report) && !is_reports_admin() && (int) $report['user_id'] !== (int) $_SESSION[SESS_USER_ID]) {
raise_message('reports_idor', __('You do not have permission to view this Report.'), MESSAGE_LEVEL_ERROR);
header('Location: ' . get_reports_page());
exit;
}
}
reports_tabs(grv('id'));