8000 Merge commit from fork · lodash/lodash@eba8431 · GitHub
[go: up one dir, main page]

Skip to content

Commit eba8431

Browse files
authored
Merge commit from fork
* test: add tests to prevent security regressions * sec: prevent prototype pollution on `baseUnset` function * chore: improve security patch - Expand both `_.omit` & `_.unset` security tests to loop over `__proto__`, `constructor`, `prototype` - Only block `__proto__` if not an own property References: - https://github.com/lodash/lodash-ghsa-xxjr-mmjv-4gpg/pull/1#issuecomment-3507207439 - https://github.com/lodash/lodash-ghsa-xxjr-mmjv-4gpg/pull/1#issuecomment-3508891777
1 parent 4879a7a commit eba8431

File tree

4 files changed

+168
-60
lines changed

4 files changed

+168
-60
lines changed

dist/lodash.js

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4370,8 +4370,47 @@
43704370
*/
43714371
function baseUnset(object, path) {
43724372
path = castPath(path, object);
4373-
object = parent(object, path);
4374-
return object == null || delete object[toKey(last(path))];
4373+
4374+
// Prevent prototype pollution, see: https://github.com/lodash/lodash/security/advisories/GHSA-xxjr-mmjv-4gpg
4375+
var index = -1,
4376+
length = path.length;
4377+
4378+
if (!length) {
4379+
return true;
4380+
}
4381+
4382+
var isRootPrimitive = object == null || (typeof object !== 'object' && typeof object !== 'function');
4383+
4384+
while (++index < length) {
4385+
var key = path[index];
4386+
4387+
// skip non-string keys (e.g., Symbols, numbers)
4388+
if (typeof key !== 'string') {
4389+
continue;
4390+
}
4391+
4392+
// Always block "__proto__" anywhere in the path if it's not expected
4393+
if (key === '__proto__' && !hasOwnProperty.call(object, '__proto__')) {
4394+
return false;
4395+
}
4396+
4397+
// Block "constructor.prototype" chains
4398+
if (key === 'constructor' &&
4399+
(index + 1) < length &&
4400+
typeof path[index + 1] === 'string' &&
4401+
path[index + 1] === 'prototype') {
4402+
4403+
// Allow ONLY when the path starts at a primitive root, e.g., _.unset(0, 'constructor.prototype.a')
4404+
if (isRootPrimitive && index === 0) {
4405+
continue;
4406+
}
4407+
4408+
return false;
4409+
}
4410+
}
4411+
4412+
var obj = parent(object, path);
4413+
return obj == null || delete obj[toKey(last(path))];
43754414
}
43764415

43774416
/**

0 commit comments

Comments
 (0)
0