Skip to content

Commit 16d6154

Browse files
committed
fix: prevent __proto__ assignment via implicit string
1 parent 48f14a1 commit 16d6154

File tree

4 files changed

+23
-6
lines changed

4 files changed

+23
-6
lines changed

readme.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# dset [![CI](https://github.com/lukeed/dset/workflows/CI/badge.svg?branch=master&event=push)](https://github.com/lukeed/dset/actions) [![codecov](https://badgen.net/codecov/c/github/lukeed/dset)](https://codecov.io/gh/lukeed/dset)
22

3-
> A tiny (194B) utility for safely writing deep Object values~!
3+
> A tiny (197B) utility for safely writing deep Object values~!
44
55
For _accessing_ deep object properties, please see [`dlv`](https://github.com/developit/dlv).
66

@@ -17,15 +17,15 @@ $ npm install --save dset
1717
There are two "versions" of `dset` available:
1818

1919
#### `dset`
20-
> **Size (gzip):** 194 bytes<br>
20+
> **Size (gzip):** 197 bytes<br>
2121
> **Availability:** [CommonJS](https://unpkg.com/dset/dist/index.js), [ES Module](https://unpkg.com/dset/dist/index.mjs), [UMD](https://unpkg.com/dset/dist/index.min.js)
2222
2323
```js
2424
import { dset } from 'dset';
2525
```
2626

2727
#### `dset/merge`
28-
> **Size (gzip):** 288 bytes<br>
28+
> **Size (gzip):** 307 bytes<br>
2929
> **Availability:** [CommonJS](https://unpkg.com/dset/merge/index.js), [ES Module](https://unpkg.com/dset/merge/index.mjs), [UMD](https://unpkg.com/dset/merge/index.min.js)
3030
3131
```js

src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ export function dset(obj, keys, val) {
22
keys.split && (keys=keys.split('.'));
33
var i=0, l=keys.length, t=obj, x, k;
44
while (i < l) {
5-
k = keys[i++];
5+
k = ''+keys[i++];
66
if (k === '__proto__' || k === 'constructor' || k === 'prototype') break;
77
t = t[k] = (i === l) ? val : (typeof(x=t[k])===typeof(keys)) ? x : (keys[i]*0 !== 0 || !!~(''+keys[i]).indexOf('.')) ? {} : [];
88
}

src/merge.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export function dset(obj, keys, val) {
1919
keys.split && (keys=keys.split('.'));
2020
var i=0, l=keys.length, t=obj, x, k;
2121
while (i < l) {
22-
k = keys[i++];
22+
k = ''+keys[i++];
2323
if (k === '__proto__' || k === 'constructor' || k === 'prototype') break;
2424
t = t[k] = (i === l) ? merge(t[k],val) : (typeof(x=t[k])===typeof keys) ? x : (keys[i]*0 !== 0 || !!~(''+keys[i]).indexOf('.')) ? {} : [];
2525
}

test/suites/pollution.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,23 @@ export default function (dset) {
3838
assert.is(Object.create(null).hello, undefined);
3939
});
4040

41+
pollution('should protect against ["__proto__"] assignment :: implicit string', () => {
42+
let input = { abc: 123 };
43+
let before = input.__proto__;
44+
45+
dset(input, [['__proto__'], 'polluted'], true);
46+
47+
assert.equal(input.__proto__, before);
48+
assert.equal(input, { abc: 123 });
49+
50+
assert.is({}.polluted, undefined);
51+
assert.is(input.polluted, undefined);
52+
assert.is((new Object).polluted, undefined);
53+
assert.is(Object.create(null).polluted, undefined);
54+
});
55+
56+
57+
4158
pollution('should ignore "prototype" assignment', () => {
4259
let input = { a: 123 };
4360
dset(input, 'a.prototype.hello', 'world');
@@ -85,7 +102,7 @@ export default function (dset) {
85102
});
86103
});
87104

88-
// Test for CVE-2022-25645 - CWE-1321
105+
// Test for CVE-2022-25645 - CWE-1321
89106
pollution('should ignore JSON.parse crafted object with "__proto__" key', () => {
90107
let a = { b: { c: 1 } };
91108
assert.is(a.polluted, undefined);

0 commit comments

Comments
 (0)