---
title: "Block prototype pollution · Agent Wranglers"
url: https://agentwranglers.se/playbook/application-security/input-and-injection/prototype-pollution
id: APS-9
level: Recommended
updated: 2026-10-27
build: a2a6bdfed830
tokens: 737
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Block prototype pollution

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Input and injection](https://agentwranglers.se/playbook/application-security/input-and-injection.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers.md). Updated 2026-10-27.

- ID: APS-9
- Level: Recommended
- Chapter: [Input and injection](https://agentwranglers.se/playbook/application-security/input-and-injection.md)
- Rule: In JavaScript, never merge or copy untrusted objects in a way that lets keys such as `__proto__` change every object in the app.
- 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.
- How: 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](https://agentwranglers.se/playbook/api-design/requests-and-responses/strict-input.md) stops these keys at the door.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### JavaScript example

```js
// 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);
```

## Sources

- [OWASP Prototype Pollution Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Prototype_Pollution_Prevention_Cheat_Sheet.html)

## Related rules

- API-12 [Accept only fields you know](https://agentwranglers.se/playbook/api-design/requests-and-responses/strict-input.md) in API design

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/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.

- Previous: [Never rebuild objects from untrusted data](https://agentwranglers.se/playbook/application-security/input-and-injection/unsafe-deserialisation.md)
- Next: [Escape input in directory queries](https://agentwranglers.se/playbook/application-security/input-and-injection/ldap-injection.md)
- [Input and injection](https://agentwranglers.se/playbook/application-security/input-and-injection.md)
