HD-2024-1408

Information Exposure
Affects
Node.js
16.20.2 LTS
in
Node.js
Node.js NES
Exclamation circle icon
Patch Available
This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs

‍Overview

Undici is a high-performance HTTP/1.1 client written for Node.js that can be used in place of the native library. Part of the Fetch Standard indicates that forbidden request headers, such as cookies, should never be passed to the target site upon a redirect. Versions of undici prior to 5.26.2 failed to do that. (Note that for Node 16 this is a concern only when the --experimental-fetch flag is used.)

This vulnerability may be combined with the Open Redirect exploit in which an attacker gets a server to redirect to a site they control. If sensitive data, such as authorization tokens, is contained in the cookie, the destination site (which may be controlled by the attacker), receives the sensitive data. 

This issue affects undici versions lower than 5.26.2.

Details

Module Info

Vulnerability Info

This low-severity vulnerability is found in undici in versions lower than 5.26.2. 

undici can be imported independently and is also included as part of the Node.js distribution. Generally, it is best to upgrade Node.js to a version that includes the fixed version of the library rather than trying to upgrade just the undici library.

Steps To Reproduce

  • Import a vulnerable version of undici or set up an instance of a version of Node.js that contains a vulnerable version of undici.
  • Use the code below, which was taken from the test for this vulnerability that is included with the fix:
'use strict'
const { test } = require('tap')
const { createServer } = require('http')
const { once } = require('events')
const { fetch } = require('../..')

test('Cross-origin redirects clear forbidden headers', async (t) => {
  t.plan(5)
  const server1 = createServer((req, res) => {
    t.equal(req.headers.cookie, undefined)
    t.equal(req.headers.authorization, undefined)
    res.end('redirected')
  }).listen(0)
  const server2 = createServer((req, res) => {
    t.equal(req.headers.authorization, 'test')
    t.equal(req.headers.cookie, 'ddd=dddd')
    res.writeHead(302, {
      ...req.headers,
      Location: `http://localhost:${server1.address().port}`
    })
    res.end()
  }).listen(0)
  t.teardown(() => {
    server1.close()
    server2.close()
  })
  await Promise.all([
    once(server1, 'listening'),
    once(server2, 'listening')
  ])
  const res = await fetch(`http://localhost:${server2.address().port}`, {
    headers: {
      Authorization: 'test',
      Cookie: 'ddd=dddd'
    }
  })
  const text = await res.text()
  t.equal(text, 'redirected')
})

  • Note that the lines below assert that the specific headers are undefined:
t.equal(req.headers.cookie, undefined)
t.equal(req.headers.authorization, undefined)

  • On a vulnerable system, these assertions will fail because Server1 will receive the Authorization and Cookie headers.

Mitigation

undici is a popular library that was added in Node 16 (in addition to the native HTTP library). All users that use the experimental fetch() should upgrade immediately.

Additional Resources

Vulnerability Details
ID
HD-2024-1408
PROJECT Affected
Node.js
Versions Affected
16.20.2 LTS
Published date
October 15, 2024
≈ Fix date
October 11, 2023
Fixed in
Severity
Low
Category
Information Exposure