VYPR
Low severityNVD Advisory· Published Jul 20, 2022· Updated Apr 22, 2025

Uncleared cookies on cross-host/cross-origin redirect in undici

CVE-2022-31151

Description

Authorization headers are cleared on cross-origin redirect. However, cookie headers which are sensitive headers and are official headers found in the spec, remain uncleared. There are active users using cookie headers in undici. This may lead to accidental leakage of cookie to a 3rd-party site or a malicious attacker who can control the redirection target (ie. an open redirector) to leak the cookie to the 3rd party site. This was patched in v5.7.1. By default, this vulnerability is not exploitable. Do not enable redirections, i.e. maxRedirections: 0 (the default).

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
undicinpm
< 5.8.05.8.0

Affected products

1

Patches

1
0a5bee9465e6

Merge pull request from GHSA-q768-x9m6-m9qp

https://github.com/nodejs/undiciMatteo CollinaJul 18, 2022via ghsa
4 files changed · +66 3
  • lib/handler/redirect.js+2 1 modified
    @@ -186,7 +186,8 @@ function shouldRemoveHeader (header, removeContent, unknownOrigin) {
       return (
         (header.length === 4 && header.toString().toLowerCase() === 'host') ||
         (removeContent && header.toString().toLowerCase().indexOf('content-') === 0) ||
    -    (unknownOrigin && header.length === 13 && header.toString().toLowerCase() === 'authorization')
    +    (unknownOrigin && header.length === 13 && header.toString().toLowerCase() === 'authorization') ||
    +    (unknownOrigin && header.length === 6 && header.toString().toLowerCase() === 'cookie')
       )
     }
     
    
  • test/redirect-request.js+21 1 modified
    @@ -7,7 +7,8 @@ const {
       startRedirectingWithBodyServer,
       startRedirectingChainServers,
       startRedirectingWithoutLocationServer,
    -  startRedirectingWithAuthorization
    +  startRedirectingWithAuthorization,
    +  startRedirectingWithCookie
     } = require('./utils/redirecting-servers')
     const { createReadable, createReadableStream } = require('./utils/stream')
     
    @@ -489,3 +490,22 @@ t.test('removes authorization header on third party origin', async t => {
     
       t.equal(body, '')
     })
    +
    +t.test('removes cookie header on third party origin', async t => {
    +  t.plan(1)
    +
    +  const [server1] = await startRedirectingWithCookie(t, 'a=b')
    +  const { body: bodyStream } = await undici.request(`http://${server1}`, {
    +    maxRedirections: 10,
    +    headers: {
    +      cookie: 'a=b'
    +    }
    +  })
    +
    +  let body = ''
    +  for await (const b of bodyStream) {
    +    body += b
    +  }
    +
    +  t.equal(body, '')
    +})
    
  • test/redirect-stream.js+19 1 modified
    @@ -7,7 +7,8 @@ const {
       startRedirectingWithBodyServer,
       startRedirectingChainServers,
       startRedirectingWithoutLocationServer,
    -  startRedirectingWithAuthorization
    +  startRedirectingWithAuthorization,
    +  startRedirectingWithCookie
     } = require('./utils/redirecting-servers')
     const { createReadable, createWritable } = require('./utils/stream')
     
    @@ -401,3 +402,20 @@ t.test('removes authorization header on third party origin', async t => {
     
       t.equal(body.length, 0)
     })
    +
    +t.test('removes cookie header on third party origin', async t => {
    +  t.plan(1)
    +
    +  const body = []
    +
    +  const [server1] = await startRedirectingWithCookie(t, 'a=b')
    +  await stream(`http://${server1}`, {
    +    maxRedirections: 10,
    +    opaque: body,
    +    headers: {
    +      cookie: 'a=b'
    +    }
    +  }, ({ statusCode, headers, opaque }) => createWritable(opaque))
    +
    +  t.equal(body.length, 0)
    +})
    
  • test/utils/redirecting-servers.js+24 0 modified
    @@ -178,6 +178,29 @@ async function startRedirectingWithAuthorization (t, authorization) {
       return [server1, server2]
     }
     
    +async function startRedirectingWithCookie (t, cookie) {
    +  const server1 = await startServer(t, (req, res) => {
    +    if (req.headers.cookie !== cookie) {
    +      res.statusCode = 403
    +      res.setHeader('Connection', 'close')
    +      res.end('')
    +      return
    +    }
    +
    +    res.statusCode = 301
    +    res.setHeader('Connection', 'close')
    +
    +    res.setHeader('Location', `http://${server2}`)
    +    res.end('')
    +  })
    +
    +  const server2 = await startServer(t, (req, res) => {
    +    res.end(req.headers.cookie || '')
    +  })
    +
    +  return [server1, server2]
    +}
    +
     async function startRedirectingWithRelativePath (t) {
       const server = await startServer(t, (req, res) => {
         res.setHeader('Connection', 'close')
    @@ -206,5 +229,6 @@ module.exports = {
       startRedirectingWithoutLocationServer,
       startRedirectingChainServers,
       startRedirectingWithAuthorization,
    +  startRedirectingWithCookie,
       startRedirectingWithRelativePath
     }
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

11

News mentions

0

No linked articles in our index yet.