Summary
Zigbee2MQTT contains a path traversal vulnerability in its external JavaScript extension handlers. An attacker with access to the MQTT broker may escape the intended extensions directory to write and execute JavaScript files, or delete arbitrary files, when external JavaScript support is enabled.
Affected context
The vulnerability occurs in Zigbee2MQTT deployments using the external JavaScript extension feature. The affected handlers derive filesystem paths from an MQTT-supplied extension name and validate only the filename extension, allowing traversal components to escape the configured extensions directory. Risk is higher when external JavaScript support is enabled and the MQTT broker permits unauthenticated or insufficiently restricted access.
Exploit preconditions
- Attack surface: MQTT extension management messages, including the extension-save and extension-removal handlers
- Required access: Ability to publish relevant requests to the Zigbee2MQTT MQTT broker
- Configuration condition: External JavaScript extensions must be enabled for the write-and-import execution path
- Trigger point: Extension path construction followed by file writing and dynamic import, or extension removal
- Why exploitation is possible: User-controlled path components are passed to
path.join()without traversal containment checks, allowing paths to resolve outside the intended extensions directory
Why this happens
The underlying bug is insufficient validation of a user-controlled filesystem path. The application combines an attacker-influenced extension name with a trusted base directory using a path-joining operation, but does not verify that the normalized result remains within that directory. This maps to CWE-22: Improper Limitation of a Pathname to a Restricted Directory, and the impact is amplified because written JavaScript is subsequently loaded as executable code.
Potential impact
- An attacker may execute arbitrary JavaScript with the privileges of the Zigbee2MQTT process
- The application may be used to access credentials, configuration, or connected-device data
- An attacker could modify files outside the extensions directory
- Arbitrary files may be deleted through the extension-removal handler
- The host or surrounding environment could be used for further compromise
General mitigation guidance
Mitigation generally focuses on enforcing a strict filesystem trust boundary and reducing the capabilities of extension management interfaces.
Common defensive patterns include:
- Resolve candidate paths canonically and verify that they remain beneath the intended base directory
- Reject absolute paths and traversal components before filesystem operations
- Prefer opaque, server-generated extension identifiers over user-supplied filenames
- Apply strict allowlists for extension names and constrain writes and deletions to dedicated directories
- Require authenticated, authorized MQTT access and avoid exposing broker management topics broadly
- Keep external JavaScript execution disabled unless it is explicitly required
- Run Zigbee2MQTT with a dedicated low-privilege account and restrict filesystem permissions
- Treat dynamically imported extensions as untrusted code and isolate them where practical
How teams detect issues like this
Detection may combine source review, runtime monitoring, and access-control checks:
- Use static analysis rules for filesystem APIs that combine a trusted directory with MQTT, message, or request data
- Flag
path.join()or equivalent operations whose normalized output is not checked against the permitted base directory - Review code paths that write, delete, or dynamically import files based on externally supplied names
- Monitor MQTT topics for unexpected extension-management requests, traversal indicators, or unusual publication sources
- Audit broker authentication, authorization, and exposure of Zigbee2MQTT bridge topics
- Use policy checks and automated code-review tools to identify dynamic code loading and unrestricted file operations

