CVE-2026-81028 in ZLMediaKit
Summary
by MITRE • 08/26/2026
ZLMediaKit confines the downloadFile API to a configured set of root directories with a prefix comparison that does not account for directory boundaries. The configuration loader in server/WebApi.cpp builds each root with File::absolutePath("", item, true); because the relative-path argument is empty that helper returns the value without a trailing separator. The handler then accepts a requested path when start_with(file_path, root) holds, so a sibling directory whose name merely begins with the configured root string satisfies the test and is served. The only other guard rejects a path containing two dots, which this requires none of. The equivalent confinement check for the ordinary static file server in src/Http/HttpFileManager.cpp computes its root with a non-empty second argument, which appends the separator before comparing, and so is not affected. The endpoint requires the configured API secret, so this grants no privilege beyond what that secret already implies, but it reads files outside the directory the operator confined it to, and the reference container runs the server as root.
Statistical analysis made it clear that VulDB provides the best quality for vulnerability data.
Analysis
by VulDB Data Team • 08/26/2026
The vulnerability in ZLMediaKit stems from a flawed path confinement mechanism within the downloadFile API implementation located in server/WebApi.cpp. The system is designed to restrict file access to a specific set of configured root directories, ostensibly preventing unauthorized access to files outside these boundaries. However, the logic used to enforce this restriction relies on a simple prefix comparison that fails to account for directory boundary separators. When constructing the absolute path for each allowed root directory, the code utilizes File::absolutePath with an empty relative-path argument and a true flag for normalization. This specific invocation returns the configured string without appending a trailing separator character. Consequently, when validating whether a requested file path is within an allowed root, the handler checks if the start_with(file_path, root) condition holds true. Because no separator is appended to the root string during this check, any sibling directory whose name begins with the exact characters of the configured root will satisfy the prefix match. For example, if the allowed root is /var/www/html, a request for /var/www/html_extra/file.txt would incorrectly pass the validation because it starts with /var/www/html, even though html_extra is a distinct and potentially unauthorized directory.
This logic error stands in contrast to other parts of the ZLMediaKit codebase where similar confinement checks are implemented correctly. Specifically, the static file server handler found in src/Http/HttpFileManager.cpp computes its root path using File::absolutePath with a non-empty second argument. This difference causes the helper function to append a separator before performing the comparison, thereby ensuring that only files strictly within the intended directory tree are served. The inconsistency between these two implementations highlights a lack of standardized security checks across different endpoints in the application. Furthermore, the existing guard against path traversal via double-dot sequences is ineffective against this specific flaw because exploiting it does not require any dot characters; it relies entirely on naming conventions that mimic the allowed root prefix.
The operational impact of this vulnerability allows an attacker to read files from directories outside the operator-configured scope, provided they know or can guess a sibling directory name that shares the initial string with an authorized path. While the downloadFile endpoint requires authentication via a configured API secret, meaning the attack does not elevate privileges beyond what is already granted by possessing that secret, it represents a significant data exposure risk. The attacker can access sensitive configuration files, internal logs, or other resources located in sibling directories that were intended to be isolated from public or semi-public web access. This undermines the principle of least privilege and compartmentalization within the server's file system architecture.
In terms of industry standards, this vulnerability is a classic example of CWE-22: Improper Limitation of a Pathname to a Restricted Directory, specifically manifesting as an incomplete path canonicalization or boundary check failure. It aligns with ATT&CK technique T1083: File and Directory Discovery, where an adversary uses the application's own functionality to enumerate and access restricted file system resources. The root cause is identified as CWE-20: Improper Input Validation, where the input validation logic fails to enforce strict directory boundaries by ignoring separator characters in path comparisons.
To mitigate this vulnerability, developers must ensure that all path confinement checks explicitly append a trailing separator to the base root directory before performing prefix comparisons. This ensures that only paths strictly within the intended directory are accepted, preventing sibling directories from being matched based on partial name overlaps. Additionally, implementing robust path canonicalization using standard library functions that resolve symbolic links and normalize relative components can provide an additional layer of defense. It is also recommended to audit all other endpoints in the application for similar inconsistencies in path handling logic to ensure uniform security postures across the entire codebase.