javascript / expert
Snippet
Sanitizing Prototype Pollution via Object.create(null) in React State Reducers
When applying dynamic payload updates to state in React reducers from external APIs or user input, malicious keys like __proto__ can pollute Object.prototype. Utilizing null-prototype objects created via Object.create(null) alongside Reflect.ownKeys filtering ensures prototype chain integrity without inherited object properties.
snippet.js
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import React, { useReducer } from 'react';const DANGEROUS_KEYS = new Set(['__proto__', 'constructor', 'prototype']);function safeStateReducer(state, action) {if (action.type === 'PATCH_UNTRUSTED') {const safePatch = Object.create(null);for (const key of Reflect.ownKeys(action.payload)) {if (typeof key === 'string' && DANGEROUS_KEYS.has(key)) continue;Object.defineProperty(safePatch, key, {value: action.payload[key],writable: true,enumerable: true,configurable: true});}return Object.assign(Object.create(null), state, safePatch);}return state;}
react
Breakdown
1
const DANGEROUS_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
Establishes a constant-time lookup set containing standard prototype pollution payload vectors.
2
const safePatch = Object.create(null);
Instantiates a bare dictionary object without any prototype chain, preventing property lookup delegation.
3
for (const key of Reflect.ownKeys(action.payload)) {
Iterates over all own property keys, including non-enumerable properties and Symbols, avoiding prototype lookups.
4
if (typeof key === 'string' && DANGEROUS_KEYS.has(key)) continue;
Bypasses assignment if the property key matches known prototype pollution attack strings.
5
return Object.assign(Object.create(null), state, safePatch);
Merges sanitized properties into a new null-prototype state object to keep state decoupled from Object.prototype.