High severity7.3NVD Advisory· Published May 5, 2026· Updated May 6, 2026
CVE-2026-43870
CVE-2026-43870
Description
Origin Validation Error, Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal'), Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Request/Response Splitting'), Uncontrolled Resource Consumption vulnerability in Apache Thrift.
This issue affects Apache Thrift: before 0.23.0.
Users are recommended to upgrade to version 0.23.0, which fixes the issue.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
thriftnpm | <= 0.22.0 | — |
Affected products
2Patches
180184ddca4d4Harden Node.js WebSocket server handling
1 file changed · +25 −9
lib/nodejs/lib/thrift/web_server.js+25 −9 modified@@ -27,6 +27,10 @@ var log = require("./log"); var MultiplexedProcessor = require("./multiplexed_processor").MultiplexedProcessor; +function sanitizeHeader(value) { + return (value || "").replace(/[\r\n]/g, ""); +} + var TBufferedTransport = require("./buffered_transport"); var TBinaryProtocol = require("./binary_protocol"); var InputBufferUnderrunError = require("./input_buffer_underrun_error"); @@ -84,7 +88,7 @@ var wsFrame = { * @returns {Buffer} - The WebSocket frame, ready to send */ encode: function (data, mask, binEncoding) { - var frame = new Buffer(wsFrame.frameSizeFromData(data, mask)); + var frame = Buffer.alloc(wsFrame.frameSizeFromData(data, mask)); //Byte 0 - FIN & OPCODE frame[0] = wsFrame.fin.FIN + @@ -171,19 +175,19 @@ var wsFrame = { } //MASK if (wsFrame.mask.TO_SERVER == (frame[1] & wsFrame.mask.TO_SERVER)) { - result.mask = new Buffer(4); + result.mask = Buffer.alloc(4); frame.copy(result.mask, 0, dataOffset, dataOffset + 4); dataOffset += 4; } //Payload - result.data = new Buffer(len); + result.data = Buffer.alloc(len); frame.copy(result.data, 0, dataOffset, dataOffset + len); if (result.mask) { wsFrame.applyMask(result.data, result.mask); } //Next Frame if (frame.length > dataOffset + len) { - result.nextFrame = new Buffer(frame.length - (dataOffset + len)); + result.nextFrame = Buffer.alloc(frame.length - (dataOffset + len)); frame.copy(result.nextFrame, 0, dataOffset + len, frame.length); } //Don't forward control frames @@ -450,7 +454,8 @@ exports.createWebServer = function (options) { var filename = path.resolve(path.join(baseDir, uri)); //Ensure the basedir path is not able to be escaped - if (filename.indexOf(baseDir) != 0) { + var normalizedBase = baseDir.endsWith(path.sep) ? baseDir : baseDir + path.sep; + if (filename !== baseDir && filename.indexOf(normalizedBase) !== 0) { response.writeHead(400, "Invalid request path", {}); response.end(); return; @@ -543,6 +548,14 @@ exports.createWebServer = function (options) { } }) .on("upgrade", function (request, socket, head) { + //Verify CORS origin for WebSocket upgrades + if (request.headers.origin && options.cors) { + if (!options.cors["*"] && !options.cors[request.headers.origin]) { + socket.write("HTTP/1.1 403 Origin not allowed\r\n\r\n"); + socket.destroy(); + return; + } + } //Lookup service var svc; try { @@ -557,6 +570,9 @@ exports.createWebServer = function (options) { request.headers["sec-websocket-key"] + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", ); + var origin = sanitizeHeader(request.headers.origin); + var host = sanitizeHeader(request.headers.host); + var reqUrl = sanitizeHeader(request.url); socket.write( "HTTP/1.1 101 Switching Protocols\r\n" + "Upgrade: websocket\r\n" + @@ -565,11 +581,11 @@ exports.createWebServer = function (options) { hash.digest("base64") + "\r\n" + "Sec-WebSocket-Origin: " + - request.headers.origin + + origin + "\r\n" + "Sec-WebSocket-Location: ws://" + - request.headers.host + - request.url + + host + + reqUrl + "\r\n" + "\r\n", ); @@ -582,7 +598,7 @@ exports.createWebServer = function (options) { //Prepend any existing decoded data if (data) { if (result.data) { - var newData = new Buffer(data.length + result.data.length); + var newData = Buffer.alloc(data.length + result.data.length); data.copy(newData); result.data.copy(newData, data.length); result.data = newData;
Vulnerability mechanics
AI mechanics synthesis has not run for this CVE yet.
References
6- www.openwall.com/lists/oss-security/2026/05/05/4nvdMailing ListThird Party AdvisoryWEB
- github.com/advisories/GHSA-526f-jxpj-jmg2ghsaADVISORY
- lists.apache.org/thread/pgtfq44ltc9t63kxcbqmwqzt45pnhqdynvdVendor AdvisoryWEB
- nvd.nist.gov/vuln/detail/CVE-2026-43870ghsaADVISORY
- github.com/apache/thrift/commit/80184ddca4d4f60ac657bd82b2abc47269814f79ghsaWEB
- github.com/apache/thrift/releases/tag/v0.23.0ghsaWEB
News mentions
1- Patch Tuesday - May 2026Rapid7 Blog · May 13, 2026