CVE-2026-71279
Full vulnerability record from the local CVENow database.
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.
Severity
HIGH
CVSS score
8.0
(v3.1)
Vulnerability status
Deferred
Source identifier
309f9ea4-e3e9-4c6c-b79d-e8eb01244f2c
Published
2026-08-05 13:24:52.437000
Last modified
2026-10-23 21:10:00.157000
View original CVE JSON
{
"id": "CVE-2026-71279",
"sourceIdentifier": "309f9ea4-e3e9-4c6c-b79d-e8eb01244f2c",
"published": "2026-08-05T13:24:52.437",
"lastModified": "2026-10-23T21:10:00.157",
"vulnStatus": "Deferred",
"cveTags": [],
"descriptions": [
{
"lang": "en",
"value": "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."
},
{
"lang": "es",
"value": "ExternalJSExtension.getFilePath() de Zigbee2MQTT (lib/extensión/externalJS.ts) une un parámetro ’name’ recibido a través de un mensaje MQTT (tema zigbee2mqtt/bridge/request/extensión/save) en la ruta base de las extensiones usando path.join(basePath, name) sin sanitización. Debido a que path.join() resuelve secuencias ’.. / ’, un nombre como ’.. / .. / tmp/evil.js’ escapa del directorio de extensiones previsto. El gestor de extensiones solo valida que el nombre termine en .js/.mjs/.cjs, escribe el archivo y luego lo importa dinámicamente a través de Node.js import(), logrando ejecución remota de código. Requiere la opción de configuración ’enable_external_js’ (desactivada por defecto, pero comúnmente habilitada en instalaciones heredadas) y acceso al broker MQTT, que con frecuencia no está autenticado en implementaciones reales. El idéntico getFilePath() no sanitizado también es utilizado por el gestor de eliminación de extensiones, permitiendo la eliminación arbitraria de archivos."
}
],
"affected": [
{
"source": "309f9ea4-e3e9-4c6c-b79d-e8eb01244f2c",
"affectedData": [
{
"vendor": "Koenkk",
"product": "zigbee2mqtt",
"defaultStatus": "unaffected",
"programFiles": [
"lib/extension/externalJS.ts"
],
"versions": [
{
"version": "0",
"lessThanOrEqual": "2.12.0",
"versionType": "semver",
"status": "affected"
}
]
}
]
}
],
"metrics": {
"cvssMetricV31": [
{
"source": "309f9ea4-e3e9-4c6c-b79d-e8eb01244f2c",
"type": "Secondary",
"cvssData": {
"version": "3.1",
"vectorString": "CVSS:3.1/AV:A/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"baseScore": 8.0,
"baseSeverity": "HIGH",
"attackVector": "ADJACENT_NETWORK",
"attackComplexity": "LOW",
"privilegesRequired": "LOW",
"userInteraction": "NONE",
"scope": "UNCHANGED",
"confidentialityImpact": "HIGH",
"integrityImpact": "HIGH",
"availabilityImpact": "HIGH"
},
"exploitabilityScore": 2.1,
"impactScore": 5.9
}
],
"ssvcV203": [
{
"source": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"ssvcData": {
"timestamp": "2026-08-05T15:55:04.507481Z",
"id": "CVE-2026-71279",
"options": [
{
"exploitation": "none"
},
{
"automatable": "no"
},
{
"technicalImpact": "total"
}
],
"role": "CISA Coordinator",
"version": "2.0.3"
}
}
]
},
"weaknesses": [
{
"source": "309f9ea4-e3e9-4c6c-b79d-e8eb01244f2c",
"type": "Secondary",
"description": [
{
"lang": "en",
"value": "CWE-22"
}
]
}
],
"references": [
{
"url": "https://github.com/Koenkk/zigbee2mqtt",
"source": "309f9ea4-e3e9-4c6c-b79d-e8eb01244f2c"
},
{
"url": "https://github.com/Koenkk/zigbee2mqtt/blob/master/lib/extension/externalJS.ts",
"source": "309f9ea4-e3e9-4c6c-b79d-e8eb01244f2c"
}
]
}