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.
| Package | Affected versions | Patched versions |
|---|---|---|
fastifynpm | < 2.15.1 | 2.15.1 |
Affected products
2- Fastify/Fastifydescription
Patches
174c3157ca90cDisable allErrors in default Ajv config.
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- github.com/advisories/GHSA-xw5p-hw6r-2j98ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2020-8192ghsaADVISORY
- github.com/fastify/fastify/commit/74c3157ca90c3ffed9e4434f63c2017471ec970eghsaWEB
- hackerone.com/reports/903521ghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.