From b09da2e2aa9e021cd002196299e5ccf892c09365 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 6 Aug 2026 14:15:17 +0000 Subject: [PATCH 1/2] fix: prevent CRLF injection in CONNECT request headers The buildConnectRequest function interpolated header names and values directly into the raw HTTP CONNECT request without validation. This allowed CRLF sequences in header values to inject arbitrary headers into the proxy CONNECT request (CWE-113). Add validateHeaderName() and validateHeaderValue() that reject names or values containing CR, LF, or NUL characters. These are called automatically in buildConnectRequest and also exported for consumers who want to pre-validate input. Co-authored-by: ProxyMesh AI --- index.js | 2 +- lib/core/utils.js | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 8de00e9..be9f625 100644 --- a/index.js +++ b/index.js @@ -8,5 +8,5 @@ */ export { ProxyHeadersAgent, ConnectError } from './lib/core/proxy-headers-agent.js'; -export { parseProxyUrl, parseTargetUrl, buildConnectRequest } from './lib/core/utils.js'; +export { parseProxyUrl, parseTargetUrl, buildConnectRequest, validateHeaderName, validateHeaderValue } from './lib/core/utils.js'; export { parseConnectResponse, hasCompleteHeaders } from './lib/core/connect-parser.js'; diff --git a/lib/core/utils.js b/lib/core/utils.js index 01e714b..fdadf1e 100644 --- a/lib/core/utils.js +++ b/lib/core/utils.js @@ -2,6 +2,40 @@ * Utility functions for proxy header handling. */ +const INVALID_HEADER_CHAR = /[\r\n\0]/; + +/** + * Validate that a header name does not contain characters that could + * enable CRLF injection in raw HTTP protocol strings. + * @param {string} name - Header name + * @throws {TypeError} If the name contains CR, LF, or NUL + */ +export function validateHeaderName(name) { + if (typeof name !== 'string' || name.length === 0) { + throw new TypeError('Header name must be a non-empty string'); + } + if (INVALID_HEADER_CHAR.test(name)) { + throw new TypeError( + `Invalid character in header name: ${JSON.stringify(name.slice(0, 50))}` + ); + } +} + +/** + * Validate that a header value does not contain characters that could + * enable CRLF injection in raw HTTP protocol strings. + * @param {string} value - Header value + * @throws {TypeError} If the value contains CR, LF, or NUL + */ +export function validateHeaderValue(value) { + const str = String(value); + if (INVALID_HEADER_CHAR.test(str)) { + throw new TypeError( + `Invalid character in header value: ${JSON.stringify(str.slice(0, 50))}` + ); + } +} + /** * Parse a proxy URL into components. * @param {string|URL} proxyUrl - The proxy URL @@ -60,6 +94,8 @@ export function buildConnectRequest(targetHost, targetPort, proxyAuth, proxyHead ? [...proxyHeaders.entries()] : Object.entries(proxyHeaders || {}); for (const [key, value] of entries) { + validateHeaderName(key); + validateHeaderValue(value); lines.push(`${key}: ${value}`); } From d5d32feb5ca61e68f368024c7f4ced1a6507ea3f Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 6 Aug 2026 14:20:56 +0000 Subject: [PATCH 2/2] ci: retry integration tests (previous run hit transient 503 from proxy) Co-authored-by: ProxyMesh AI