VYPR
High severity7.5NVD Advisory· Published Apr 15, 2026· Updated Apr 17, 2026

CVE-2026-33806

CVE-2026-33806

Description

Impact:

Fastify applications using schema.body.content for per-content-type body validation can have validation bypassed entirely by prepending a space to the Content-Type header. The body is still parsed correctly but schema validation is skipped.

This is a regression introduced in fastify >= 5.3.2 by the fix for CVE-2025-32442

Patches:

Upgrade to fastify v5.8.5 or later.

Workarounds:

None. Upgrade to the patched version.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
fastifynpm
>= 5.3.2, < 5.8.55.8.5

Affected products

1
  • cpe:2.3:a:fastify:fastify:*:*:*:*:*:node.js:*:*
    Range: >=5.3.2,<5.8.5

Patches

1
f3d2bcb3963c

fix: treat space as a delimiter in content-type parsing (#6064)

https://github.com/fastify/fastifyMatteo CollinaApr 18, 2025via ghsa
2 files changed · +32 16
  • lib/validation.js+1 1 modified
    @@ -261,7 +261,7 @@ function wrapValidationError (result, dataVar, schemaErrorFormatter) {
      */
     function getEssenceMediaType (header) {
       if (!header) return ''
    -  return header.split(';', 1)[0].trim().toLowerCase()
    +  return header.split(/[ ;]/, 1)[0].trim().toLowerCase()
     }
     
     module.exports = {
    
  • test/schema-validation.test.js+31 15 modified
    @@ -2,6 +2,7 @@
     
     const { test } = require('tap')
     const Fastify = require('..')
    +const { request } = require('undici')
     
     const AJV = require('ajv')
     const Schema = require('fluent-json-schema')
    @@ -1342,7 +1343,7 @@ test('Schema validation when no content type is provided', async t => {
     })
     
     test('Schema validation will not be bypass by different content type', async t => {
    -  t.plan(8)
    +  t.plan(10)
     
       const fastify = Fastify()
     
    @@ -1365,58 +1366,73 @@ test('Schema validation will not be bypass by different content type', async t =
         }
       }, async () => 'ok')
     
    -  await fastify.ready()
    +  await fastify.listen({ port: 0 })
    +  t.teardown(() => fastify.close())
    +  const address = fastify.listeningOrigin
     
    -  const correct1 = await fastify.inject({
    +  const correct1 = await request(address, {
         method: 'POST',
         url: '/',
         headers: {
           'content-type': 'application/json'
         },
    -    body: { foo: 'string' }
    +    body: JSON.stringify({ foo: 'string' })
       })
       t.equal(correct1.statusCode, 200)
    +  await correct1.body.dump()
     
    -  const correct2 = await fastify.inject({
    +  const correct2 = await request(address, {
         method: 'POST',
         url: '/',
         headers: {
           'content-type': 'application/json; charset=utf-8'
         },
    -    body: { foo: 'string' }
    +    body: JSON.stringify({ foo: 'string' })
       })
       t.equal(correct2.statusCode, 200)
    +  await correct2.body.dump()
     
    -  const invalid1 = await fastify.inject({
    +  const invalid1 = await request(address, {
         method: 'POST',
         url: '/',
         headers: {
           'content-type': 'application/json ;'
         },
    -    body: { invalid: 'string' }
    +    body: JSON.stringify({ invalid: 'string' })
       })
       t.equal(invalid1.statusCode, 400)
    -  t.equal(invalid1.json().code, 'FST_ERR_VALIDATION')
    +  t.equal((await invalid1.body.json()).code, 'FST_ERR_VALIDATION')
     
    -  const invalid2 = await fastify.inject({
    +  const invalid2 = await request(address, {
         method: 'POST',
         url: '/',
         headers: {
           'content-type': 'ApPlIcAtIoN/JsOn;'
         },
    -    body: { invalid: 'string' }
    +    body: JSON.stringify({ invalid: 'string' })
       })
       t.equal(invalid2.statusCode, 400)
    -  t.equal(invalid2.json().code, 'FST_ERR_VALIDATION')
    +  t.equal((await invalid2.body.json()).code, 'FST_ERR_VALIDATION')
     
    -  const invalid3 = await fastify.inject({
    +  const invalid3 = await request(address, {
         method: 'POST',
         url: '/',
         headers: {
           'content-type': 'ApPlIcAtIoN/JsOn ;'
         },
    -    body: { invalid: 'string' }
    +    body: JSON.stringify({ invalid: 'string' })
       })
       t.equal(invalid3.statusCode, 400)
    -  t.equal(invalid3.json().code, 'FST_ERR_VALIDATION')
    +  t.equal((await invalid3.body.json()).code, 'FST_ERR_VALIDATION')
    +
    +  const invalid4 = await request(address, {
    +    method: 'POST',
    +    url: '/',
    +    headers: {
    +      'content-type': 'ApPlIcAtIoN/JsOn foo;'
    +    },
    +    body: JSON.stringify({ invalid: 'string' })
    +  })
    +  t.equal(invalid4.statusCode, 400)
    +  t.equal((await invalid4.body.json()).code, 'FST_ERR_VALIDATION')
     })
    

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

8

News mentions

0

No linked articles in our index yet.