• Agents
  • Docs
  • Pricing
  • Blog
Log in
Get started

Security for apps built with AI. Paste a URL, get a report, fix what matters.

Product

  • How it works
  • What we find
  • Pricing
  • Agents
  • MCP Server
  • CLI
  • GitHub Action

Resources

  • Blog
  • Docs
  • FAQ
  • Glossary

Security

  • Supabase Security
  • Next.js Security
  • Lovable Security
  • Cursor Security
  • Bolt Security

Legal

  • Privacy Policy
  • Terms of Service
  • Cookie Policy
  • Imprint
© 2026 Flowpatrol. All rights reserved.
Home/Glossary/Prototype Pollution
CWE-1321

JavaScript Object Manipulation (Prototype Pollution)

Prototype Pollution is a JavaScript-specific vulnerability where an attacker manipulates the prototype chain of base objects by injecting properties through user-controlled input. It is classified under CWE-1321 (Improperly Controlled Modification of Object Prototype Attributes). Because every JavaScript object inherits from Object.prototype, a single polluted property can cascade across the entire application — bypassing security checks, escalating privileges, or enabling remote code execution.

What is Prototype Pollution?

Every object in JavaScript inherits from Object.prototype. If an attacker can write to that prototype — say, by passing __proto__ as a key in a JSON body — every object in your app suddenly has that new property. An isAdmin check that defaults to undefined? Now it's true.

This isn't hypothetical. Prototype pollution has been found in widely-used libraries like Lodash, jQuery, and Express. The attack works because JavaScript's object model trusts prototype chain lookups by default — there's no built-in guard against writing to __proto__ or constructor.prototype.

What makes this especially dangerous in AI-generated code is that deep merge and config-parsing utilities are among the first things AI writes. These functions recursively assign properties from user input to objects without filtering dangerous keys — exactly the pattern that enables pollution.

How does Prototype Pollution work?

Prototype pollution needs two things: a code path that recursively merges or assigns properties from user input onto an object, and no filtering of special keys like __proto__, constructor, or prototype.

Here's a deep merge function that AI commonly generates:

Vulnerable — no key filtering on merge
// lib/utils.ts
function deepMerge(target: any, source: any) {
  for (const key in source) {
    if (typeof source[key] === 'object' && source[key] !== null) {
      if (!target[key]) target[key] = {};
      deepMerge(target[key], source[key]);
    } else {
      target[key] = source[key];
    }
  }
  return target;
}

// API route
app.post('/api/settings', (req, res) => {
  const settings = deepMerge({}, req.body);
  // Attacker sends: { "__proto__": { "isAdmin": true } }
  // Now EVERY object has isAdmin === true
  res.json(settings);
});
Fixed — safe object creation + schema validation
import { z } from 'zod';

const settingsSchema = z.object({
  theme: z.enum(['light', 'dark']).optional(),
  language: z.string().max(5).optional(),
  notifications: z.boolean().optional(),
});

app.post('/api/settings', (req, res) => {
  // Schema validation strips unexpected keys entirely
  const parsed = settingsSchema.safeParse(req.body);

  if (!parsed.success) {
    return res.status(400).json({ error: 'Invalid settings' });
  }

  // Object.create(null) has no prototype — can't be polluted
  const settings = Object.assign(Object.create(null), parsed.data);
  res.json(settings);
});

Why do AI tools generate Prototype Pollution vulnerabilities?

AI code generators love writing utility functions from scratch. Deep merge, config parsers, and object spread helpers are among the most commonly generated patterns — and they almost never include prototype pollution guards.

  • Utility functions are written inline. Instead of using a vetted library, AI generates its own deepMerge or extend function. These hand-rolled versions rarely filter __proto__ or constructor keys.
  • Training data includes vulnerable patterns. Older Stack Overflow answers and tutorials show recursive merge without any mention of prototype safety. The model reproduces what it learned.
  • The vulnerability is invisible in testing. A polluted prototype doesn't crash anything immediately. Unit tests pass. The app works fine — until an attacker sends a crafted payload.

Prototype pollution often acts as a stepping stone. On its own, it might seem low-impact. But combined with other patterns — like an <code>isAdmin</code> check that reads from the object — it becomes a full privilege escalation chain.

Common Prototype Pollution patterns

Deep merge from user input

Recursively merging req.body into a config or settings object without filtering keys.

Query string parsing

Libraries like qs can parse nested keys: ?__proto__[isAdmin]=true becomes a polluted prototype.

Template engine gadgets

Polluting prototype properties that template engines like Pug or Handlebars read during rendering, leading to XSS or RCE.

Config file merging

Merging user-uploaded JSON or YAML config files into application defaults without schema validation.

How Flowpatrol detects Prototype Pollution

Flowpatrol tests for prototype pollution by sending crafted payloads to every endpoint that accepts JSON input:

  1. 1Identifies merge endpoints by mapping API routes that accept nested JSON objects — settings, profiles, configs.
  2. 2Sends __proto__ payloads with known canary properties and checks whether subsequent responses reflect the polluted values.
  3. 3Tests constructor.prototype paths because some frameworks filter __proto__ but miss the constructor.prototype vector.
  4. 4Checks for downstream impact — if a polluted property affects auth checks, template rendering, or other security-sensitive logic.

Most scanners test for prototype pollution in known library versions. Flowpatrol tests your actual code paths — because AI-generated merge functions won't show up in any CVE database.

Related terms

Cross-Site Scripting (XSS)Unprotected Object Binding (Mass Assignment)Untrusted Data Deserialization (Insecure Deserialization)

Check your app for Prototype Pollution.

Flowpatrol sends real payloads to your merge and config endpoints. Five minutes. One URL.

Try it free