From 937f67ed66936ce4fe5156a23b01b20c0d51db1a Mon Sep 17 00:00:00 2001 From: anupamme Date: Sat, 26 Sep 2026 15:28:03 +0000 Subject: [PATCH] fix: multi_agent.cwe-770 security vulnerability Automated security fix generated by OrbisAI Security --- lib/gateway.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/gateway.js b/lib/gateway.js index 04b97c4..74e800b 100644 --- a/lib/gateway.js +++ b/lib/gateway.js @@ -100,11 +100,14 @@ function createGateway(options) { const scope = options.scope || 'local'; const bodyLimit = positive(options.bodyLimit, 16 * 1024 * 1024, 'bodyLimit'); const timeoutMs = positive(options.timeoutMs, 120000, 'timeoutMs'); + const maxConcurrentUpstream = positive(options.maxConcurrentUpstream, 64, 'maxConcurrentUpstream'); const doFetch = options.fetch || globalThis.fetch; + let upstreamInFlight = 0; return http.createServer(async (req, res) => { const controller = new AbortController(); const timer = setTimeout(() => controller.abort(), timeoutMs); res.on('close', () => { if (!res.writableEnded) controller.abort(); }); + let countedUpstream = false; try { const path = new URL(req.url, 'http://localhost').pathname; /* /health is free, like the core serve: a probe must speak without a token. */ @@ -120,6 +123,9 @@ function createGateway(options) { } if (!baseUrl || !((req.method === 'POST' && path === '/v1/chat/completions') || (req.method === 'GET' && path === '/v1/models'))) return send(res, 404, { error: { code: 'NOTJEV_NO_ROUTE', message: 'Unknown gateway route' } }); + if (upstreamInFlight >= maxConcurrentUpstream) + return send(res, 429, { error: { code: 'NOTJEV_RATE_LIMITED', message: 'Too many concurrent upstream requests' } }); + upstreamInFlight++; countedUpstream = true; const body = req.method === 'POST' ? await readJson(req, bodyLimit) : undefined; const upstream = await doFetch(baseUrl + path, { method: req.method, signal: controller.signal, headers: { 'content-type': 'application/json', ...(options.upstreamApiKey ? { authorization: 'Bearer ' + options.upstreamApiKey } : {}) }, @@ -140,7 +146,7 @@ function createGateway(options) { } catch (e) { if (res.headersSent) res.destroy(); else send(res, e.code === 'NOTJEV_BODY_LIMIT' ? 413 : 400, { error: { code: e.code || 'NOTJEV_GATEWAY_ERROR', message: e.message } }); - } finally { clearTimeout(timer); } + } finally { clearTimeout(timer); if (countedUpstream) upstreamInFlight--; } }); }