Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/controller-utils/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Add optional `startTime` to `TraceRequest` to allow backdating a span's start time ([#9315](https://github.com/MetaMask/core/pull/9315))

### Changed

- Widen `isSafeDynamicKey` parameter type from `string` to `PropertyKey` ([#9774](https://github.com/MetaMask/core/pull/9774))
- `number` and `symbol` keys are now considered safe and return `true`; previously any non-string input returned `false`

### Deprecated

- Deprecate `createServicePolicy` and related symbols ([#9418](https://github.com/MetaMask/core/pull/9418))
Expand Down
9 changes: 8 additions & 1 deletion packages/controller-utils/src/util.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,15 @@ describe('util', () => {
for (const badKey of util.PROTOTYPE_POLLUTION_BLOCKLIST) {
expect(util.isSafeDynamicKey(badKey)).toBe(false);
}
// @ts-expect-error - ensure that non-string input return false.
expect(util.isSafeDynamicKey(0)).toBe(true);
expect(util.isSafeDynamicKey(123)).toBe(true);
expect(util.isSafeDynamicKey(Number.NaN)).toBe(true);
expect(util.isSafeDynamicKey(Symbol('__proto__'))).toBe(true);
expect(util.isSafeDynamicKey(Symbol.iterator)).toBe(true);
// @ts-expect-error - ensure that non-`PropertyKey` input returns false.
expect(util.isSafeDynamicKey(null)).toBe(false);
// @ts-expect-error - ensure that non-`PropertyKey` input returns false.
expect(util.isSafeDynamicKey(undefined)).toBe(false);
});
it('isSafeChainId', () => {
expect(util.isSafeChainId(util.toHex(MAX_SAFE_CHAIN_ID + 1))).toBe(false);
Expand Down
17 changes: 12 additions & 5 deletions packages/controller-utils/src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,21 @@ export const PROTOTYPE_POLLUTION_BLOCKLIST = [
* Checks whether a dynamic property key could be used in
* a [prototype pollution attack](https://portswigger.net/web-security/prototype-pollution).
*
* String keys are compared against the {@link PROTOTYPE_POLLUTION_BLOCKLIST}.
* Number and symbol keys are always considered safe: number keys are coerced
* to numeric strings, which can never collide with the blocklist, and symbol
* keys cannot alias the string-keyed `Object.prototype` properties.
*
* @param key - The dynamic key to validate.
* @returns Whether the given dynamic key is safe to use.
*/
export function isSafeDynamicKey(key: string): boolean {
return (
typeof key === 'string' &&
!PROTOTYPE_POLLUTION_BLOCKLIST.some((blockedKey) => key === blockedKey)
);
export function isSafeDynamicKey(key: PropertyKey): boolean {
if (typeof key === 'string') {
return !PROTOTYPE_POLLUTION_BLOCKLIST.some(
(blockedKey) => key === blockedKey,
);
}
return typeof key === 'number' || typeof key === 'symbol';
}

/**
Expand Down