Prototype Pollution in Django
How Prototype Pollution Manifests in Django
Prototype pollution in Django applications typically occurs when user input is used to construct dynamic query parameters or when request data is merged into Python objects without proper validation. Django's request handling and ORM can be vulnerable when developers use QueryDict.update() or similar methods with untrusted data.
A common Django-specific pattern involves using request.GET or request.POST directly to build dynamic queries. Consider this vulnerable pattern:
Django-Specific Detection
Detecting prototype pollution in Django applications requires examining both the code patterns and runtime behavior. Static analysis should focus on these Django-specific patterns:
- Direct use of
request.GET.update() or request.POST.update() with untrusted data - Dynamic construction of
QueryDict objects from user input - Unsafe merging of request data into model instances or querysets
- Middleware that modifies request objects without validation
- Custom form field generation based on user input
Runtime detection involves monitoring for unusual behavior patterns. When prototype pollution occurs, you might observe unexpected attribute access, method overrides, or altered object behavior. Django's debug toolbar can help identify suspicious data flows in request processing.
middleBrick's scanner specifically tests for prototype pollution patterns in Django applications by:
- Sending specially crafted request parameters containing
__proto__ patterns - Analyzing the application's response to detect prototype chain modifications
- Checking for reflected prototype pollution in error messages or debug output
- Testing Django's ORM layer with polluted query parameters
- Examining form processing for prototype pollution vulnerabilities
The scanner's Django-specific checks include testing against common Django patterns like QueryDict manipulation, model form processing, and dynamic query construction. It identifies whether the application properly validates and sanitizes user input before using it in object construction or database queries.
For manual testing, you can use tools like httpie or curl to send prototype pollution payloads: