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

CVE-2026-102608: ZoneMinder Shell Command Injection RCE

CVE-2026-102608 is a shell command injection flaw in ZoneMinder that enables remote code execution through malicious monitor names. Attackers can exploit this to run arbitrary commands as the web server user. This article covers technical details, affected versions, impact assessment, and mitigation strategies.

Published:

CVE-2026-102608 Overview

CVE-2026-102608 is a command injection vulnerability in ZoneMinder, an open-source closed-circuit television (CCTV) software application. The downloadEvents() function manually wraps a monitor Name value in single quotes instead of using PHP's escapeshellarg() before placing the value into shell commands. An authenticated user with monitor-create or monitor-edit permission can store a monitor Name containing shell metacharacters. When a user with Events View permission exports that monitor's events, the stored name reaches both the ffmpeg concatenation command and the tar or zip archive command, breaking out of manual quoting. Arbitrary commands then execute as the web server user. The issue is fixed in version 1.38.3.

Critical Impact

Stored command injection allows an authenticated low-privilege ZoneMinder user to achieve arbitrary code execution as the web server account during event export.

Affected Products

  • ZoneMinder versions prior to 1.38.3
  • ZoneMinder deployments exposing event export functionality to multi-user web interfaces
  • Any CCTV deployment granting monitor-create or monitor-edit permission to non-administrators

Discovery Timeline

  • 2026-10-16 - CVE-2026-102608 published to NVD
  • 2026-10-19 - Last updated in NVD database

Technical Details for CVE-2026-102608

Vulnerability Analysis

The flaw is a stored OS command injection [CWE-78] triggered during event export. ZoneMinder's downloadEvents() logic in web/includes/download_functions.php constructs shell commands by concatenating user-controlled monitor Name values into single-quoted strings. Because the quoting is applied manually, a Name containing a literal single quote terminates the quoted segment and allows arbitrary shell syntax to follow. The injected payload reaches two separate sinks: the ffmpeg -f concat command used to merge event video and the archive command (tar or zip) used to package the export. Both sinks execute via exec(), so arbitrary commands run with the privileges of the web server user, typically www-data or apache.

Root Cause

The root cause is improper neutralization of special elements used in an OS command. The vulnerable code paths relied on hand-written single-quote wrapping instead of PHP's dedicated escapeshellarg() function. Additionally, the archive command invocation did not use the -- end-of-options marker, allowing filename operands beginning with - to be interpreted as command-line switches.

Attack Vector

Exploitation requires two authenticated roles. First, a user with monitor-create or monitor-edit permission stores a crafted monitor Name containing shell metacharacters. Second, any user with Events View permission triggers an event export for that monitor, which invokes downloadEvents() and executes the injected commands.

php
// Vulnerable (pre-1.38.3) and patched code in web/includes/download_functions.php
// Source: https://github.com/ZoneMinder/zoneminder/commit/2de2ae44a1d751bad4b020c5573b2d58c59c1525

    } else {
      ZM\Error("Can't open event images export file 'event_files.txt'");
    }
-    $cmd = ZM_PATH_FFMPEG.' -f concat -safe 0 -i event_files.txt -c copy \''.$export_dir.'/'.$mergedFileName. '\' 2>&1';
+    $cmd = ZM_PATH_FFMPEG.' -f concat -safe 0 -i event_files.txt -c copy '.escapeshellarg($export_dir.'/'.$mergedFileName). ' 2>&1';
     exec($cmd, $output, $return);
     ZM\Debug($cmd.' return code: '.$return.' output: '.print_r($output,true));
     $exportFileList[] = $mergedFileName;

The patch replaces manual single-quote wrapping with escapeshellarg(). A follow-up commit also adds the -- end-of-options marker before filename operands passed to tar, zip, and gzip:

php
// Source: https://github.com/ZoneMinder/zoneminder/commit/b5605e01c14354fc8e2dcae8cefd90c3674880d9

    if ($command) {
-      $command .= ' '.escapeshellarg($mergedFileName); # Name of the file to be added
+      $command .= ' -- '.escapeshellarg($mergedFileName); # Name of the file to be added
      if (executeShelCommand($command, $deleteFile = $mergedFileName) === false) return false;
    }

Stop Remote Code Execution Before It Runs

Singularity™ Endpoint detects and blocks exploit attempts at machine speed, including zero-days and novel attack techniques.

Stop Exploit Attempts

Detection Methods for CVE-2026-102608

Indicators of Compromise

  • Monitor Name values stored in the ZoneMinder database that contain single quotes, backticks, $(), ;, |, or & characters
  • Unexpected child processes of the web server account spawning shells, curl, wget, nc, or python during event export operations
  • Entries in ZoneMinder debug logs showing ffmpeg -f concat or tar/zip commands containing shell metacharacters outside quoted segments

Detection Strategies

  • Audit the Monitors table for Name values containing shell metacharacters using a SQL query against the ZoneMinder database
  • Monitor process execution telemetry for www-data or apache spawning non-standard binaries following HTTP requests to index.php?view=download or event export endpoints
  • Inspect web server access logs for POST requests to monitor edit endpoints followed by GET requests to the event export handler

Monitoring Recommendations

  • Enable detailed PHP execution logging on the ZoneMinder web host and alert on exec() invocations containing suspicious patterns
  • Baseline normal child processes of the web server account and alert on deviations, especially outbound network tools
  • Forward web server, PHP, and OS process telemetry to a centralized analytics platform for correlation of monitor edits with subsequent export activity

How to Mitigate CVE-2026-102608

Immediate Actions Required

  • Upgrade ZoneMinder to version 1.38.3 or later, which replaces manual quoting with escapeshellarg() and adds the -- end-of-options marker
  • Review all existing monitor Name values and remove or rename any entries containing shell metacharacters before upgrading
  • Restrict monitor-create and monitor-edit permissions to trusted administrators only

Patch Information

The fix is included in ZoneMinder Release 1.38.3. The relevant commits are 2de2ae4, b3a7c05, and b5605e0. Full details are documented in ZoneMinder Security Advisory GHSA-88m4-hrgp-m9v3 and the Script Kittens technical write-up.

Workarounds

  • Temporarily revoke Events View permission for untrusted users until the upgrade is applied
  • Place the ZoneMinder web interface behind a network-level access control such as a VPN or source IP allowlist
  • Run the ZoneMinder web process under a hardened account with no shell, restrictive filesystem permissions, and no outbound network access
bash
# Example audit query to find monitor names containing shell metacharacters
mysql -u zmuser -p zm -e "SELECT Id, Name FROM Monitors WHERE Name REGEXP '[\\'\\\"\\\\\\\\\\\\$\\\\\\\\\\\\\\\\\\\\\\\\\\\\;\\\\\\\\\\\\|\\\\\\\\\\\\&\\\\\\\\\\\\\\\\\\\\\\\\\\\\`()<>]';"

# Example upgrade on Debian/Ubuntu once 1.38.3 is in your repository
sudo apt-get update
sudo apt-get install --only-upgrade zoneminder
sudo systemctl restart zoneminder apache2

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.