diff --git a/readme.md b/readme.md
index e1e3ad3..804654d 100644
--- a/readme.md
+++ b/readme.md
@@ -1,6 +1,6 @@
# 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)
-> A tiny (194B) utility for safely writing deep Object values~!
+> A tiny (197B) utility for safely writing deep Object values~!
For _accessing_ deep object properties, please see [`dlv`](https://github.com/developit/dlv).
@@ -17,7 +17,7 @@ $ npm install --save dset
There are two "versions" of `dset` available:
#### `dset`
-> **Size (gzip):** 194 bytes
+> **Size (gzip):** 197 bytes
> **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)
```js
@@ -25,7 +25,7 @@ import { dset } from 'dset';
```
#### `dset/merge`
-> **Size (gzip):** 288 bytes
+> **Size (gzip):** 307 bytes
> **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)
```js
diff --git a/src/index.js b/src/index.js
index 75a01fb..85fd6a7 100644
--- a/src/index.js
+++ b/src/index.js
@@ -2,7 +2,7 @@ export function dset(obj, keys, val) {
keys.split && (keys=keys.split('.'));
var i=0, l=keys.length, t=obj, x, k;
while (i < l) {
- k = keys[i++];
+ k = ''+keys[i++];
if (k === '__proto__' || k === 'constructor' || k === 'prototype') break;
t = t[k] = (i === l) ? val : (typeof(x=t[k])===typeof(keys)) ? x : (keys[i]*0 !== 0 || !!~(''+keys[i]).indexOf('.')) ? {} : [];
}
diff --git a/src/merge.js b/src/merge.js
index 49f467b..4b5f0dc 100644
--- a/src/merge.js
+++ b/src/merge.js
@@ -19,7 +19,7 @@ export function dset(obj, keys, val) {
keys.split && (keys=keys.split('.'));
var i=0, l=keys.length, t=obj, x, k;
while (i < l) {
- k = keys[i++];
+ k = ''+keys[i++];
if (k === '__proto__' || k === 'constructor' || k === 'prototype') break;
t = t[k] = (i === l) ? merge(t[k],val) : (typeof(x=t[k])===typeof keys) ? x : (keys[i]*0 !== 0 || !!~(''+keys[i]).indexOf('.')) ? {} : [];
}
diff --git a/test/suites/pollution.js b/test/suites/pollution.js
index bf47756..8d338ed 100644
--- a/test/suites/pollution.js
+++ b/test/suites/pollution.js
@@ -38,6 +38,23 @@ export default function (dset) {
assert.is(Object.create(null).hello, undefined);
});
+ pollution('should protect against ["__proto__"] assignment :: implicit string', () => {
+ let input = { abc: 123 };
+ let before = input.__proto__;
+
+ dset(input, [['__proto__'], 'polluted'], true);
+
+ assert.equal(input.__proto__, before);
+ assert.equal(input, { abc: 123 });
+
+ assert.is({}.polluted, undefined);
+ assert.is(input.polluted, undefined);
+ assert.is((new Object).polluted, undefined);
+ assert.is(Object.create(null).polluted, undefined);
+ });
+
+
+
pollution('should ignore "prototype" assignment', () => {
let input = { a: 123 };
dset(input, 'a.prototype.hello', 'world');
@@ -85,7 +102,7 @@ export default function (dset) {
});
});
- // Test for CVE-2022-25645 - CWE-1321
+ // Test for CVE-2022-25645 - CWE-1321
pollution('should ignore JSON.parse crafted object with "__proto__" key', () => {
let a = { b: { c: 1 } };
assert.is(a.polluted, undefined);