CVE-2025-48054
Description
Radashi is a TypeScript utility toolkit. Prior to version 12.5.1, the set function within the Radashi library is vulnerable to prototype pollution. If an attacker can control parts of the path argument to the set function, they could potentially modify the prototype of all objects in the JavaScript runtime, leading to unexpected behavior, denial of service, or even remote code execution in some specific scenarios. This issue has been patched in version 12.5.1. A workaround for this issue involves sanitizing the path argument provided to the set function to ensure that no part of the path string is __proto__, prototype, or constructor.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
radashinpm | < 12.5.1 | 12.5.1 |
Patches
2028de5e39aca8147abc8cfc3fix(set): prevent prototype pollution
4 files changed · +51 −6
src/mod.ts+1 −0 modified@@ -85,6 +85,7 @@ export * from './object/crush.ts' export * from './object/filterKey.ts' export * from './object/get.ts' export * from './object/invert.ts' +export * from './object/isDangerousKey.ts' export * from './object/keys.ts' export * from './object/listify.ts' export * from './object/lowerize.ts'
src/object/isDangerousKey.ts+17 −0 added@@ -0,0 +1,17 @@ +/** + * Check if a property key is “dangerous” in the sense that it could + * be used to modify built-in objects, possibly leading to prototype + * pollution or other unintended side effects. + * + * If you pass an object, it will be checked for a `null` prototype, + * in which case, the key will be considered safe. + * + * @see https://radashi.js.org/reference/object/isDangerousKey + * @version 12.5.1 + */ +export function isDangerousKey(key: PropertyKey, object?: object): boolean { + return ( + !(object && !Object.getPrototypeOf(object)) && + (key === '__proto__' || key === 'prototype' || key === 'constructor') + ) +}
src/object/set.ts+5 −1 modified@@ -1,4 +1,4 @@ -import { clone, isIntString } from 'radashi' +import { clone, isDangerousKey, isIntString } from 'radashi' /** * Opposite of get, dynamically set a nested value into an object @@ -28,6 +28,10 @@ export function set<T extends object, K>( object ??= isIntString(key) ? [] : {} + if (isDangerousKey(key, object)) { + throw new Error('Unsafe key in path: ' + key) + } + if (index < keys.length - 1) { value = recurse(object[key], keys, index + 1) }
tests/object/set.test.ts+28 −5 modified@@ -93,11 +93,34 @@ describe('set', () => { }) }) - test('prototype pollution', () => { - const prototype: any = {} - _.set(Object.create(prototype), '__proto__.polluted', true) + test('prototype pollution is forbidden', () => { + expect(() => _.set({}, '__proto__.polluted', true)).toThrowError( + 'Unsafe key in path: __proto__', + ) + expect(() => _.set({}, 'prototype.polluted', true)).toThrowError( + 'Unsafe key in path: prototype', + ) - expect(prototype.polluted).toBeUndefined() - expect('polluted' in prototype).toBe(false) + // Prototype-less objects don't care: + let obj = Object.create(null) + + obj = _.set(obj, '__proto__.polluted', true) + expect(Object.getPrototypeOf(obj)).toBe(null) + expect(obj.__proto__).toEqual({ polluted: true }) + + obj = _.set(obj, 'prototype.polluted', true) + expect(Object.getPrototypeOf(obj)).toBe(null) + expect(obj.prototype).toEqual({ polluted: true }) + }) + + test('constructor pollution is forbidden', () => { + expect(() => _.set({}, 'constructor.polluted', true)).toThrowError( + 'Unsafe key in path: constructor', + ) + + // Prototype-less objects don't care: + let obj = Object.create(null) + obj = _.set(obj, 'constructor.polluted', true) + expect(obj.constructor).toEqual({ polluted: true }) }) })
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4News mentions
0No linked articles in our index yet.