{"id":"CVE-2026-97705","aliases":["GHSA-h89v-g948-47vp"],"url":"https://o3.security/vulnerability/CVE-2026-97705","summary":"Moleculer: Unauthenticated Denial of Service via negative length field in the TCP transporter packet parser","details":"### Summary\n\nThe TCP transporter's packet parser (`src/transporters/tcp/parser.js`) reads the packet length field with `Buffer.prototype.readInt32BE`, a signed read. A crafted packet whose length field has the sign bit set yields a negative `length`. The parser then advances past the parsed message with `packet = packet.slice(length)`, but `Buffer.prototype.slice` clamps an out-of-range negative start index to `0`, so the buffer is returned unchanged. The `while (packet.length > 0)` loop condition therefore never becomes false, producing an infinite synchronous loop that blocks the Node.js event loop indefinitely.\n\n### Impact\n\nAny Moleculer node using the TCP transporter can be rendered completely unresponsive by an unauthenticated remote peer sending a single ~10-byte crafted TCP packet, before any protocol handshake or authentication takes place. `TcpReader.onTcpClientConnected` pipes each accepted socket's bytes straight into a fresh `Parser` instance (`socket.pipe(parser)`) with no handshake, so the code path is reachable by any peer able to reach the transporter's listening port. Because Node.js is single-threaded, the hang blocks the entire event loop of the process, taking down every service hosted in it until it is forcibly restarted. TCP transporter endpoints are frequently auto-discovered via UDP broadcast, so any host on the same network segment can reach the port.\n\nNeither the CRC check nor `maxPacketSize` mitigate the issue: the CRC bytes are fully attacker-computable, and `maxPacketSize` bounds the received buffer size, not the value of the length field.\n\n### Affected component\n\n`Parser._write` in `src/transporters/tcp/parser.js`.\n\n### Patch\n\nThe fix validates that the decoded length is at least the 6-byte header size before processing, rejecting negative and undersized values (which would otherwise fail to shrink the buffer) with an error on the write callback instead of looping.\n\n### Credit\n\nReported by xor4xor via the Tidelift security program.","published":"2026-11-04T19:28:56.273Z","modified":"2026-11-07T02:30:53.994213015Z","cvss":{"score":7.5,"severity":"HIGH","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"},"epss":null,"cisaKev":null,"exploitsKnown":null,"affectedPackages":[{"ecosystem":"npm","name":"moleculer","fixedVersion":"0.15.2"},{"ecosystem":"npm","name":"moleculer","fixedVersion":"0.14.36"}],"fix":{"url":"https://github.com/moleculerjs/moleculer/commit/168ecbdc245c9a9d1dc4ef9b8a81dbae38ee3063","label":"moleculerjs/moleculer@168ecbd"},"references":[{"type":"WEB","url":"https://github.com/moleculerjs/moleculer/releases/tag/v0.14.36"},{"type":"WEB","url":"https://github.com/moleculerjs/moleculer/releases/tag/v0.15.2"},{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/97xxx/CVE-2026-97705.json"},{"type":"ADVISORY","url":"https://github.com/moleculerjs/moleculer/security/advisories/GHSA-h89v-g948-47vp"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-97705"},{"type":"FIX","url":"https://github.com/moleculerjs/moleculer/commit/168ecbdc245c9a9d1dc4ef9b8a81dbae38ee3063"},{"type":"FIX","url":"https://github.com/moleculerjs/moleculer/commit/914074e502ae403a0338ad168b45b16d6bcc3e44"},{"type":"PACKAGE","url":"https://github.com/moleculerjs/moleculer"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-11-07T02:30:53.994213015Z"}}