VYPR
Moderate severityNVD Advisory· Published Jul 30, 2020· Updated Aug 4, 2024

CVE-2020-8192

CVE-2020-8192

Description

A denial of service vulnerability exists in Fastify v2.14.1 and v3.0.0-rc.4 that allows a malicious user to trigger resource exhaustion (when the allErrors option is used) with specially crafted schemas.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Fastify v2.14.1 and v3.0.0-rc.4 are vulnerable to denial of service via resource exhaustion when the allErrors option is enabled, triggered by specially crafted schemas.

Vulnerability

Overview

CVE-2020-8192 is a denial of service (DoS) vulnerability in the Fastify web framework, specifically affecting versions v2.14.1 and v3.0.0-rc.4. The issue lies in the default configuration of Ajv, the JSON schema validator used by Fastify. When the allErrors option is enabled, the framework collects all validation errors for a given payload instead of stopping at the first. An attacker can craft a schema that triggers the generation of an excessive number of validation errors, leading to resource exhaustion [1].

Attack

Vector and Prerequisites

To exploit this vulnerability, an attacker does not need authentication but must be able to send requests to a Fastify server that uses schema validation with the allErrors option. The attacker provides a specially crafted JSON payload that fails multiple schema constraints, causing Ajv to generate a long list of error messages. This consumes CPU and memory as the server processes and stores each error [2].

Impact

Successful exploitation results in a denial of service condition, where the Fastify server becomes unresponsive or crashes due to resource exhaustion. This can impact availability of the service for legitimate users.

Mitigation

The vulnerability is patched in later versions of Fastify. The commit at [2] disables the allErrors option in the default Ajv configuration, so that validation stops at the first error. Users are advised to update to a patched version. If updating is not immediately possible, a mitigation is to set the allErrors option to false in the server's schema validator configuration.

AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
fastifynpm
< 2.15.12.15.1

Affected products

2

Patches

1
74c3157ca90c

Disable allErrors in default Ajv config.

https://github.com/fastify/fastifyMatteo CollinaJun 29, 2020via ghsa
3 files changed · +11 22
  • docs/Validation-and-Serialization.md+2 8 modified
    @@ -338,7 +338,6 @@ Fastify's [baseline ajv configuration](https://github.com/epoberezkin/ajv#option
       removeAdditional: true, // remove additional properties
       useDefaults: true, // replace missing properties and items with the values from corresponding default keyword
       coerceTypes: true, // change data type of data to match type keyword
    -  allErrors: true,   // check for all errors
       nullable: true     // support keyword "nullable" from Open API 3 specification.
     }
     ```
    @@ -355,7 +354,6 @@ const ajv = new Ajv({
       removeAdditional: true,
       useDefaults: true,
       coerceTypes: true,
    -  allErrors: true,
       nullable: true,
       // any other options
       // ...
    @@ -666,7 +664,7 @@ Inline comments in the schema below describe how to configure it to show a diffe
     ```js
     const fastify = Fastify({
       ajv: {
    -    customOptions: { allErrors: true, jsonPointers: true },
    +    customOptions: { jsonPointers: true },
         plugins: [
           require('ajv-errors')
         ]
    @@ -713,11 +711,7 @@ If you want to return localized error messages, take a look at [ajv-i18n](https:
     ```js
     const localize = require('ajv-i18n')
     
    -const fastify = Fastify({
    -  ajv: {
    -    customOptions: { allErrors: true }
    -  }
    -})
    +const fastify = Fastify()
     
     const schema = {
       body: {
    
  • lib/validation.js+3 1 modified
    @@ -171,7 +171,9 @@ function buildSchemaCompiler (externalSchemas, options, cache) {
         coerceTypes: true,
         useDefaults: true,
         removeAdditional: true,
    -    allErrors: true,
    +    // Explicitly set allErrors to `false`.
    +    // When set to `true`, a DoS attack is possible.
    +    allErrors: false,
         nullable: true
       }, options.customOptions, { cache }))
     
    
  • test/validation-error-handling.test.js+6 13 modified
    @@ -57,10 +57,10 @@ test('should fail immediately with invalid payload', t => {
         url: '/'
       }, (err, res) => {
         t.error(err)
    -    t.deepEqual(JSON.parse(res.payload), {
    +    t.deepEqual(res.json(), {
           statusCode: 400,
           error: 'Bad Request',
    -      message: "body should have required property 'name', body should have required property 'work'"
    +      message: "body should have required property 'name'"
         })
         t.strictEqual(res.statusCode, 400)
       })
    @@ -216,19 +216,12 @@ test('should be able to attach validation to request', t => {
       }, (err, res) => {
         t.error(err)
     
    -    t.deepEqual(JSON.parse(res.payload), [{
    +    t.deepEqual(res.json(), [{
           keyword: 'required',
           dataPath: '',
           schemaPath: '#/required',
           params: { missingProperty: 'name' },
           message: 'should have required property \'name\''
    -    },
    -    {
    -      keyword: 'required',
    -      dataPath: '',
    -      schemaPath: '#/required',
    -      params: { missingProperty: 'work' },
    -      message: 'should have required property \'work\''
         }])
         t.strictEqual(res.statusCode, 400)
       })
    @@ -255,7 +248,7 @@ test('should respect when attachValidation is explicitly set to false', t => {
         t.deepEqual(JSON.parse(res.payload), {
           statusCode: 400,
           error: 'Bad Request',
    -      message: "body should have required property 'name', body should have required property 'work'"
    +      message: "body should have required property 'name'"
         })
         t.strictEqual(res.statusCode, 400)
       })
    @@ -285,7 +278,7 @@ test('Attached validation error should take precendence over setErrorHandler', t
         url: '/'
       }, (err, res) => {
         t.error(err)
    -    t.deepEqual(res.payload, "Attached: Error: body should have required property 'name', body should have required property 'work'")
    +    t.deepEqual(res.payload, "Attached: Error: body should have required property 'name'")
         t.strictEqual(res.statusCode, 400)
       })
     })
    @@ -378,7 +371,7 @@ test('should return a defined output message parsing AJV errors', t => {
         url: '/'
       }, (err, res) => {
         t.error(err)
    -    t.strictEqual(res.payload, '{"statusCode":400,"error":"Bad Request","message":"body should have required property \'name\', body should have required property \'work\'"}')
    +    t.strictEqual(res.payload, '{"statusCode":400,"error":"Bad Request","message":"body should have required property \'name\'"}')
       })
     })
     
    

Vulnerability mechanics

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

References

4

News mentions

0

No linked articles in our index yet.