CVE-2026-102297 Overview
CVE-2026-102297 is an incorrect authorization vulnerability in ZoneMinder versions before 1.38.4. The FramesController index endpoint in the ZoneMinder REST API fails to enforce per-monitor access control lists (ACLs). Authenticated users holding the Events view permission can query the frames API and retrieve records from monitors they are explicitly denied access to. This exposes event and frame metadata across monitor boundaries, breaking multi-tenant and role-based segmentation assumptions. The flaw is tracked as CWE-863: Incorrect Authorization.
Critical Impact
Authenticated low-privilege users can enumerate event and frame metadata from restricted monitors, disclosing surveillance data beyond their authorized scope.
Affected Products
- ZoneMinder open-source video surveillance software
- ZoneMinder API component (web/api/app/Controller/FramesController.php)
- All ZoneMinder releases prior to version 1.38.4
Discovery Timeline
- 2026-09-28 - CVE-2026-102297 published to NVD
- 2026-09-30 - Last updated in NVD database
Technical Details for CVE-2026-102297
Vulnerability Analysis
ZoneMinder implements a per-user monitor access model where administrators can designate specific monitors as viewable or unviewable per account. The FramesController::index() endpoint queries frame records associated with events but did not apply the caller's monitor ACL to the underlying database query. As a result, any authenticated user with the Events view permission could list frame metadata belonging to events recorded on monitors outside their permitted scope. The disclosure is limited to metadata returned by the frames API, but that metadata can reveal camera activity patterns, event timing, and monitor identifiers useful for further reconnaissance.
Root Cause
The root cause is a missing authorization check in the frames listing logic. The controller retrieved the user's viewable monitor list through $user->viewableMonitorIds() but did not consistently constrain the query with an Event.MonitorId filter tied to that allowlist. Requests bypassed the intended ACL boundary because the filter path could resolve to an empty options set, returning frames across all monitors.
Attack Vector
Exploitation requires network access to the ZoneMinder web API and valid credentials for any account holding Events view rights. The attacker sends a request to the frames index endpoint and parses the returned JSON to enumerate frames from monitors the account is denied. No user interaction, elevated privileges, or exploit tooling is required.
// Patch: apply per-monitor ACL to FramesController::index()
// File: web/api/app/Controller/FramesController.php
global $user;
$allowedMonitors = ($user and $user->unviewableMonitorIds()) ? $user->viewableMonitorIds() : null;
- if ( $allowedMonitors ) {
- $mon_options = array('Event.MonitorId' => $allowedMonitors);
- } else {
- $mon_options = '';
- }
+
$named_params = $this->request->params['named'];
if ( $named_params ) {
$this->FilterComponent = $this->Components->load('Filter');
Source: ZoneMinder Commit aafe580b
Detection Methods for CVE-2026-102297
Indicators of Compromise
- Repeated authenticated requests to the ZoneMinder frames API endpoint (/zm/api/frames.json or /zm/api/frames/index) from a single low-privilege account.
- API responses containing MonitorId values that fall outside the requesting user's assigned monitor scope.
- Unusual enumeration patterns iterating over event IDs or paginating through frame records at high volume.
Detection Strategies
- Review ZoneMinder web server access logs for FramesController requests correlated with user session identifiers and compare the returned MonitorId set against each account's ACL.
- Compare frame API response payloads to the caller's viewableMonitorIds() result to identify boundary violations before patch deployment.
- Alert on API accounts that suddenly query frame data at a rate inconsistent with their historical baseline.
Monitoring Recommendations
- Forward ZoneMinder Apache or Nginx access logs to a centralized logging platform and retain API request URIs with authenticated user context.
- Instrument the ZoneMinder host to capture PHP error logs and database query logs during triage of suspected enumeration.
- Track the ZoneMinder version string reported in the UI or /zm/api/host/getVersion.json to confirm patched builds across deployments.
How to Mitigate CVE-2026-102297
Immediate Actions Required
- Upgrade all ZoneMinder installations to version 1.38.4 or later using the ZoneMinder Release v1.38.4 package.
- Audit ZoneMinder user accounts and revoke Events view permissions from any account that does not require frame API access.
- Rotate ZoneMinder API credentials for accounts that may have been used to enumerate restricted monitors.
Patch Information
The fix is delivered in ZoneMinder 1.38.4 via commits aafe580b and efe6c60d. Both commits apply per-monitor ACL enforcement to FramesController::index(). Full details are available in the ZoneMinder GitHub Security Advisory GHSA-mg2g-jmfc-3w8g and the VulnCheck ZoneMinder Advisory.
Workarounds
- Restrict network access to the ZoneMinder API using firewall rules or reverse-proxy allowlists until the patch is applied.
- Temporarily disable the frames API endpoint at the web server layer by blocking requests matching /zm/api/frames for non-administrative users.
- Enforce OPTIONS authentication and multi-factor authentication in front of ZoneMinder to raise the cost of credential abuse.
# Nginx snippet: block frames API for all users pending upgrade
location ~* ^/zm/api/frames {
deny all;
return 403;
}
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

