Skip to content

Update dependency undici to v6.28.0 [SECURITY] - #355

Open
transcend-renovate[bot] wants to merge 2 commits into
mainfrom
renovate/npm-undici-vulnerability
Open

Update dependency undici to v6.28.0 [SECURITY]#355
transcend-renovate[bot] wants to merge 2 commits into
mainfrom
renovate/npm-undici-vulnerability

Conversation

@transcend-renovate

@transcend-renovate transcend-renovate Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Change Age Adoption Passing Confidence
undici (source) 6.27.06.28.0 age adoption passing confidence

undici vulnerable to downstream response desynchronization via retry interceptor

CVE-2026-16728 / GHSA-8xcm-r25x-g524

More information

Details

Impact

Undici's interceptors.retry() can deliver a response whose body length does not match the Content-Length header exposed to the application after a retry or resume of a partial response. Applications that use interceptors.retry() and forward upstream response headers and bodies downstream, for example proxy or gateway applications, may emit an invalid HTTP response with a stale Content-Length header. This can lead to downstream response desynchronization, connection hangs, or response corruption in clients or intermediaries that rely on the forwarded framing metadata.

A malicious or faulty upstream can respond to a range request with a 206 Partial Content response such as:

Content-Range: bytes 0-99/300
Content-Length: 300

and then send only 99 bytes before closing the socket. interceptors.retry() can then retry with Range: bytes=99-99, receive the final byte, and deliver a 100-byte body to the application while the response headers still contain Content-Length: 300 from the first response.

The bug requires interceptors.retry() to be enabled, an upstream that returns a partial response with a mismatched framing header, and a downstream forwarder that does not remove or recalculate Content-Length.

Patches

Patched in undici v6.28.0, v7.29.0, and v8.9.0. Users should upgrade to one of these versions or later.

Workarounds
  • Disable interceptors.retry() for untrusted upstreams.
  • Remove or recalculate Content-Length before forwarding a response body assembled or transformed by Undici.

Severity

  • CVSS Score: 4.8 / 10 (Medium)
  • Vector String: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


undici vulnerable to cookie attribute injection via unsanitized domain and unparsed setCookie fields

CVE-2026-16729 / GHSA-v3r7-h72x-cjcm

More information

Details

Impact

The setCookie function has two attribute injection paths. validateCookieDomain does not reject semicolons (validateCookiePath already does at 0x3B), so a domain value like example.com; SameSite=None lands verbatim as Domain=example.com; SameSite=None. The unparsed array's loop only checks each entry contains = and does not sanitize values, so an entry like X-Custom=val; HttpOnly lands unchanged, injecting HttpOnly without the caller setting cookie.httpOnly = true.

Applications that pass user-controlled input to these fields, typically multi-tenant or reverse-proxy servers that scope session cookies to a tenant-supplied domain, can have SameSite CSRF protections bypassed, Secure or HttpOnly forced or stripped, or the intended SameSite tier overridden.

Patches

Patched in undici v6.28.0, v7.29.0, and v8.9.0.

Workarounds
  • Sanitize domain values against the RFC 1034 letter-digit-hyphen set before passing to setCookie.
  • Do not pass user-controlled data to the unparsed field.

Severity

  • CVSS Score: 4.8 / 10 (Medium)
  • Vector String: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


undici vulnerable to CRLF Injection via blob-like body 'type' property

CVE-2026-15157 / GHSA-m8rv-5g2x-5cg5

More information

Details

Impact

When an application passes a duck-typed blob-like body to undici's HTTP/1.1 dispatcher (via request(), stream(), pipeline(), or dispatch()) with a .type derived from untrusted input, an attacker can inject CRLF sequences (\r\n) to append arbitrary HTTP headers and potentially smuggle a second request past the upstream.

The vulnerable branch in lib/dispatcher/client-h1.js pushes body.type directly into the outgoing headers with no validation, while every other header path in undici goes through isValidHeaderValue():

} else if (util.isBlobLike(body) && request.contentType == null && body.type) {
  headers.push('content-type', body.type)  // bypasses isValidHeaderValue()
}

The bug requires a hand-rolled duck-typed blob object or a Blob subclass with a controlled .type. Native Blob is safe because its constructor strips CRLF from .type. fetch() is unaffected because it validates via the Headers class. Ecosystem consumers that build duck-typed blob shapes from user input include form-data-encoder, formdata-polyfill, and formdata-node.

Same defect class as CVE-2022-35948 (explicit content-type sink, fixed in undici 5.8.2) and CVE-2026-1527 (upgrade option sink, fixed in 6.24.0 / 7.24.0), both closed by adding isValidHeaderValue() on their respective sinks. This branch was missed.

Patches

Patched in undici v6.28.0, v7.29.0, and v8.9.0. Users should upgrade to one of these versions or later.

Workarounds
  • Set an explicit, validated content-type header on the request options (skips the vulnerable branch).
  • Use a native Blob (or fetch-blob) instead of a hand-rolled duck-typed object.
  • Reject control characters in the MIME type before assigning it to .type.
  • Use fetch() instead of the non-fetch APIs.

Severity

  • CVSS Score: 4.2 / 10 (Medium)
  • Vector String: CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:L/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


undici vulnerable to downstream response desynchronization via retry interceptor

CVE-2026-16728 / GHSA-8xcm-r25x-g524

More information

Details

Impact

Undici's interceptors.retry() can deliver a response whose body length does not match the Content-Length header exposed to the application after a retry or resume of a partial response. Applications that use interceptors.retry() and forward upstream response headers and bodies downstream, for example proxy or gateway applications, may emit an invalid HTTP response with a stale Content-Length header. This can lead to downstream response desynchronization, connection hangs, or response corruption in clients or intermediaries that rely on the forwarded framing metadata.

A malicious or faulty upstream can respond to a range request with a 206 Partial Content response such as:

Content-Range: bytes 0-99/300
Content-Length: 300

and then send only 99 bytes before closing the socket. interceptors.retry() can then retry with Range: bytes=99-99, receive the final byte, and deliver a 100-byte body to the application while the response headers still contain Content-Length: 300 from the first response.

The bug requires interceptors.retry() to be enabled, an upstream that returns a partial response with a mismatched framing header, and a downstream forwarder that does not remove or recalculate Content-Length.

Patches

Patched in undici v6.28.0, v7.29.0, and v8.9.0. Users should upgrade to one of these versions or later.

Workarounds
  • Disable interceptors.retry() for untrusted upstreams.
  • Remove or recalculate Content-Length before forwarding a response body assembled or transformed by Undici.

Severity

  • CVSS Score: 4.8 / 10 (Medium)
  • Vector String: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N

References

This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).


undici vulnerable to CRLF Injection via blob-like body 'type' property

CVE-2026-15157 / GHSA-m8rv-5g2x-5cg5

More information

Details

Impact

When an application passes a duck-typed blob-like body to undici's HTTP/1.1 dispatcher (via request(), stream(), pipeline(), or dispatch()) with a .type derived from untrusted input, an attacker can inject CRLF sequences (\r\n) to append arbitrary HTTP headers and potentially smuggle a second request past the upstream.

The vulnerable branch in lib/dispatcher/client-h1.js pushes body.type directly into the outgoing headers with no validation, while every other header path in undici goes through isValidHeaderValue():

} else if (util.isBlobLike(body) && request.contentType == null && body.type) {
  headers.push('content-type', body.type)  // bypasses isValidHeaderValue()
}

The bug requires a hand-rolled duck-typed blob object or a Blob subclass with a controlled .type. Native Blob is safe because its constructor strips CRLF from .type. fetch() is unaffected because it validates via the Headers class. Ecosystem consumers that build duck-typed blob shapes from user input include form-data-encoder, formdata-polyfill, and formdata-node.

Same defect class as CVE-2022-35948 (explicit content-type sink, fixed in undici 5.8.2) and CVE-2026-1527 (upgrade option sink, fixed in 6.24.0 / 7.24.0), both closed by adding isValidHeaderValue() on their respective sinks. This branch was missed.

Patches

Patched in undici v6.28.0, v7.29.0, and v8.9.0. Users should upgrade to one of these versions or later.

Workarounds
  • Set an explicit, validated content-type header on the request options (skips the vulnerable branch).
  • Use a native Blob (or fetch-blob) instead of a hand-rolled duck-typed object.
  • Reject control characters in the MIME type before assigning it to .type.
  • Use fetch() instead of the non-fetch APIs.

Severity

  • CVSS Score: 4.2 / 10 (Medium)
  • Vector String: CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:L/A:N

References

This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).


undici vulnerable to cookie attribute injection via unsanitized domain and unparsed setCookie fields

CVE-2026-16729 / GHSA-v3r7-h72x-cjcm

More information

Details

Impact

The setCookie function has two attribute injection paths. validateCookieDomain does not reject semicolons (validateCookiePath already does at 0x3B), so a domain value like example.com; SameSite=None lands verbatim as Domain=example.com; SameSite=None. The unparsed array's loop only checks each entry contains = and does not sanitize values, so an entry like X-Custom=val; HttpOnly lands unchanged, injecting HttpOnly without the caller setting cookie.httpOnly = true.

Applications that pass user-controlled input to these fields, typically multi-tenant or reverse-proxy servers that scope session cookies to a tenant-supplied domain, can have SameSite CSRF protections bypassed, Secure or HttpOnly forced or stripped, or the intended SameSite tier overridden.

Patches

Patched in undici v6.28.0, v7.29.0, and v8.9.0.

Workarounds
  • Sanitize domain values against the RFC 1034 letter-digit-hyphen set before passing to setCookie.
  • Do not pass user-controlled data to the unparsed field.

Severity

  • CVSS Score: 4.8 / 10 (Medium)
  • Vector String: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N

References

This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).


Release Notes

nodejs/undici (undici)

v6.28.0

Compare Source

⚠️ Security fixes

  • GHSA-m8rv-5g2x-5cg5: a malicious type property on a duck-typed blob-like HTTP/1.1 request body could inject CRLF sequences into the generated content-type header. Undici now coerces and validates the value before adding it to the request. Fixed by 740a0b7c.
  • GHSA-8xcm-r25x-g524: the retry interceptor could expose a stale Content-Length after resuming a partial response, potentially causing downstream response desynchronization, hangs, or corruption. Undici now rejects partial responses whose Content-Length is inconsistent with Content-Range. Fixed by cba3a52a, with corrected fixtures in 4fd5a0c6.
  • GHSA-v3r7-h72x-cjcm: unsanitized domain and unparsed values passed to setCookie() could inject cookie attributes. Undici now validates cookie domains, paths, and unparsed attributes more strictly. Fixed by af748404.

GHSA-4cwx-7wf7-3272 and GHSA-jr45-8vmc-qm54 affect the cache interceptor in Undici v7 and v8; Undici v6 is not in their affected version ranges.

Full Changelog: nodejs/undici@v6.27.0...v6.28.0


Configuration

📅 Schedule: (in timezone America/Los_Angeles)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR has been generated by Mend Renovate.

@pkg-pr-new

pkg-pr-new Bot commented Aug 4, 2026

Copy link
Copy Markdown

Open in StackBlitz

@transcend-io/airgap.js-types

pnpm add https://pkg.pr.new/@transcend-io/airgap.js-types@355
yarn add https://pkg.pr.new/@transcend-io/airgap.js-types@355.tgz

@transcend-io/cli

pnpm add https://pkg.pr.new/@transcend-io/cli@355
yarn add https://pkg.pr.new/@transcend-io/cli@355.tgz

@transcend-io/design-tokens

pnpm add https://pkg.pr.new/@transcend-io/design-tokens@355
yarn add https://pkg.pr.new/@transcend-io/design-tokens@355.tgz

@transcend-io/internationalization

pnpm add https://pkg.pr.new/@transcend-io/internationalization@355
yarn add https://pkg.pr.new/@transcend-io/internationalization@355.tgz

@transcend-io/privacy-types

pnpm add https://pkg.pr.new/@transcend-io/privacy-types@355
yarn add https://pkg.pr.new/@transcend-io/privacy-types@355.tgz

@transcend-io/sdk

pnpm add https://pkg.pr.new/@transcend-io/sdk@355
yarn add https://pkg.pr.new/@transcend-io/sdk@355.tgz

@transcend-io/type-utils

pnpm add https://pkg.pr.new/@transcend-io/type-utils@355
yarn add https://pkg.pr.new/@transcend-io/type-utils@355.tgz

@transcend-io/utils

pnpm add https://pkg.pr.new/@transcend-io/utils@355
yarn add https://pkg.pr.new/@transcend-io/utils@355.tgz

@transcend-io/mcp

pnpm add https://pkg.pr.new/@transcend-io/mcp@355
yarn add https://pkg.pr.new/@transcend-io/mcp@355.tgz

@transcend-io/mcp-server-admin

pnpm add https://pkg.pr.new/@transcend-io/mcp-server-admin@355
yarn add https://pkg.pr.new/@transcend-io/mcp-server-admin@355.tgz

@transcend-io/mcp-server-assessment

pnpm add https://pkg.pr.new/@transcend-io/mcp-server-assessment@355
yarn add https://pkg.pr.new/@transcend-io/mcp-server-assessment@355.tgz

@transcend-io/mcp-server-base

pnpm add https://pkg.pr.new/@transcend-io/mcp-server-base@355
yarn add https://pkg.pr.new/@transcend-io/mcp-server-base@355.tgz

@transcend-io/mcp-server-consent

pnpm add https://pkg.pr.new/@transcend-io/mcp-server-consent@355
yarn add https://pkg.pr.new/@transcend-io/mcp-server-consent@355.tgz

@transcend-io/mcp-server-discovery

pnpm add https://pkg.pr.new/@transcend-io/mcp-server-discovery@355
yarn add https://pkg.pr.new/@transcend-io/mcp-server-discovery@355.tgz

@transcend-io/mcp-server-docs

pnpm add https://pkg.pr.new/@transcend-io/mcp-server-docs@355
yarn add https://pkg.pr.new/@transcend-io/mcp-server-docs@355.tgz

@transcend-io/mcp-server-dsr

pnpm add https://pkg.pr.new/@transcend-io/mcp-server-dsr@355
yarn add https://pkg.pr.new/@transcend-io/mcp-server-dsr@355.tgz

@transcend-io/mcp-server-inventory

pnpm add https://pkg.pr.new/@transcend-io/mcp-server-inventory@355
yarn add https://pkg.pr.new/@transcend-io/mcp-server-inventory@355.tgz

@transcend-io/mcp-server-preferences

pnpm add https://pkg.pr.new/@transcend-io/mcp-server-preferences@355
yarn add https://pkg.pr.new/@transcend-io/mcp-server-preferences@355.tgz

@transcend-io/mcp-server-workflows

pnpm add https://pkg.pr.new/@transcend-io/mcp-server-workflows@355
yarn add https://pkg.pr.new/@transcend-io/mcp-server-workflows@355.tgz

commit: 09b15fd

@htunnicliff

Copy link
Copy Markdown
Member

@cursor add a changeset

htunnicliff
htunnicliff previously approved these changes Aug 6, 2026
@cursor

cursor Bot commented Aug 6, 2026

Copy link
Copy Markdown

Added a changeset and pushed it to the branch.

  • Created .changeset/undici-6-28-0-security.md marking @transcend-io/cli as a patch, since the only publishable change is the undici bump from 6.27.0 to 6.28.0 in packages/cli/package.json. The body names the three CVEs the release closes (CRLF injection via a blob-like body's type, retry-interceptor response desynchronisation, and cookie attribute injection via setCookie).
  • Verified locally that pnpm check:changeset now passes — it previously flagged @transcend-io/cli as uncovered, which was the CI failure. The pre-commit and pre-push hooks both ran green, though I did have to install shellcheck and switch to Node 22.22 in this environment for the tooling to run at all.

I left the Renovate-authored PR title and description untouched.

Open in Web Open in Cursor 

@cursor
cursor Bot requested a review from a team as a code owner August 6, 2026 18:55
@htunnicliff
htunnicliff enabled auto-merge August 6, 2026 18:57
@transcend-renovate

Copy link
Copy Markdown
Contributor Author

Edited/Blocked Notification

Renovate will not automatically rebase this PR, because it does not recognize the last commit author and assumes somebody else may have edited the PR.

You can manually request rebase by checking the rebase/retry box above.

⚠️ Warning: custom changes will be lost.

@htunnicliff
htunnicliff disabled auto-merge August 6, 2026 19:50
@htunnicliff
htunnicliff enabled auto-merge August 6, 2026 19:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants