Overview
This vulnerability occurs when an application allows attackers to modify internal object properties or attributes that they should not be able to control. This is a common flaw in dynamically-typed languages or frameworks that map user input (like JSON or form data) directly onto objects.- In JavaScript (Node.js): This is known as Prototype Pollution. An attacker sends a crafted payload (e.g.,
{"__proto__": {"isAdmin": true}}) that modifies theObject.prototype. Since most objects inherit from this prototype, the attacker pollutes all objects in the application, potentially adding properties likeisAdminor overwriting critical functions, leading to security bypasses or RCE. - In Server-Side Frameworks (Rails, Laravel, ASP.NET): This is known as Mass Assignment. An attacker submits data for fields that aren’t in the form (e.g.,
{"name": "Attacker", "is_admin": true}). If the application maps all submitted data to the model (User.update(params)), the attacker can “assign” themselves theis_adminrole.
Business Impact
Exploiting this flaw can lead to:- Privilege Escalation: The most common impact. Attackers grant themselves administrative rights (
isAdmin = true) or modify their user ID. - Data Tampering: Overwriting critical object properties (like an item’s price) before processing.
- Security Bypass: Disabling security controls or flags (
isVerified = true). - Remote Code Execution (RCE): In prototype pollution, if a polluted property is later used to execute code (e.g., as part of a
child_processcommand or template render).
Reference Details
CWE ID: CWE-915
OWASP Top 10 (2021): A08:2021 - Software and Data Integrity Failures
Severity: High to Critical
Framework-Specific Analysis and Remediation
Defenses vary by language and framework but center on validating attribute names and controlling data binding. Never trust that user input only contains the fields you expect.- Python
- Java
- .NET(C#)
- PHP
- Node.js
- Ruby
Framework Context
Risk occurs when usingsetattr() with user-controlled property names or unsafely using __dict__.update() with user data.Vulnerable Scenario 1: Unsafe setattr()
A view updates a user profile by dynamically setting attributes from POST data.Vulnerable Scenario 2: Unsafe __dict__.update()
Mitigation and Best Practices
Use Django Forms or DRF Serializers. These tools act as a secure intermediary. They explicitly define which fields are allowed to be updated from user input, creating a secure allow-list. Avoidsetattr and __dict__.update with user-controlled keys/data.Secure Code Example
Testing Strategy
Identify endpoints that update objects (user profiles, settings). Submit requests containing additional, malicious properties (e.g.,is_staff=True, is_superuser=True, __class__=...). Check if the server state reflects these unauthorized changes. Review code for setattr(obj, key, ...) or obj.__dict__.update(...) where key or the update dictionary are user-controlled.
