CVE-2020-15366
Description
An issue was discovered in ajv.validate() in Ajv (aka Another JSON Schema Validator) 6.12.2. A carefully crafted JSON schema could be provided that allows execution of other code by prototype pollution. (While untrusted schemas are recommended against, the worst case of an untrusted schema should be a denial of service, not execution of code.)
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
CVE-2020-15366 is a prototype pollution vulnerability in Ajv 6.12.2 that allows code execution via a crafted JSON schema, exceeding the expected denial-of-service impact.
Vulnerability
Overview
CVE-2020-15366 is a prototype pollution vulnerability discovered in the ajv.validate() function of Ajv (Another JSON Schema Validator) version 6.12.2 [1]. The root cause lies in insufficient sanitization of JSON schema inputs, allowing a carefully crafted schema to inject properties into the JavaScript object prototype. While the project recommends against using untrusted schemas, the typical expectation is that such inputs would only lead to a denial of service, not arbitrary code execution [1].
Attack
Vector and Prerequisites
An attacker can exploit this flaw by providing a malicious JSON schema to an application that uses Ajv validate(). The attack does not require authentication if the application accepts user-supplied schemas. Successful exploitation leverages prototype pollution, a technique where the attacker modifies the prototype of base objects (e.g., Object.prototype), which can then affect runtime behavior and potentially lead to arbitrary code execution [1].
Impact
A successful attack could allow an adversary to execute arbitrary code within the context of the vulnerable application. This goes beyond the expected denial-of-service scenario and could lead to full compromise of the application and its data. The vulnerability was present in Ajv version 6.12.2 [1].
Mitigation
The Ajv project released version 6.12.3 to address this vulnerability [4]. Users are strongly advised to upgrade to version 6.12.3 or later. As a general security best practice, schemas from untrusted sources should not be validated [1].
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 |
|---|---|---|
ajvnpm | < 6.12.3 | 6.12.3 |
Affected products
4- ajv/ajvdescription
- ghsa-coords3 versions
< 6.12.3+ 2 more
- (no CPE)range: < 6.12.3
- (no CPE)range: < 1.18.3-1.module_el8.3.0+2023+d2377ea3
- (no CPE)range: < 17-3.module_el8.4.0+2224+b07ac28e
Patches
165b2f7d76b19validate numbers in schemas during schema compilation
6 files changed · +66 −0
lib/dot/definitions.def+7 −0 modified@@ -138,6 +138,13 @@ #}} +{{## def.numberKeyword: + {{? !($isData || typeof $schema == 'number') }} + {{ throw new Error($keyword + ' must be number'); }} + {{?}} +#}} + + {{## def.beginDefOut: {{ var $$outStack = $$outStack || [];
lib/dot/_limitItems.jst+2 −0 modified@@ -3,6 +3,8 @@ {{# def.setupKeyword }} {{# def.$data }} +{{# def.numberKeyword }} + {{ var $op = $keyword == 'maxItems' ? '>' : '<'; }} if ({{# def.$dataNotType:'number' }} {{=$data}}.length {{=$op}} {{=$schemaValue}}) { {{ var $errorKeyword = $keyword; }}
lib/dot/_limit.jst+9 −0 modified@@ -17,6 +17,15 @@ , $op = $isMax ? '<' : '>' , $notOp = $isMax ? '>' : '<' , $errorKeyword = undefined; + + if (!($isData || typeof $schema == 'number' || $schema === undefined)) { + throw new Error($keyword + ' must be number'); + } + if (!($isDataExcl || $schemaExcl === undefined + || typeof $schemaExcl == 'number' + || typeof $schemaExcl == 'boolean')) { + throw new Error($exclusiveKeyword + ' must be number or boolean'); + } }} {{? $isDataExcl }}
lib/dot/_limitLength.jst+2 −0 modified@@ -3,6 +3,8 @@ {{# def.setupKeyword }} {{# def.$data }} +{{# def.numberKeyword }} + {{ var $op = $keyword == 'maxLength' ? '>' : '<'; }} if ({{# def.$dataNotType:'number' }} {{# def.strLength }} {{=$op}} {{=$schemaValue}}) { {{ var $errorKeyword = $keyword; }}
lib/dot/_limitProperties.jst+2 −0 modified@@ -3,6 +3,8 @@ {{# def.setupKeyword }} {{# def.$data }} +{{# def.numberKeyword }} + {{ var $op = $keyword == 'maxProperties' ? '>' : '<'; }} if ({{# def.$dataNotType:'number' }} Object.keys({{=$data}}).length {{=$op}} {{=$schemaValue}}) { {{ var $errorKeyword = $keyword; }}
spec/ajv.spec.js+44 −0 modified@@ -512,5 +512,49 @@ describe('Ajv', function () { }); }); }); + + describe('sub-schema validation outside of definitions during compilation', function() { + it('maximum', function() { + passValidationThrowCompile({ + $ref: '#/foo', + foo: {maximum: 'bar'} + }); + }); + + it('exclusiveMaximum', function() { + passValidationThrowCompile({ + $ref: '#/foo', + foo: {exclusiveMaximum: 'bar'} + }); + }); + + it('maxItems', function() { + passValidationThrowCompile({ + $ref: '#/foo', + foo: {maxItems: 'bar'} + }); + }); + + it('maxLength', function() { + passValidationThrowCompile({ + $ref: '#/foo', + foo: {maxLength: 'bar'} + }); + }); + + it('maxProperties', function() { + passValidationThrowCompile({ + $ref: '#/foo', + foo: {maxProperties: 'bar'} + }); + }); + + function passValidationThrowCompile(schema) { + ajv.validateSchema(schema) .should.equal(true); + should.throw(function() { + ajv.compile(schema); + }); + } + }); }); });
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
7- github.com/advisories/GHSA-v88g-cgmw-v5xwghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2020-15366ghsaADVISORY
- github.com/ajv-validator/ajv/commit/65b2f7d76b190ac63a0d4e9154c712d7aa37049fghsaWEB
- github.com/ajv-validator/ajv/releases/tag/v6.12.3ghsaWEB
- hackerone.com/bugsghsaWEB
- security.netapp.com/advisory/ntap-20240621-0007ghsaWEB
- security.netapp.com/advisory/ntap-20240621-0007/mitre
News mentions
0No linked articles in our index yet.