CVE-2026-76788
El analizador de respuestas del Panel de Control OSDP cp_decode_response() en subsys/mgmt/osdp/src/osdp_cp.c decodifica las respuestas de un Dispositivo Periférico en una estructura struct osdp_event asignada en la pila. Para los tipos de respuesta REPLY_KEYPPAD y REPLY_RAW, la longitud de la carga útil se toma de la trama recibida, y la única validación realizada es que la longitud declarada sea coherente con el número de bytes de carga útil presentes en la trama.
Leer descripción completaMostrar menos
Como el atacante controla tanto el campo de longitud como la longitud de la trama, esa comprobación no impone ningún límite, y el memcpy() posterior escribe en los arrays de datos de 64 bytes de tamaño fijo de struct osdp_event_keypress / struct osdp_event_cardread (OSDP_EVENT_MAX_DATALEN). El manejador hermano REPLY_FMT, dentro del mismo switch, ya incluía la comprobación de límite > OSDP_EVENT_MAX_DATALEN que faltaba.
Se llega al defecto desde cp_process_reply(), que lee bytes del canal RS-485 de OSDP y los pasa por osdp_phy_check_packet() y osdp_phy_decode_packet() antes de despachar según el ID de respuesta. Para provocarlo se requiere CONFIG_OSDP con CONFIG_OSDP_MODE_CP y un callback de eventos de la aplicación registrado (la integración habitual del Panel de Control), además de una trama con un SOM correcto, un CRC-16 válido y un número de secuencia de 2 bits coincidente; todo ello es calculable o observable por cualquiera en el bus. Ninguna comprobación vincula el ID de respuesta con el comando pendiente, por lo que un REPLY_KEYPPAD o REPLY_RAW demasiado grande se acepta como respuesta a un CMD_POLL rutinario. Un lector de tarjetas malicioso o comprometido, o cualquiera con acceso al cableado RS-485, puede enviar una trama de este tipo. CONFIG_OSDP_SC_ENABLED solo ayuda mientras hay un canal seguro activo, y una única trama sin autenticar con un MAC incorrecto provoca sc_deactivate(), tras lo cual vuelven a aceptarse las respuestas en texto plano.
Con el valor por defecto de CONFIG_OSDP_UART_BUFFER_LENGTH, que es 256, pueden escribirse unos 180 bytes de datos totalmente elegidos por el atacante más allá del final del objeto de evento asignado en la pila, sobre los registros guardados y la dirección de retorno en los diseños de trama habituales de Cortex-M y RISC-V (Zephyr no activa por defecto los canarios de pila). El impacto va desde un bloqueo completo del panel de control de acceso hasta un posible secuestro del flujo de control en el contexto del hilo de recepción de OSDP. La corrección añade un límite OSDP_EVENT_MAX_DATALEN a ambos manejadores, acotando cada memcpy() al tamaño de su destino.
Traducción automática del texto original de NVD (en inglés).
CVSS
- Puntuación base
- 8.8
- Versión
- 3.1
- Vector
- CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Probabilidad de explotación (EPSS)
- Probabilidad de explotación en los próximos 30 días
- 0.20 %
- Percentil entre todas las CVEs puntuadas
- 10
- Fecha de la puntuación
- 20/10/2026
EPSS (Exploit Prediction Scoring System, de FIRST) estima la probabilidad de que una vulnerabilidad sea explotada en 30 días. Complementa a CVSS (impacto) y a CISA KEV (explotación confirmada).
Técnicas ATT&CK
Cómo se explota esta vulnerabilidad y qué consigue el atacante, en el lenguaje de MITRE ATT&CK.
- Explotación
T1210Exploitation of Remote Serviceslateral movement90 % - Impacto principal
T1499Endpoint Denial of Serviceimpact85 % - Impacto secundario
T1059Command and Scripting Interpreterexecution35 %
Vector AV:A/PR:N/UI:N y escritura de pila desde respuestas OSDP (REPLY_KEYPPAD/RAW sin límite): provoca caída del panel y posible secuestro del flujo de control.
Inferido por nuestro agente de análisis a partir de la descripción oficial, el vector CVSS y la CWE, y comprobado por un supervisor. Puede contener errores.
Mitigaciones ATT&CK que cubren estas técnicas
Tecnologías afectadas (1)
⚠ Inferidas por IA a partir de la descripción — NVD aún no ha analizado esta CVE; no son CPE verificados.
CWE
- CWE-787
Referencias
JSON original (NVD)
Mostrar
{
"id": "CVE-2026-76788",
"cveTags": [],
"metrics": {
"cvssMetricV31": [
{
"type": "Secondary",
"source": "vulnerabilities@zephyrproject.org",
"cvssData": {
"scope": "UNCHANGED",
"version": "3.1",
"baseScore": 8.8,
"attackVector": "ADJACENT_NETWORK",
"baseSeverity": "HIGH",
"vectorString": "CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"integrityImpact": "HIGH",
"userInteraction": "NONE",
"attackComplexity": "LOW",
"availabilityImpact": "HIGH",
"privilegesRequired": "NONE",
"confidentialityImpact": "HIGH"
},
"impactScore": 5.9,
"exploitabilityScore": 2.8
}
]
},
"affected": [
{
"source": "vulnerabilities@zephyrproject.org",
"affectedData": [
{
"vendor": "zephyrproject",
"product": "zephyr",
"versions": [
{
"status": "affected",
"version": "3.3.0",
"versionType": "semver",
"lessThanOrEqual": "4.4.2"
}
],
"packageName": "zephyr",
"programFiles": [
"subsys/mgmt/osdp/src/osdp_cp.c"
],
"collectionURL": "https://github.com/zephyrproject-rtos/zephyr",
"defaultStatus": "unaffected",
"programRoutines": [
{
"name": "cp_decode_response"
}
]
}
]
}
],
"published": "2026-10-19T21:18:01.380",
"references": [
{
"url": "https://github.com/zephyrproject-rtos/zephyr/commit/f10d55f47c6970e95d3a7c6ba08e6adec3c79acd",
"source": "vulnerabilities@zephyrproject.org"
},
{
"url": "https://github.com/zephyrproject-rtos/zephyr/security/advisories/GHSA-fgg7-h8p9-9q3w",
"source": "vulnerabilities@zephyrproject.org"
}
],
"vulnStatus": "Received",
"weaknesses": [
{
"type": "Secondary",
"source": "vulnerabilities@zephyrproject.org",
"description": [
{
"lang": "en",
"value": "CWE-787"
}
]
}
],
"descriptions": [
{
"lang": "en",
"value": "The OSDP Control Panel reply parser cp_decode_response() in subsys/mgmt/osdp/src/osdp_cp.c decodes replies from a Peripheral Device into a stack-allocated struct osdp_event. For the REPLY_KEYPPAD and REPLY_RAW reply types, the payload length is taken from the received frame and the only validation performed is that the declared length is self-consistent with the number of payload bytes present in the frame. Because the attacker controls both the length field and the frame length, that check imposes no bound, and the subsequent memcpy() writes into the fixed 64-byte data arrays of struct osdp_event_keypress / struct osdp_event_cardread (OSDP_EVENT_MAX_DATALEN). The sibling REPLY_FMT handler in the same switch already carried the missing > OSDP_EVENT_MAX_DATALEN bound.\n\nThe defect is reached from cp_process_reply(), which reads bytes from the OSDP RS-485 channel and passes them through osdp_phy_check_packet() and osdp_phy_decode_packet() before dispatching on the reply ID. Triggering it requires CONFIG_OSDP with CONFIG_OSDP_MODE_CP and an application event callback registered (the normal Control Panel integration), plus a frame carrying a correct SOM, a valid CRC-16, and a matching 2-bit sequence number — all of which are computable or observable by anyone on the bus. No check ties the reply ID to the outstanding command, so an oversized REPLY_KEYPPAD or REPLY_RAW is accepted as the answer to a routine CMD_POLL. A malicious or compromised card reader, or anyone with access to the RS-485 wiring, can supply such a frame; CONFIG_OSDP_SC_ENABLED only helps while a secure channel is active, and a single unauthenticated frame carrying a bad MAC causes sc_deactivate(), after which plaintext replies are again accepted.\n\nWith the default CONFIG_OSDP_UART_BUFFER_LENGTH of 256, roughly 180 bytes of fully attacker-chosen data can be written past the end of the stack-allocated event object, over saved registers and the return address on typical Cortex-M and RISC-V frame layouts (Zephyr does not enable stack canaries by default). The impact ranges from a hard crash of the access-control panel to potential control-flow hijack in the context of the OSDP receive thread. The fix adds an OSDP_EVENT_MAX_DATALEN bound to both handlers, capping each memcpy() at the size of its destination."
}
],
"lastModified": "2026-10-19T21:18:01.380",
"sourceIdentifier": "vulnerabilities@zephyrproject.org"
}