Description
Zigbee2MQTT's ExternalJSExtension.getFilePath (lib/extension/externalJS.ts) joins a parameter received via an MQTT message (topic zigbee2mqtt/bridge/request/extension/save) into the extensions base path using path.join(basePath, name) with no sanitization. The extension handler only validates that the name ends in .js/.mjs/.cjs, writes the file, and then dynamically imports it via Node.js import, achieving remote code execution.
Published: 2026-08-05
Score: 8.1 High
EPSS: < 1% Very Low
KEV: No
Impact: n/a
Action: n/a
AI Analysis

Impact

Zigbee2MQTT's ExternalJSExtension.getFilePath function joins a file name supplied via an MQTT message (topic zigbee2mqtt/bridge/request/extension/save) into the extensions base directory using path.join(basePath, name) with no sanitization. The only validation performed is that the filename ends with .js/.mjs/.cjs; the code then writes the file and immediately imports it using the Node.js import() function, providing an attacker with the ability to create arbitrary files elsewhere on the host and execute them. This flaw is a classic path traversal vulnerability (CWE‑22) that directly enables remote code execution. An attacker who can publish a crafted MQTT message can cause the gateway to write a malicious script to an arbitrary location, load it, and run it with the privileges of the Zigbee2MQTT process, compromising the host and potentially any connected smart‑home devices.

Affected Systems

The vulnerable logic exists in all Koenkk:zigbee2mqtt releases where the external JavaScript extension feature is enabled. Any environment running Zigbee2MQTT with enable_external_js set to true, regardless of host operating system, is at risk. The exploitation is performed through the MQTT bridge that processes messages on the bridge request topic, potentially impacting connected smart‑home devices via the bridge.

Risk and Exploitability

The CVSS score of 8.1 indicates a high severity condition for this vulnerability. The EPSS score is less than 1% and the vulnerability is not listed in the CISA KEV catalog. Exploitation requires an attacker to publish a specially crafted MQTT message to a broker that the gateway subscribes to. In many real deployments the broker is unauthenticated or has weak access controls, making the attack vector highly feasible. If successful, the attacker gains full remote code execution on the host running Zigbee2MQTT, compromising confidentiality, integrity, and availability of both the gateway and any connected devices.

Generated by OpenCVE AI on August 10, 2026 at 21:22 UTC.

Remediation

No vendor fix or workaround currently provided.

OpenCVE Recommended Actions

  • Disable the enable_external_js configuration option unless it is absolutely required.
  • Configure the MQTT broker to require authentication and restrict the bridge request topic to trusted clients only.
  • Check the vendor’s website or repository for updates or patches that address the issue.

Generated by OpenCVE AI on August 10, 2026 at 21:22 UTC.

Tracking

Sign in to view the affected projects.

Advisories

No advisories yet.

History

Mon, 10 Aug 2026 12:00:00 +0000

Type Values Removed Values Added
Description Zigbee2MQTT's ExternalJSExtension.getFilePath() (lib/extension/externalJS.ts) joins a `name` parameter received via an MQTT message (topic zigbee2mqtt/bridge/request/extension/save) into the extensions base path using path.join(basePath, name) with no sanitization. Because path.join() resolves `../` sequences, a name such as `../../tmp/evil.js` escapes the intended extensions directory. The extension handler only validates that the name ends in .js/.mjs/.cjs, writes the file, and then dynamically imports it via Node.js import(), achieving remote code execution. Requires the `enable_external_js` config option (off by default, but commonly enabled in legacy installs) and MQTT broker access, which is frequently unauthenticated in real deployments. The identical unsanitized getFilePath() is also used by the extension-removal handler, enabling arbitrary file deletion. Zigbee2MQTT's ExternalJSExtension.getFilePath (lib/extension/externalJS.ts) joins a parameter received via an MQTT message (topic zigbee2mqtt/bridge/request/extension/save) into the extensions base path using path.join(basePath, name) with no sanitization. The extension handler only validates that the name ends in .js/.mjs/.cjs, writes the file, and then dynamically imports it via Node.js import, achieving remote code execution.
Title Zigbee2MQTT - External JS Extension Path Traversal Leading to Remote Code Execution Zigbee2MQTT External JS Extension Path Traversal Leading to Remote Code Execution

Mon, 10 Aug 2026 11:45:00 +0000

Type Values Removed Values Added
Title Zigbee2MQTT External JS Extension Path Traversal Leading to Remote Code Execution Zigbee2MQTT - External JS Extension Path Traversal Leading to Remote Code Execution

Fri, 07 Aug 2026 10:30:00 +0000

Type Values Removed Values Added
First Time appeared Koenkk
Koenkk zigbee2mqtt
Vendors & Products Koenkk
Koenkk zigbee2mqtt

Wed, 05 Aug 2026 16:30:00 +0000

Type Values Removed Values Added
Metrics ssvc

{'options': {'Automatable': 'no', 'Exploitation': 'none', 'Technical Impact': 'total'}, 'version': '2.0.3'}


Wed, 05 Aug 2026 13:15:00 +0000

Type Values Removed Values Added
Description Zigbee2MQTT's ExternalJSExtension.getFilePath() (lib/extension/externalJS.ts) joins a `name` parameter received via an MQTT message (topic zigbee2mqtt/bridge/request/extension/save) into the extensions base path using path.join(basePath, name) with no sanitization. Because path.join() resolves `../` sequences, a name such as `../../tmp/evil.js` escapes the intended extensions directory. The extension handler only validates that the name ends in .js/.mjs/.cjs, writes the file, and then dynamically imports it via Node.js import(), achieving remote code execution. Requires the `enable_external_js` config option (off by default, but commonly enabled in legacy installs) and MQTT broker access, which is frequently unauthenticated in real deployments. The identical unsanitized getFilePath() is also used by the extension-removal handler, enabling arbitrary file deletion.
Title Zigbee2MQTT External JS Extension Path Traversal Leading to Remote Code Execution
Weaknesses CWE-22
References
Metrics cvssV3_1

{'score': 8.1, 'vector': 'CVSS:3.1/AV:A/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H'}


Subscriptions

Koenkk Zigbee2mqtt
cve-icon MITRE

Status: PUBLISHED

Assigner: TuranSec

Published:

Updated: 2026-08-10T11:47:00.480Z

Reserved: 2026-08-05T12:23:34.967Z

Link: CVE-2026-71279

cve-icon Vulnrichment

Updated: 2026-08-05T15:55:07.728Z

cve-icon NVD

Status : Deferred

Published: 2026-08-05T13:24:52.437

Modified: 2026-08-26T17:13:24.800

Link: CVE-2026-71279

cve-icon Redhat

No data.

cve-icon OpenCVE Enrichment

Updated: 2026-08-10T21:30:04Z

Weaknesses
  • CWE-22

    Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')