Skip to content

Commit

Permalink
fix(security): prevent proto pollution in simple assignment
Browse files Browse the repository at this point in the history
  • Loading branch information
bigopon committed Jun 19, 2021
1 parent a990648 commit d3bb6fa
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 6 deletions.
11 changes: 8 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,7 @@ function parseComplexParam(queryParams: Object, keys: (string | number)[], value
let keysLastIndex = keys.length - 1;
for (let j = 0; j <= keysLastIndex; j++) {
let key = keys[j] === '' ? (currentParams as any).length : keys[j];
if (key === '__proto__') {
throw new Error('Prototype pollution detected.');
}
preventPollution(key);
if (j < keysLastIndex) {
// The value has to be an array or a false value
// It can happen that the value is no array if the key was repeated with traditional style like `list=1&list[]=2`
Expand Down Expand Up @@ -267,6 +265,7 @@ export function parseQueryString(queryString: string): Object {
if (keysLastIndex) {
parseComplexParam(queryParams, keys, value);
} else {
preventPollution(key);
queryParams[key] = processScalarParam(queryParams[key], value);
}
} else {
Expand All @@ -275,3 +274,9 @@ export function parseQueryString(queryString: string): Object {
}
return queryParams;
}

function preventPollution(key: string) {
if (key === '__proto__') {
throw new Error('Prototype pollution detected.');
}
}
18 changes: 15 additions & 3 deletions test/path.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -337,8 +337,20 @@ describe('query strings', () => {
});
});

it('does not pollute prototype', () => {
const path1 = '__proto__[asdf]=asdf';
assert.throws(() => parseQueryString(path1), 'Prototype pollution detected');
describe('prototype pollution', () => {
it('does not allow __proto__ in AccessKey assignment: "__proto__[asdf]=asdf"', () => {
const path1 = '__proto__[asdf]=asdf';
assert.throws(() => parseQueryString(path1), 'Prototype pollution detected');
});

it('does not attempt on AccessMember like key that has __proto__: "__proto__.asdf=asdf"', () => {
const path1 = '__proto__.asdf=asdf';
assert.doesNotThrow(() => parseQueryString(path1));
});

it('does not allow __proto__ in simple assignment: "__proto__=x&0[xxx]=xxx"', () => {
const path1 = '__proto__=x&0[xxx]=xxx';
assert.throws(() => parseQueryString(path1), 'Prototype pollution detected');
});
});
});

0 comments on commit d3bb6fa

Please sign in to comment.