CVE-2026-71279 Overview
CVE-2026-71279 is a path traversal vulnerability in Zigbee2MQTT's ExternalJSExtension that leads to remote code execution and arbitrary file deletion. The getFilePath() function in lib/extension/externalJS.ts joins an attacker-controlled name parameter into the extensions base path using path.join(basePath, name) without sanitization. An attacker who can publish to the zigbee2mqtt/bridge/request/extension/save MQTT topic can escape the intended directory using ../ sequences, write a JavaScript file anywhere the process can reach, and trigger its execution via a dynamic import().
Critical Impact
Attackers with MQTT broker access can achieve remote code execution on the Zigbee2MQTT host when enable_external_js is enabled, and delete arbitrary files reachable by the process.
Affected Products
- Zigbee2MQTT bridge with enable_external_js configuration enabled
- Installations exposing an MQTT broker without authentication
- Legacy Zigbee2MQTT deployments that retained external JS extension support
Discovery Timeline
- 2026-08-05 - CVE-2026-71279 published to NVD
- 2026-08-05 - Last updated in NVD database
Technical Details for CVE-2026-71279
Vulnerability Analysis
The vulnerability resides in ExternalJSExtension.getFilePath() within lib/extension/externalJS.ts. The handler accepts a name field from an MQTT message published to zigbee2mqtt/bridge/request/extension/save and passes it directly into path.join(basePath, name). Because path.join() collapses ../ sequences, a payload such as ../../tmp/evil.js resolves outside the extensions directory. The save handler validates only the file extension (.js, .mjs, .cjs), writes attacker-supplied content to the resolved path, and then loads it through Node.js import(), producing arbitrary code execution in the Zigbee2MQTT process context. The same unsanitized function backs the extension-removal handler, so the primitive extends to arbitrary file deletion.
Root Cause
The root cause is missing input validation on a filesystem path segment sourced from an untrusted MQTT message, mapped to [CWE-22] Improper Limitation of a Pathname to a Restricted Directory. The code trusts name as a plain filename but never rejects directory separators or parent references. See the External JS extension source.
Attack Vector
Exploitation requires MQTT broker access adjacent to the Zigbee2MQTT deployment and the enable_external_js option to be set, which is off by default but common in older installs. Many home and small-business MQTT brokers run without authentication, lowering the practical barrier. The attacker publishes a crafted save request whose name field escapes the base directory and whose code field carries a JavaScript payload. The subsequent dynamic import() executes the payload with the privileges of the Zigbee2MQTT process. A parallel remove request abusing the same primitive deletes files at arbitrary paths.
Refer to the Zigbee2MQTT repository for handler implementation details.
Detection Methods for CVE-2026-71279
Indicators of Compromise
- MQTT messages to zigbee2mqtt/bridge/request/extension/save containing ../ or absolute paths in the name field
- Unexpected .js, .mjs, or .cjs files written outside the configured Zigbee2MQTT extensions directory
- Outbound network connections initiated by the Node.js process hosting Zigbee2MQTT after an extension save event
- Unexpected deletion of files owned by the Zigbee2MQTT service account
Detection Strategies
- Inspect MQTT broker logs for bridge/request/extension/save and bridge/request/extension/remove messages and alert on name values containing path separators or parent-directory sequences.
- Monitor the Zigbee2MQTT host for child processes spawned by the Node.js runtime, which is unusual under normal operation.
- Baseline the contents of the extensions directory and alert on file creation elsewhere by the Zigbee2MQTT user.
Monitoring Recommendations
- Forward MQTT broker and Zigbee2MQTT application logs to a centralized log platform for retention and correlation.
- Enable process and file integrity telemetry on the host running Zigbee2MQTT to identify anomalous writes and executions.
- Alert on any MQTT client connecting to the broker from unexpected network segments or without authentication.
How to Mitigate CVE-2026-71279
Immediate Actions Required
- Set enable_external_js: false in the Zigbee2MQTT configuration.yaml unless the feature is actively required.
- Enforce authentication and TLS on the MQTT broker and restrict broker access to trusted hosts using firewall rules or ACLs.
- Audit the extensions directory and the wider filesystem for unauthorized .js, .mjs, or .cjs files created after the feature was enabled.
- Rotate any secrets stored on or accessible from the Zigbee2MQTT host if compromise is suspected.
Patch Information
Apply the latest Zigbee2MQTT release that sanitizes the name parameter in ExternalJSExtension.getFilePath(). Track fix commits in the Zigbee2MQTT repository and review release notes before upgrading. Where a patched release is not yet deployable, disable the external JS feature until the upgrade is complete.
Workarounds
- Disable the external JS extension feature by removing or setting enable_external_js to false.
- Configure MQTT broker ACLs to deny publishes to zigbee2mqtt/bridge/request/# from clients other than trusted administrative accounts.
- Run Zigbee2MQTT under a dedicated low-privilege user with a restricted filesystem view, for example via containerization, to limit the impact of arbitrary file writes and deletions.
# Configuration example: disable external JS in Zigbee2MQTT configuration.yaml
external_converters: []
external_extensions: []
enable_external_js: false
# Mosquitto broker ACL restricting bridge request topics to a single admin user
# /etc/mosquitto/acl.conf
user admin
topic readwrite zigbee2mqtt/#
user z2m
topic readwrite zigbee2mqtt/#
topic deny zigbee2mqtt/bridge/request/extension/#
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

