mirror of
https://github.com/openembedded/meta-openembedded.git
synced 2026-07-27 07:57:27 +00:00
thrift: fix multiple CVEs
CVE-2026-43868:
Memory Allocation with Excessive Size Value vulnerability in Apache Thrift.
CVE-2026-43869:
Improper Validation of Certificate with Host Mismatch vulnerability in Apache Thrift.
This CVE only affects the Java client, which is not built by the recipe. Marked as
'not-applicable-config'.
Upstream commit:
https://github.com/apache/thrift/commit/a30c552bd0808b7e19f35ad30212ba7a9aee8c66
CVE-2026-43870:
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.
Signed-off-by: Roland Kovacs <roland.kovacs@est.tech>
Signed-off-by: Anuj Mittal <anuj.mittal@oss.qualcomm.com>
This commit is contained in:
committed by
Anuj Mittal
parent
d97b5602d7
commit
0a044f3363
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,134 @@
|
|||||||
|
From 86f647c6894360da7496efee6f6f5eb2601a5c3f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jens Geyer <jensg@apache.org>
|
||||||
|
Date: Sat, 11 Apr 2026 12:29:16 +0200
|
||||||
|
Subject: [PATCH] Harden Node.js WebSocket server handling Client: nodejs
|
||||||
|
|
||||||
|
- Validate origin on WebSocket upgrade using the same CORS rules
|
||||||
|
as HTTP requests
|
||||||
|
- Fix path containment check to use trailing separator
|
||||||
|
- Replace deprecated new Buffer() with Buffer.alloc()
|
||||||
|
- Sanitize interpolated header values in upgrade response
|
||||||
|
|
||||||
|
(04)
|
||||||
|
|
||||||
|
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
||||||
|
|
||||||
|
This closes #3391
|
||||||
|
|
||||||
|
CVE: CVE-2026-43870
|
||||||
|
Upstream-Status: Backport [https://github.com/apache/thrift/commit/5e4f01d737e4d3845d07dde6da43981feee0cb9a]
|
||||||
|
|
||||||
|
Signed-off-by: Roland Kovacs <roland.kovacs@est.tech>
|
||||||
|
---
|
||||||
|
lib/nodejs/lib/thrift/web_server.js | 34 +++++++++++++++++++++--------
|
||||||
|
1 file changed, 25 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/nodejs/lib/thrift/web_server.js b/lib/nodejs/lib/thrift/web_server.js
|
||||||
|
index f49f654b1..ad3a34c5c 100644
|
||||||
|
--- a/lib/nodejs/lib/thrift/web_server.js
|
||||||
|
+++ b/lib/nodejs/lib/thrift/web_server.js
|
||||||
|
@@ -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;
|
||||||
|
--
|
||||||
|
2.34.1
|
||||||
|
|
||||||
@@ -11,6 +11,8 @@ DEPENDS = "thrift-native boost flex-native bison-native openssl zlib"
|
|||||||
SRC_URI = "https://downloads.apache.org/${BPN}/${PV}/${BP}.tar.gz \
|
SRC_URI = "https://downloads.apache.org/${BPN}/${PV}/${BP}.tar.gz \
|
||||||
file://0001-DefineInstallationPaths.cmake-Define-libdir-in-terms.patch \
|
file://0001-DefineInstallationPaths.cmake-Define-libdir-in-terms.patch \
|
||||||
file://0001-support-reproducible-builds.patch \
|
file://0001-support-reproducible-builds.patch \
|
||||||
|
file://CVE-2026-43868.patch \
|
||||||
|
file://CVE-2026-43870.patch \
|
||||||
"
|
"
|
||||||
SRC_URI[sha256sum] = "794a0e455787960d9f27ab92c38e34da27e8deeda7a5db0e59dc64a00df8a1e5"
|
SRC_URI[sha256sum] = "794a0e455787960d9f27ab92c38e34da27e8deeda7a5db0e59dc64a00df8a1e5"
|
||||||
|
|
||||||
@@ -18,6 +20,8 @@ BBCLASSEXTEND = "native nativesdk"
|
|||||||
|
|
||||||
CVE_PRODUCT = "apache:thrift"
|
CVE_PRODUCT = "apache:thrift"
|
||||||
|
|
||||||
|
CVE_STATUS[CVE-2026-43869] = "not-applicable-config: The issue is present in the Java client which is not built"
|
||||||
|
|
||||||
inherit pkgconfig cmake python3native
|
inherit pkgconfig cmake python3native
|
||||||
|
|
||||||
export STAGING_INCDIR
|
export STAGING_INCDIR
|
||||||
|
|||||||
Reference in New Issue
Block a user