Skip to content

Commit ef8edea

Browse files
fix(deps): update dependency fastify to v5.8.5 [security] (#8157)
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [fastify](https://fastify.dev/) ([source](https://redirect.github.com/fastify/fastify)) | [`5.8.3` → `5.8.5`](https://renovatebot.com/diffs/npm/fastify/5.8.3/5.8.5) | ![age](https://developer.mend.io/api/mc/badges/age/npm/fastify/5.8.5?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/fastify/5.8.3/5.8.5?slim=true) | ### GitHub Vulnerability Alerts #### [CVE-2026-33806](https://redirect.github.com/fastify/fastify/security/advisories/GHSA-247c-9743-5963) ### 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`](https://redirect.github.com/fastify/fastify/commit/f3d2bcb3963cd570a582e5d39aab01a9ae692fe4) (fix for [CVE-2025-32442](https://redirect.github.com/fastify/fastify/security/advisories/GHSA-mg2h-6x62-wpwc)). ### 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: ```js 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: ```js 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`](https://redirect.github.com/fastify/fastify/commit/f3d2bcb3963cd570a582e5d39aab01a9ae692fe4) (April 18, 2025) changed the split delimiter from `';'` to `/[ ;]/` to fix [CVE-2025-32442](https://redirect.github.com/fastify/fastify/security/advisories/GHSA-mg2h-6x62-wpwc). 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 ```js 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 <code>schema.body.content</code> (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`: ```js 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` --- ### Release Notes <details> <summary>fastify/fastify (fastify)</summary> ### [`v5.8.5`](https://redirect.github.com/fastify/fastify/releases/tag/v5.8.5) [Compare Source](https://redirect.github.com/fastify/fastify/compare/v5.8.4...v5.8.5) #### ⚠️ Security Release This fixes CVE CVE-2026-33806 <GHSA-247c-9743-5963>. #### What's Changed - chore: Fix port parsing by [@&#8203;jsumners](https://redirect.github.com/jsumners) in [#&#8203;6603](https://redirect.github.com/fastify/fastify/pull/6603) - chore: upgrade to typescript v6.0.2 by [@&#8203;Tony133](https://redirect.github.com/Tony133) in [#&#8203;6605](https://redirect.github.com/fastify/fastify/pull/6605) - fix: restore trustProxy function for number and string types, add null check for socketAddr by [@&#8203;mcollina](https://redirect.github.com/mcollina) in [#&#8203;6613](https://redirect.github.com/fastify/fastify/pull/6613) - ci: reduce cron scheduled workflows from daily/weekly to monthly by [@&#8203;Fdawgs](https://redirect.github.com/Fdawgs) in [#&#8203;6623](https://redirect.github.com/fastify/fastify/pull/6623) - chore: Bump pnpm/action-setup from 4.2.0 to 5.0.0 by [@&#8203;dependabot](https://redirect.github.com/dependabot)\[bot] in [#&#8203;6629](https://redirect.github.com/fastify/fastify/pull/6629) - chore: Bump markdownlint-cli2 from 0.21.0 to 0.22.0 by [@&#8203;dependabot](https://redirect.github.com/dependabot)\[bot] in [#&#8203;6632](https://redirect.github.com/fastify/fastify/pull/6632) - chore: Bump borp from 0.21.0 to 1.0.0 by [@&#8203;dependabot](https://redirect.github.com/dependabot)\[bot] in [#&#8203;6633](https://redirect.github.com/fastify/fastify/pull/6633) - chore: Bump actions/dependency-review-action from 4.8.3 to 4.9.0 by [@&#8203;dependabot](https://redirect.github.com/dependabot)\[bot] in [#&#8203;6630](https://redirect.github.com/fastify/fastify/pull/6630) - docs(ecosystem): add [@&#8203;pompelmi/fastify-plugin](https://redirect.github.com/pompelmi/fastify-plugin) by [@&#8203;SonoTommy](https://redirect.github.com/SonoTommy) in [#&#8203;6610](https://redirect.github.com/fastify/fastify/pull/6610) #### New Contributors - [@&#8203;SonoTommy](https://redirect.github.com/SonoTommy) made their first contribution in [#&#8203;6610](https://redirect.github.com/fastify/fastify/pull/6610) **Full Changelog**: <fastify/fastify@v5.8.4...v5.8.5> ### [`v5.8.4`](https://redirect.github.com/fastify/fastify/releases/tag/v5.8.4) [Compare Source](https://redirect.github.com/fastify/fastify/compare/v5.8.3...v5.8.4) **Full Changelog**: <fastify/fastify@v5.8.3...v5.8.4> </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - "" - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Enabled. ♻ **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. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/netlify/cli). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMjAuMiIsInVwZGF0ZWRJblZlciI6IjQzLjEyMC4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiLCJqYXZhc2NyaXB0Il19--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
1 parent 89249d0 commit ef8edea

File tree

2 files changed

+5
-5
lines changed

2 files changed

+5
-5
lines changed

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@
103103
"express-logging": "1.1.1",
104104
"extract-zip": "2.0.1",
105105
"fastest-levenshtein": "1.0.16",
106-
"fastify": "5.8.3",
106+
"fastify": "5.8.5",
107107
"find-up": "8.0.0",
108108
"folder-walker": "3.2.0",
109109
"fuzzy": "0.1.3",

0 commit comments

Comments
 (0)