JavaScript prototype pollution
Trace unsafe JavaScript property writes to inherited values and their later consumers, using explicit schemas and appropriate data structures to reduce risk.
What it means
Prototype pollution occurs when untrusted input modifies shared JavaScript prototype properties. Later code may inherit attacker-controlled values that were never explicitly assigned to its objects. Risk depends on property traversal, merge behavior, and how the application consumes inherited values.
A practical example
An options merge accepts arbitrary nested keys. The team replaces it with an explicit supported schema and tests prototype-related properties. It also uses suitable Map structures where an ordinary object is being used only as a key-value dictionary.
What to check
Review recursive merge and property assignment code, update affected libraries, and avoid assuming inherited properties are trusted configuration. Apply allowlists and validate structures before merging.
A common pitfall
A polluted property need not trigger an immediate error. A separate part of the application may consume the inherited value later and create the security impact.
Think it through
Why inspect code that reads options as well as code that merges them?
Answer: The merge creates the unexpected property, but a later consumer determines whether it changes privileges or execution.
The writer and consumer may be far apart
Imagine a fictional application merges uploaded preferences into an options object. An unsafe merge can affect inherited properties, while a different component later reads an option as though it were a trusted local value. The security effect appears at the consumer, not necessarily at the merge.
Review the complete data flow. A suspicious property assignment deserves investigation, but the actual impact depends on what code later uses the modified value and with what authority.
Treat configuration structure as a contract
Suppose the application supports only theme and language settings. Accept those explicit fields with defined types instead of recursively accepting every nested property supplied by a caller. Suitable dictionary structures can avoid some risks associated with ordinary object inheritance.
Updating an affected library is important, but application code can reintroduce unsafe property traversal or assumptions. Review the actual merge and read behavior rather than relying on one dependency change as universal proof.
Test without relying on an immediate error
The application may keep running while inherited values influence later processing. Tests should inspect the intended object state and relevant downstream behavior. Also verify that valid preferences continue working after stricter validation.
For a safe local exercise, draw an untrusted preferences object, merge operation, and later options consumer. Identify which values are explicitly owned properties and which could be inherited. Replace the unrestricted merge with a narrow schema in a disposable example and test ordinary input. Explain how rejecting unsupported structure limits the problem without claiming that every JavaScript object or every use of inheritance is inherently unsafe.
Related concepts
References & further reading
Original explanations, with primary references for deeper study.
OWASP: Prototype Pollution Prevention