follow-redirects sensitiveHeaders regex escaping can expose credential headers
### Summary follow-redirects 1.16.0 introduced the `sensitiveHeaders` option (the fix for CVE-2026-40895 / GHSA-r4q5-vmmm-2653), which lets an application declare extra header names that must be removed when a redirect crosses to a different host or downgrades protocol. The filter is a single case-insensitive regular expression built by concatenating the declared header names into an alternation after passing each through `escapeRegex`. `escapeRegex` escapes only a partial set of metacharacters and leaves `^`, `|`, `[`, `{`, and `}` unescaped. Header names may legitimately contain `^` and `|` (both are valid RFC 9110 token characters that Node accepts and sends), and for a declared name containing either, the generated pattern can never match the intended header. As a result, an application that adopts this option to protect a custom credential header, then follows an attacker-controlled cross-origin redirect, forwards that credential to the attacker with no error or warning, while believing it is protected. The failure is silent: the protection simply does not exist for the affected names. The built-in list (Authorization, Proxy-Authorization, Cookie) contains no metacharacters and is not affected by this defect. ### Details The filter is constructed once, in the `RedirectableRequest` constructor at `index.js:118-120`: ```js this._headerFilter = new RegExp("^(?:" + sensitiveHeaders.concat(options.sensitiveHeaders).map(escapeRegex).join("|") + ")$", "i"); ``` `escapeRegex` at
- Products
- follow-redirects
- Affected versions
- Not specified
- Fixed versions
- 1.16.1
- CVEs
- CVE-2026-111755
- Confirmed fixed CVEs
- Not specified
- Updated in this feed
- 31 Oct 2026, 13:14 UTC · Revision 1
Source evidence
follow-redirects sensitiveHeaders regex escaping can expose credential headers
core-osv · Original sourcePublished 20 Oct 2026, 17:53 UTC
### Summary follow-redirects 1.16.0 introduced the `sensitiveHeaders` option (the fix for CVE-2026-40895 / GHSA-r4q5-vmmm-2653), which lets an application declare extra header names that must be removed when a redirect crosses to a different host or downgrades protocol. The filter is a single case-insensitive regular expression built by concatenating the declared header names into an alternation after passing each through `escapeRegex`. `escapeRegex` escapes only a partial set of metacharacters and leaves `^`, `|`, `[`, `{`, and `}` unescaped. Header names may legitimately contain `^` and `|` (both are valid RFC 9110 token characters that Node accepts and sends), and for a declared name containing either, the generated pattern can never match the intended header. As a result, an application that adopts this option to protect a custom credential header, then follows an attacker-controlled cross-origin redirect, forwards that credential to the attacker with no error or warning, while believing it is protected. The failure is silent: the protection simply does not exist for the affected names. The built-in list (Authorization, Proxy-Authorization, Cookie) contains no metacharacters and is not affected by this defect. ### Details The filter is constructed once, in the `RedirectableRequest` constructor at `index.js:118-120`: ```js this._headerFilter = new RegExp("^(?:" + sensitiveHeaders.concat(options.sensitiveHeaders).map(escapeRegex).join("|") + ")$", "i"); ``` `escapeRegex` at
osv:GHSA-8r9p-f939-6h3c
follow-redirects
Fixed versions: 1.16.1
Complete source record
{
"id": "9875e1e4dfbcc3237b41508676dde1cdc74e31ab66a2c87e7615f5d9b3782ce8",
"url": "https://osv.dev/vulnerability/GHSA-8r9p-f939-6h3c",
"method": "structured",
"payload": {
"kind": "advisory",
"title": "follow-redirects sensitiveHeaders regex escaping can expose credential headers",
"summary": "### Summary follow-redirects 1.16.0 introduced the `sensitiveHeaders` option (the fix for CVE-2026-40895 / GHSA-r4q5-vmmm-2653), which lets an application declare extra header names that must be removed when a redirect crosses to a different host or downgrades protocol. The filter is a single case-insensitive regular expression built by concatenating the declared header names into an alternation after passing each through `escapeRegex`. `escapeRegex` escapes only a partial set of metacharacters and leaves `^`, `|`, `[`, `{`, and `}` unescaped. Header names may legitimately contain `^` and `|` (both are valid RFC 9110 token characters that Node accepts and sends), and for a declared name containing either, the generated pattern can never match the intended header. As a result, an application that adopts this option to protect a custom credential header, then follows an attacker-controlled cross-origin redirect, forwards that credential to the attacker with no error or warning, while believing it is protected. The failure is silent: the protection simply does not exist for the affected names. The built-in list (Authorization, Proxy-Authorization, Cookie) contains no metacharacters and is not affected by this defect. ### Details The filter is constructed once, in the `RedirectableRequest` constructor at `index.js:118-120`: ```js this._headerFilter = new RegExp(\"^(?:\" + sensitiveHeaders.concat(options.sensitiveHeaders).map(escapeRegex).join(\"|\") + \")$\", \"i\"); ``` `escapeRegex` at",
"evidence": "osv:GHSA-8r9p-f939-6h3c",
"products": [
{
"name": {
"value": "follow-redirects",
"evidence": "/affected/0/package/name"
},
"prerequisites": [],
"fixed_versions": [
{
"value": "1.16.1",
"evidence": "/affected/0/ranges"
}
],
"affected_versions": []
}
],
"severity": "high",
"structured": {
"id": "GHSA-8r9p-f939-6h3c",
"aliases": [
"CVE-2026-111755",
"GHSA-8r9p-f939-6h3c"
],
"metrics": [
{
"type": "CVSS_V4",
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N"
}
],
"affected": [
{
"ranges": [
{
"type": "SEMVER",
"events": [
{
"introduced": "1.16.0"
},
{
"fixed": "1.16.1"
}
]
}
],
"package": {
"name": "follow-redirects",
"purl": "pkg:npm/follow-redirects",
"ecosystem": "npm"
},
"database_specific": {
"source": "https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-8r9p-f939-6h3c/GHSA-8r9p-f939-6h3c.json"
}
}
],
"modified": "2026-10-20T18:00:04.701467015Z",
"provider": "osv",
"references": [
"https://github.com/follow-redirects/follow-redirects/security/advisories/GHSA-8r9p-f939-6h3c",
"https://nvd.nist.gov/vuln/detail/CVE-2026-111755",
"https://github.com/follow-redirects/follow-redirects/commit/080a76d0e125b37bf81717368a61d5dc37aa56c8",
"https://github.com/follow-redirects/follow-redirects",
"https://github.com/follow-redirects/follow-redirects/releases/tag/v1.16.1"
],
"provider_metadata": {
"cwe_ids": [
"CWE-185",
"CWE-200"
],
"severity": "HIGH",
"github_reviewed": true,
"nvd_published_at": "2026-10-19T18:17:00Z",
"github_reviewed_at": "2026-10-20T17:53:05Z"
}
},
"related_cves": [
{
"value": "CVE-2026-111755",
"evidence": "/aliases"
}
],
"security_relevant": true,
"severity_evidence": "/database_specific/severity"
},
"source_id": "core-osv",
"document_id": 390128,
"published_at": "2026-10-20T17:53:05+00:00"
}