VYPR
High severityNVD Advisory· Published Sep 23, 2022· Updated May 27, 2025

CVE-2020-36604

CVE-2020-36604

Description

hoek before 8.5.1 and 9.x before 9.0.3 allows prototype poisoning in the clone function.

AI Insight

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

hoek before 8.5.1 and 9.x before 9.0.3 allows prototype pollution via the clone() function when processing objects with a __proto__ key.

Root

Cause CVE-2020-36604 is a prototype pollution vulnerability in the hapi.js hoek utility library, affecting versions before 8.5.1 and 9.x before 9.0.3. The clone() function fails to filter out the __proto__ key when iterating over object properties during a deep clone operation. This allows an attacker-controlled object containing a __proto__ key to pollute the global object prototype, as demonstrated in the fix commit which adds a check to skip the __proto__ key [2][3].

Exploitation

This vulnerability is considered low risk and hard to exploit in typical scenarios [4]. It is not exploitable when clone() is used within hapi request handlers because hapi ensures no invalid objects can reach the clone function from user input [4]. However, if an application directly passes user-controlled JSON to hoek.clone() without sanitization, an attacker could craft a payload such as {"__proto__": {"x": 1}} to inject properties into the prototype chain [2]. The attack requires the attacker to control the object passed to the clone function.

Impact

Successful exploitation can lead to prototype pollution, allowing an attacker to modify properties inherited by all objects. This can potentially affect application logic, bypass security checks, or cause denial of service. The impact is context-dependent and less severe than typical prototype pollution vulnerabilities due to the limited conditions required for exploitation [4].

Mitigation

The issue was fixed in hoek versions 8.5.1 and 9.0.3 by adding a conditional check that skips the __proto__ key during cloning [2][3]. Users should upgrade to the latest patched versions. There is no known workaround other than avoiding direct use of hoek.clone() with untrusted input.

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
@hapi/hoeknpm
< 8.5.18.5.1
@hapi/hoeknpm
>= 9.0.0, < 9.0.39.0.3
hoeknpm
<= 6.1.3

Affected products

51

Patches

4
5bd73f642b0e

8.5.1

https://github.com/hapijs/hoekEran HammerFeb 8, 2020via osv
1 file changed · +1 1
  • package.json+1 1 modified
    @@ -1,7 +1,7 @@
     {
         "name": "@hapi/hoek",
         "description": "General purpose node utilities",
    -    "version": "8.5.0",
    +    "version": "8.5.1",
         "repository": "git://github.com/hapijs/hoek",
         "main": "lib/index.js",
         "types": "lib/index.d.ts",
    
8bf7635550d3

9.0.3

https://github.com/hapijs/hoekEran HammerFeb 8, 2020via osv
1 file changed · +1 1
  • package.json+1 1 modified
    @@ -1,7 +1,7 @@
     {
         "name": "@hapi/hoek",
         "description": "General purpose node utilities",
    -    "version": "9.0.2",
    +    "version": "9.0.3",
         "repository": "git://github.com/hapijs/hoek",
         "main": "lib/index.js",
         "types": "lib/index.d.ts",
    
4d0804bc6135

Backport #352. Closes #353

https://github.com/hapijs/hoekEran HammerFeb 8, 2020via ghsa
2 files changed · +13 0
  • lib/clone.js+4 0 modified
    @@ -75,6 +75,10 @@ module.exports = internals.clone = function (obj, options = {}, _seen = null) {
     
         const keys = Utils.keys(obj, options);
         for (const key of keys) {
    +        if (key === '__proto__') {
    +            continue;
    +        }
    +
             if (baseProto === Types.array &&
                 key === 'length') {
     
    
  • test/index.js+9 0 modified
    @@ -762,6 +762,15 @@ describe('clone()', () => {
             expect(copy.a).to.shallow.equal(obj.a);
             expect(copy.x).to.shallow.equal(obj);
         });
    +
    +    it('prevents prototype poisoning', () => {
    +
    +        const a = JSON.parse('{ "__proto__": { "x": 1 } }');
    +        expect(a.x).to.not.exist();
    +
    +        const b = Hoek.clone(a);
    +        expect(b.x).to.not.exist();
    +    });
     });
     
     describe('merge()', () => {
    
948baf98634a

Prevent prototype poisoning in clone(). Closes #352

https://github.com/hapijs/hoekEran HammerFeb 8, 2020via ghsa
2 files changed · +5 1
  • lib/clone.js+4 0 modified
    @@ -77,6 +77,10 @@ module.exports = internals.clone = function (obj, options = {}, _seen = null) {
     
         const keys = Utils.keys(obj, options);
         for (const key of keys) {
    +        if (key === '__proto__') {
    +            continue;
    +        }
    +
             if (baseProto === Types.array &&
                 key === 'length') {
     
    
  • test/clone.js+1 1 modified
    @@ -818,7 +818,7 @@ describe('clone()', () => {
     
         it('prevents prototype poisoning', () => {
     
    -        const a = JSON.parse('{ "proto": { "x": 1 } }');
    +        const a = JSON.parse('{ "__proto__": { "x": 1 } }');
             expect(a.x).to.not.exist();
     
             const b = Hoek.clone(a);
    

Vulnerability mechanics

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

References

6

News mentions

0

No linked articles in our index yet.