Skip to content

Commit

Permalink
Fix prototype pollution when path components are not strings
Browse files Browse the repository at this point in the history
  • Loading branch information
mariocasciaro committed Aug 27, 2021
1 parent ebc5e2c commit 7bdf4ab
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 2 deletions.
3 changes: 3 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@
return set(obj, path.split('.').map(getKey), value, doNotReplace);
}
var currentPath = path[0];
if (typeof currentPath !== 'string' && typeof currentPath !== 'number') {
currentPath = String(currentPath)
}
var currentValue = getShallowProperty(obj, currentPath);
if (options.includeInheritedProps && (currentPath === '__proto__' ||
(currentPath === 'constructor' && typeof currentValue === 'function'))) {
Expand Down
18 changes: 16 additions & 2 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,12 +241,18 @@ describe('set', function () {
objectPath.set({}, '__proto__.injected', 'this is bad')
expect(Object.prototype.injected).to.be.undefined

objectPath.set({}, [['__proto__'], 'injected'], 'this is bad')
expect(Object.prototype.injected).to.be.undefined

function Clazz() {}
Clazz.prototype.test = 'original'

objectPath.set(new Clazz(), '__proto__.test', 'this is bad')
expect(Clazz.prototype.test).to.be.equal('original')

objectPath.set(new Clazz(), [['__proto__'], 'test'], 'this is bad')
expect(Clazz.prototype.test).to.be.equal('original')

objectPath.set(new Clazz(), 'constructor.prototype.test', 'this is bad')
expect(Clazz.prototype.test).to.be.equal('original')
})
Expand All @@ -256,6 +262,11 @@ describe('set', function () {
.to.throw('For security reasons')
expect(Object.prototype.injected).to.be.undefined

expect(function() {
objectPath.withInheritedProps.set({}, [['__proto__'], 'injected'], 'this is bad')
expect(Object.prototype.injected).to.be.undefined
}).to.throw('For security reasons')

function Clazz() {}
Clazz.prototype.test = 'original'

Expand All @@ -267,8 +278,11 @@ describe('set', function () {
.to.throw('For security reasons')
expect(Clazz.prototype.test).to.be.equal('original')

const obj = {}
expect(function() {objectPath.withInheritedProps.set(obj, 'constructor.prototype.injected', 'this is OK')})
expect(function() {objectPath.withInheritedProps.set({}, 'constructor.prototype.injected', 'this is OK')})
.to.throw('For security reasons')
expect(Object.prototype.injected).to.be.undefined

expect(function() {objectPath.withInheritedProps.set({}, [['constructor'], 'prototype', 'injected'], 'this is bad')})
.to.throw('For security reasons')
expect(Object.prototype.injected).to.be.undefined
})
Expand Down

0 comments on commit 7bdf4ab

Please sign in to comment.