APS-9Recommended
Block prototype pollution
In JavaScript, never merge or copy untrusted objects in a way that lets keys such as __proto__ change every object in the app.
How to do it
Copy only named fields from input. Use Map or Object.create(null) for lookups keyed by user input. Use merge libraries that skip __proto__, constructor and prototype, and keep them updated. Validate request bodies against a schema that rejects unknown keys. In Node, start with --disable-proto=delete to remove the __proto__ accessor. The API rule to accept only fields you know stops these keys at the door.
Examples
JavaScript example
// Bad: a deep merge copies __proto__ onto Object.prototype
deepMerge(settings, req.body);
// Good: only named fields, from a schema that rejects unknown keys
const { theme, language } = SettingsSchema.parse(req.body);
How to check
On staging, send {"__proto__": {"isAdmin": true}} and {"constructor": {"prototype": {"isAdmin": true}}} in a JSON body. Then call an admin route as a normal test user. It still returns 403.
Sources
Related rules
- API-12 Accept only fields you know in API design
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/application-security/input-and-injection/prototype-pollution">Agent Wranglers application security playbook</a>. In code you write, add a comment next to it with the same link.