CVE-2024-24758: Exposure of Sensitive Information to an Unauthorized Actor (CWE-200)
value: Undici is an HTTP/1.1 client, written from scratch for Node.js. Undici already cleared Authorization headers on cross-origin redirects, but did not clear `Proxy-Authentication` headers. This issue has been patched in versions 5.28.3 and 6.6.1. Users are advised to upgrade. There are no known workarounds for this vulnerability.
CWE description: The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information.
Published: 2024-02-16T22:15Z
Repository: https://github.com/nodejs/undici
Language: JavaScript
Files changed: lib/fetch/index.js, test/fetch/redirect-cross-origin-header.js
Commit date: 2024-02-05 09:35:32 +0100
Commit message: Merge pull request from GHSA-3787-6prv-h9w3

Signed-off-by: Matteo Collina <hello@matteocollina.com>
Diff: diff --git a/lib/fetch/index.js b/lib/fetch/index.js
index 969378255..a3d02271d 100644
--- a/lib/fetch/index.js
+++ b/lib/fetch/index.js
@@ -1324,10 +1324,13 @@ function httpRedirectFetch (fetchParams, response) {
   //     delete headerName from request’s header list.
   if (!sameOrigin(requestCurrentURL(request), locationURL)) {
     // https://fetch.spec.whatwg.org/#cors-non-wildcard-request-header-name
     request.headersList.delete('authorization', true)
 
+    // https://fetch.spec.whatwg.org/#authentication-entries
+    request.headersList.delete('proxy-authorization', true)
+
     // "Cookie" and "Host" are forbidden request-headers, which undici doesn't implement.
     request.headersList.delete('cookie', true)
     request.headersList.delete('host', true)
   }
 
diff --git a/test/fetch/redirect-cross-origin-header.js b/test/fetch/redirect-cross-origin-header.js
index 5c1d91c99..3756c22d4 100644
--- a/test/fetch/redirect-cross-origin-header.js
+++ b/test/fetch/redirect-cross-origin-header.js
@@ -5,15 +5,16 @@ const { tspl } = require('@matteo.collina/tspl')
 const { createServer } = require('node:http')
 const { once } = require('node:events')
 const { fetch } = require('../..')
 
 test('Cross-origin redirects clear forbidden headers', async (t) => {
-  const { strictEqual } = tspl(t, { plan: 5 })
+  const { strictEqual } = tspl(t, { plan: 6 })
 
   const server1 = createServer((req, res) => {
     strictEqual(req.headers.cookie, undefined)
     strictEqual(req.headers.authorization, undefined)
+    strictEqual(req.headers['proxy-authorization'], undefined)
 
     res.end('redirected')
   }).listen(0)
 
   const server2 = createServer((req, res) => {
@@ -38,11 +39,12 @@ test('Cross-origin redirects clear forbidden headers', async (t) => {
   ])
 
   const res = await fetch(`http://localhost:${server2.address().port}`, {
     headers: {
       Authorization: 'test',
-      Cookie: 'ddd=dddd'
+      Cookie: 'ddd=dddd',
+      'Proxy-Authorization': 'test'
     }
   })
 
   const text = await res.text()
   strictEqual(text, 'redirected')

Vulnerable code:   const { strictEqual } = tspl(t, { plan: 5 })
      Cookie: 'ddd=dddd'
Fixed code:     // https://fetch.spec.whatwg.org/#authentication-entries
    request.headersList.delete('proxy-authorization', true)

  const { strictEqual } = tspl(t, { plan: 6 })
    strictEqual(req.headers['proxy-authorization'], undefined)
      Cookie: 'ddd=dddd',
      'Proxy-Authorization': 'test'