Prototype Pollution
Description
The package bmoor before 0.8.12 are vulnerable to Prototype Pollution via the set function.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
bmoor before 0.8.12 is vulnerable to Prototype Pollution via the set function, allowing attackers to pollute Object.prototype and potentially execute arbitrary code.
Vulnerability
Overview
The bmoor JavaScript package prior to version 0.8.12 is vulnerable to Prototype Pollution through its set function. The function does not properly sanitize property paths, allowing an attacker to set properties on __proto__, constructor, or prototype of an object. This pollutes the global Object.prototype, affecting all objects in the runtime [1].
Exploitation
An attacker can exploit this by providing a crafted object with a __proto__ property to any application that uses bmoor's set function with user-controlled input. No authentication is required if the application processes untrusted data. The attack is performed by passing a path like __proto__.polluted to the set function, which then assigns a value to the prototype chain [3].
Impact
Successful exploitation can lead to denial of service (via exceptions), property injection, or remote code execution depending on how the application uses the polluted properties. Since all objects inherit from Object.prototype, a single pollution can alter application behavior globally [3].
Mitigation
The vulnerability is fixed in bmoor version 0.8.12. Users should upgrade immediately. The fix includes explicit checks to prevent setting properties on __proto__ and similar dangerous paths [1]. No workarounds are available.
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 |
|---|---|---|
bmoornpm | < 0.8.12 | 0.8.12 |
Affected products
3- bmoor/bmoordescription
Patches
17d4a086a1dc3fix: prototype pollution
4 files changed · +178 −108
package.json+1 −1 modified@@ -1,6 +1,6 @@ { "name": "bmoor", - "version": "0.8.11", + "version": "0.8.12", "author": "Brian Heilman <das.ist.junk@gmail.com>", "description": "A basic foundation for other libraries, establishing useful patterbs, and letting them be more.", "license": "MIT",
src/core.js+16 −0 modified@@ -184,6 +184,10 @@ function set( root, space, value ){ for( i = 0, c = space.length; i < c; i++ ){ nextSpace = space[ i ]; + if (nextSpace === '__proto__'){ + return null; + } + if ( isUndefined(curSpace[nextSpace]) ){ curSpace[ nextSpace ] = {}; } @@ -197,6 +201,10 @@ function set( root, space, value ){ } function _makeSetter( property, next ){ + if (property === '__proto__'){ + throw new Error('unable to access __proto__'); + } + if ( next ){ return function setter( ctx, value ){ var t = ctx[property]; @@ -250,6 +258,10 @@ function get( root, path ){ for( i = 0, c = space.length; i < c; i++ ){ nextSpace = space[i]; + if (nextSpace === '__proto__'){ + return null; + } + if ( isUndefined(curSpace[nextSpace]) ){ return; } @@ -262,6 +274,10 @@ function get( root, path ){ } function _makeGetter( property, next ){ + if (property === '__proto__'){ + throw new Error('unable to access __proto__'); + } + if (next){ return function getter( obj ){ try {
src/core.spec.js+106 −54 modified@@ -4,75 +4,127 @@ const {expect} = require('chai'); const bmoor = require('./index.js'); describe('Testing object setting/getting', function() { - it('should have get working', function(){ - var t = { - eins : 1, - zwei: { - drei: 3 - } - }; - expect( bmoor.get(t,'eins') ).to.equal(1); - expect( bmoor.get(t,'zwei.drei') ).to.equal(3); - }); + describe('::get', function(){ + it('should be working', function(){ + var t = { + eins : 1, + zwei: { + drei: 3 + } + }; - it('should have get working with empty strings', function(){ - var t = { - eins : 1, - zwei: { - drei: 3 - } - }; + expect( bmoor.get(t,'eins') ).to.equal(1); + expect( bmoor.get(t,'zwei.drei') ).to.equal(3); + }); - expect( bmoor.get(t,'') ).to.equal(t); - }); + it('should be working with empty strings', function(){ + var t = { + eins : 1, + zwei: { + drei: 3 + } + }; - it('should have makeGetter working', function(){ - var t = { - eins : 1, - zwei: { - drei: 3 - } - }, - f1 = bmoor.makeGetter('eins'), - f2 = bmoor.makeGetter('zwei.drei'); + expect( bmoor.get(t,'') ).to.equal(t); + }); - expect( f1(t) ).to.equal(1); - expect( f2(t) ).to.equal(3); + it('should not allow __proto__', function(){ + var t = bmoor.get({}, '__proto__'); + + expect(t) + .to.equal(null); + }); }); + + describe('::makeGetter', function(){ + it('should be working', function(){ + var t = { + eins : 1, + zwei: { + drei: 3 + } + }, + f1 = bmoor.makeGetter('eins'), + f2 = bmoor.makeGetter('zwei.drei'); - it('should have makeGetter working with empty strings', function(){ - var t = { - eins : 1, - zwei: { - drei: 3 - } - }, - f1 = bmoor.makeGetter(''); + expect( f1(t) ).to.equal(1); + expect( f2(t) ).to.equal(3); + }); - expect( f1(t) ).to.equal(t); - }); + it('should fail with __proto__', function(){ + let failed = false; - it('should have set working', function(){ - var t = {}; + try { + bmoor.makeGetter('__proto__.polluted'); + } catch(ex){ + failed = true; + } + + expect(failed) + .to.equal(true); + }); - bmoor.set(t,'eins',1); - bmoor.set(t,'zwei.drei',3); + it('should work with empty strings', function(){ + var t = { + eins : 1, + zwei: { + drei: 3 + } + }, + f1 = bmoor.makeGetter(''); + + expect( f1(t) ).to.equal(t); + }); + }); - expect( t.eins ).to.equal(1); - expect( t.zwei.drei ).to.equal(3); + describe('::set', function(){ + it('should be working working', function(){ + var t = {}; + + bmoor.set(t,'eins',1); + bmoor.set(t,'zwei.drei',3); + + expect( t.eins ).to.equal(1); + expect( t.zwei.drei ).to.equal(3); + }); + + it('should not allow __proto__', function(){ + var t = {}; + + bmoor.set(t,'__proto__.polluted', true); + + expect( t.polluted ) + .to.not.equal(true); + }); }); - it('should have makeSetter working', function(){ - var t = {}, - f1 = bmoor.makeSetter('eins'), - f2 = bmoor.makeSetter('zwei.drei'); + describe('::makeSetter', function(){ + it('should actually work', function(){ + var t = {}, + f1 = bmoor.makeSetter('eins'), + f2 = bmoor.makeSetter('zwei.drei'); - f1(t,1); - f2(t,3); + f1(t,1); + f2(t,3); - expect( t.eins ).to.equal(1); - expect( t.zwei.drei ).to.equal(3); + expect( t.eins ).to.equal(1); + expect( t.zwei.drei ).to.equal(3); + }); + + it('should fail with __proto__', function(){ + let failed = false; + + try { + bmoor.makeGetter('__proto__.polluted'); + } catch(ex){ + failed = true; + } + + + expect(failed) + .to.equal(true); + }); }); it('should have del working', function(){
src/object.spec.js+55 −53 modified@@ -5,42 +5,44 @@ describe('bmoor.object', function() { const bmoor = require('./index.js'); - it('should operate explode correctly', function(){ - var t = { - 'eins.zwei': 12, - 'eins.drei': 13, - 'fier': 4 - }; - - expect(bmoor.object.explode(t)) - .to.deep.equal({ - eins: { - zwei: 12, - drei: 13 - }, - fier: 4 - }); - }); - - it('should operate makeExploder correctly', function(){ - var t = { + describe('::explode', function(){ + it('should operate explode correctly', function(){ + var t = { 'eins.zwei': 12, 'eins.drei': 13, 'fier': 4 - }, - explode = bmoor.object.makeExploder( Object.keys(t) ); + }; + + expect(bmoor.object.explode(t)) + .to.deep.equal({ + eins: { + zwei: 12, + drei: 13 + }, + fier: 4 + }); + }); + + it('should operate makeExploder correctly', function(){ + var t = { + 'eins.zwei': 12, + 'eins.drei': 13, + 'fier': 4 + }, + explode = bmoor.object.makeExploder( Object.keys(t) ); - expect(explode(t)) - .to.deep.equal({ - eins: { - zwei: 12, - drei: 13 - }, - fier: 4 + expect(explode(t)) + .to.deep.equal({ + eins: { + zwei: 12, + drei: 13 + }, + fier: 4 + }); }); }); - describe(':: implode', function(){ + describe('::implode', function(){ it('should operate correctly', function(){ var t = { time: { @@ -113,32 +115,32 @@ describe('bmoor.object', function() { ] }); }); - }); - it('should operate implode correctly - with an ignore', function(){ - var t = { - time: { - start: 99, - stop: 100 - }, - id: 'woot', - foo: { - bar: { - hello: 'world' + it('should operate implode correctly - with an ignore', function(){ + var t = { + time: { + start: 99, + stop: 100 + }, + id: 'woot', + foo: { + bar: { + hello: 'world' + } } - } - }; + }; - expect(bmoor.object.implode(t, { - ignore: { - time:{ - start:true - }, - id: true, - foo: true - } - })).to.deep.equal({ - 'time.stop': 100 + expect(bmoor.object.implode(t, { + ignore: { + time:{ + start:true + }, + id: true, + foo: true + } + })).to.deep.equal({ + 'time.stop': 100 + }); }); }); @@ -177,4 +179,4 @@ describe('bmoor.object', function() { }); }); }); -}); \ No newline at end of file +});
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-h3rx-g5c9-8q4xghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2020-7736ghsaADVISORY
- github.com/b-heilman/bmoor/commit/7d4a086a1dc3ef11ed0b323824d02348734b7da5ghsax_refsource_MISCWEB
- snyk.io/vuln/SNYK-JS-BMOOR-598664ghsax_refsource_MISCWEB
- www.npmjs.com/package/bmoorghsaWEB
News mentions
0No linked articles in our index yet.