diff --git a/CHANGELOG.md b/CHANGELOG.md index 381d03a..86a66d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,18 @@ # Changelog +# 8.9.1 (25.10.2024) + +Fixed prototype poisoning vulnerability in `deepClone`. + + ## 8.9.0 (31.05.2023) Ensured Node.js 18 support. `deepClone` typings have become more strict due to the goal to remove `any`. Thus, this helper does not expect `any` anymore. -Instead it expects `boolean | number | bigint | string | undefined | null | Date`, or array of them, or an object with values of these types. -The array and theh object may be nested. +Instead, it expects `boolean | number | bigint | string | undefined | null | Date`, or array of them, or an object with values of these types. +The array and the object may be nested. We believe that this is not a breaking change, because this change makes types more correct and more close to the implementation. It means that if your code does not satisfy the types of `deepClone`, you're probably not using it right. @@ -177,7 +182,7 @@ Removed `deepFlatten` & `getHostnameFromString`. Added CommonJS version for scripts to make it possible to use them in Node.js env. -To make it work we had to change [isMobile](./lib/is-mobile.js) notation. For now this helpers exports +To make it work we had to change [isMobile](./lib/is-mobile.js) notation. For now these helpers export a function that returns value, not the value itself. diff --git a/lib/deep-clone.ts b/lib/deep-clone.ts index 9f645b7..84911b1 100644 --- a/lib/deep-clone.ts +++ b/lib/deep-clone.ts @@ -37,7 +37,20 @@ function deepClone(obj: DeepCloneSupportedType): DeepCloneSupportedType { const copy: typeof obj = {}; Object.keys(obj).forEach(key => { - copy[key] = deepClone(obj[key]); + const value = deepClone(obj[key]); + + // The __proto__ property has a special meaning in JavaScript. So, to prevent prototype poisoning, + // we restrict direct assignment to this property. + if (key === '__proto__') { + Object.defineProperty(copy, key, { + configurable: true, + enumerable: true, + value, + writable: true, + }); + } else { + copy[key] = value; + } }); return copy; diff --git a/package-lock.json b/package-lock.json index 7e70d26..968db68 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@funboxteam/diamonds", - "version": "8.9.0", + "version": "8.9.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@funboxteam/diamonds", - "version": "8.9.0", + "version": "8.9.1", "license": "MIT", "devDependencies": { "@funboxteam/eslint-config": "7.3.0", diff --git a/package.json b/package.json index c0ef63e..59e441b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@funboxteam/diamonds", - "version": "8.9.0", + "version": "8.9.1", "description": "A shiny pile of typed JS helpers for everyday use", "scripts": { "build": "npm run clean && npm run build-esm-and-types && npm run build-cjs",