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

CVE-2020-15366

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.

PackageAffected versionsPatched versions
ajvnpm
< 6.12.36.12.3

Affected products

4

Patches

1
65b2f7d76b19

validate numbers in schemas during schema compilation

https://github.com/ajv-validator/ajvEvgeny PoberezkinJun 30, 2020via ghsa
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

News mentions

0

No linked articles in our index yet.