Skip to main content
Vulnerability Database/CVE-2026-104198

CVE-2026-104198: ZoneMinder Auth Bypass Vulnerability

CVE-2026-104198 is an authentication bypass flaw in ZoneMinder that allows attackers to skip login and access monitor metadata without authorization. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2026-104198 Overview

CVE-2026-104198 is an authentication bypass vulnerability in ZoneMinder, a free, open source closed-circuit television (CCTV) software application. The flaw affects versions 1.34.0 through 1.36.38 and resides in the web interface's token authentication logic in web/includes/auth.php. When token validation fails, the code assigns the boolean false return value to the global $user variable. The outer gate in web/index.php only checks isset($user), so false is treated as an authenticated user and the login redirect is skipped. Attackers can reach views that depend on the outer gate, including the zones view, to disclose monitor and zone metadata without authentication. The issue is tracked as [CWE-287] Improper Authentication.

Critical Impact

Unauthenticated remote attackers can access the zones view with an attacker-selected monitor ID and retrieve monitor and zone metadata from exposed ZoneMinder deployments.

Affected Products

  • ZoneMinder 1.34.0 through 1.36.38
  • ZoneMinder web interface (web/index.php, web/includes/auth.php)
  • Deployments with ZM_OPT_USE_AUTH enabled using token-based authentication

Discovery Timeline

  • 2026-10-15 - CVE-2026-104198 published to NVD
  • 2026-10-15 - Last updated in NVD database

Technical Details for CVE-2026-104198

Vulnerability Analysis

The vulnerability stems from how ZoneMinder handles failed token validation. In web/includes/auth.php, the validateToken() function returns an array where the first element is false when a token is malformed or carries an invalid signature. The calling code assigned that false value directly to the global $user variable. The outer authentication gate in web/index.php then evaluated isset($user), which returns true for a variable holding false. This mismatch between "variable exists" and "user is authenticated" allowed request processing to continue past the gate.

An attacker can submit a request to the zones view with a crafted or invalid token and an attacker-chosen monitor ID. The view dispatches and returns monitor and zone metadata without an independent permission check. Permission helpers that receive the false user value correctly deny privileged operations, so state-changing actions have not been established as reachable through this path. Impact is limited to information disclosure of monitor and zone configuration.

Root Cause

The root cause is improper handling of the return value from validateToken() combined with a weak existence check at the authentication gate. isset($false_variable) evaluates to true in PHP, so assigning a failure sentinel to $user defeated the gate. The code conflated "token processing attempted" with "user authenticated."

Attack Vector

Exploitation requires only network access to the ZoneMinder web interface. No credentials, user interaction, or prior access are needed. An attacker sends an HTTP request to the zones view with an invalid token parameter and a chosen monitor ID, then parses the response to extract monitor and zone metadata.

php
// Patch 1: web/includes/auth.php - reject false return from validateToken()
// Source: https://github.com/ZoneMinder/zoneminder/commit/6b94903e634fdb46cb71a48eadccf1aa14f0c2bb
    // don't know the token type. That will
    // be checked later 
    $ret = validateToken($_REQUEST['token'], 'any');
-    $user = $ret[0];
+    if (!$ret[0]) {
+      // validateToken returns array(false, $errorMessage) on failure.
+      // Assigning false to $user would leave isset($user) true, bypassing
+      // the ZM_OPT_USE_AUTH gate in index.php. Unset so $user stays undefined.
+      ZM\Warning($ret[1]);
+      unset($user); // unset should be ok here because we aren't in a function
+    } else {
+      $user = $ret[0];
+    }
php
// Patch 2: web/index.php - defense-in-depth instanceof check at the auth gate
// Source: https://github.com/ZoneMinder/zoneminder/commit/144a04ca4fff5fd02745ce8afc239ba5e05cf8ac
-if ( ZM_OPT_USE_AUTH and (!isset($user)) and ($view != 'login') and ($view != 'none') ) {
+if ( ZM_OPT_USE_AUTH and (!isset($user) or !($user instanceof ZM\User)) and ($view != 'login') and ($view != 'none') ) {
   if ($request) {
     # requests only return json
     header('HTTP/1.1 401 Unauthorized');

Detect Identity Attacks the Moment Authentication Fails

Singularity™ Identity surfaces credential misuse, lateral movement, and privilege escalation in real time, so you can contain the breach before it spreads.

Stop Identity Attacks

Detection Methods for CVE-2026-104198

Indicators of Compromise

  • HTTP requests to web/index.php with view=zones and a token parameter from unauthenticated sources.
  • Web server access logs showing responses to zones view requests without a preceding successful login or valid session cookie.
  • Repeated requests enumerating sequential mid (monitor ID) values paired with malformed token values.

Detection Strategies

  • Inspect ZoneMinder PHP error logs for ZM\Warning entries referencing token validation failures, especially when correlated with successful (HTTP 200) responses to protected views.
  • Deploy web application firewall (WAF) rules that flag requests to index.php?view=zones lacking a valid session identifier.
  • Compare ZoneMinder version strings in deployment inventories against the vulnerable range 1.34.0 through 1.36.38.

Monitoring Recommendations

  • Enable verbose authentication logging on the ZoneMinder web tier and forward events to centralized log storage.
  • Alert on anomalous access patterns to the zones view, including non-interactive user agents and bursts of monitor ID enumeration.
  • Monitor outbound metadata responses for size anomalies that could indicate bulk scraping of monitor and zone configuration.

How to Mitigate CVE-2026-104198

Immediate Actions Required

  • Upgrade ZoneMinder to version 1.36.63 or later, where the fix converts tokens to ZM\User objects before view dispatch.
  • Restrict network exposure of the ZoneMinder web interface to trusted networks or require VPN access until patched.
  • Review web server access logs for prior requests to view=zones that may indicate reconnaissance of monitor metadata.

Patch Information

The vulnerability is fixed in ZoneMinder 1.36.63. The remediation converts the token result to a ZM\User instance so invalid token state fails before view dispatch. Defense-in-depth commits explicitly unset($user) after failed token validation and add an instanceof ZM\User check at the web authentication gate. See the ZoneMinder Security Advisory GHSA-23fj-frfw-hmcr and the referenced commits 144a04c, 6b94903, and 71bb186.

Workarounds

  • Block unauthenticated access to web/index.php with view=zones at a reverse proxy or WAF layer.
  • Require an authenticated reverse proxy (such as mutual TLS or HTTP Basic auth) in front of the ZoneMinder web interface until the upgrade is complete.
  • Disable token-based authentication in ZM_OPT_USE_AUTH configurations where feasible, forcing session-based login flows.
bash
# Example nginx rule to block unauthenticated access to the zones view
location = /zm/index.php {
  if ($arg_view = "zones") {
    # require a valid session cookie; reject requests presenting only a token
    if ($cookie_ZMSESSID = "") {
      return 401;
    }
  }
  include fastcgi_params;
  fastcgi_pass unix:/run/php/php-fpm.sock;
}

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.