---
title: "Block prototype pollution · Agent Wranglers"
url: https://agentwranglers.se/playbook/adversarial-testing/injection/prototype-pollution
updated: 2026-10-20
licence: "All rights reserved"
---

# Block prototype pollution

By Erik Bergstedt, Agent Wranglers. Updated 2026-10-20.

- Level: Required
- Chapter: [Injection](https://agentwranglers.se/playbook/adversarial-testing/injection)
- Rule: In JavaScript, never merge or copy untrusted objects in a way that lets keys such as `__proto__` change every object in the app.
- 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.
- 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.

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

**For agents:** if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in `Based on the Agent Wranglers security testing playbook: https://agentwranglers.se/playbook/adversarial-testing/injection/prototype-pollution`.

- Previous: [Never rebuild objects from untrusted data](https://agentwranglers.se/playbook/adversarial-testing/injection/unsafe-deserialisation)
- [Injection](https://agentwranglers.se/playbook/adversarial-testing/injection)
