CVE-2024-30260 (published 2024-04-04T16:15Z)

Undici is an HTTP/1.1 client, written from scratch for Node.js. Undici cleared Authorization and Proxy-Authorization headers for `fetch()`, but did not clear them for `undici.request()`. This vulnerability was patched in version(s) 5.28.4 and 6.11.1.\n


Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/nodejs/undici
commit_details: repo_url: https://github.com/nodejs/undici
author: Matteo Collina
author_date: 2024-04-02 12:41:40+02:00
msg: Merge pull request from GHSA-m4v8-wqvr-p9f7

Signed-off-by: Matteo Collina <hello@matteocollina.com>
repository: repo_url: https://github.com/nodejs/undici
repo_name: nodejs/undici
description: An HTTP/1.1 client, written from scratch for Node.js
repo_language: JavaScript
owner: nodejs
file_changes: filename: redirect-handler.js
change_type: ModificationType.MODIFY
diff: @@ -201,9 +201,9 @@ function shouldRemoveHeader (header, removeContent, unknownOrigin) {
   if (removeContent && util.headerNameToString(header).startsWith('content-')) {
     return true
   }
-  if (unknownOrigin && (header.length === 13 || header.length === 6)) {
+  if (unknownOrigin && (header.length === 13 || header.length === 6 || header.length === 19)) {
     const name = util.headerNameToString(header)
-    return name === 'authorization' || name === 'cookie'
+    return name === 'authorization' || name === 'cookie' || name === 'proxy-authorization'
   }
   return false
 }

programming_language: JavaScript
filename: redirect-cross-origin-header.js
change_type: ModificationType.ADD
diff: @@ -0,0 +1,52 @@
+'use strict'
+
+const { test } = require('node:test')
+const { tspl } = require('@matteo.collina/tspl')
+const { createServer } = require('node:http')
+const { once } = require('node:events')
+const { request } = require('..')
+
+test('Cross-origin redirects clear forbidden headers', async (t) => {
+  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) => {
+    strictEqual(req.headers.authorization, 'test')
+    strictEqual(req.headers.cookie, 'ddd=dddd')
+
+    res.writeHead(302, {
+      ...req.headers,
+      Location: `http://localhost:${server1.address().port}`
+    })
+    res.end()
+  }).listen(0)
+
+  t.after(() => {
+    server1.close()
+    server2.close()
+  })
+
+  await Promise.all([
+    once(server1, 'listening'),
+    once(server2, 'listening')
+  ])
+
+  const res = await request(`http://localhost:${server2.address().port}`, {
+    maxRedirections: 1,
+    headers: {
+      Authorization: 'test',
+      Cookie: 'ddd=dddd',
+      'Proxy-Authorization': 'test'
+    }
+  })
+
+  const text = await res.body.text()
+  strictEqual(text, 'redirected')
+})

programming_language: JavaScript