Lion Cipher Lab
Exploit and fix mass assignment (privilege escalation via an extra field)
- AppSec / DevSecOps
- Intermediate
- ~50 min
- Free · no account required
Why it matters
Mass assignment is one of the quietest ways an application hands out admin. There is no memory corruption, no injection, nothing that looks like an attack in a log — just a user updating their profile, with one extra field in the JSON. The reason it is so common is that it comes from a FEATURE: every modern web framework offers a one-liner to take a request body and bind all of its fields onto a database model, because writing out each field by hand is tedious. The moment that model also has a field the user shouldn't control — is_admin, role, account_balance, email_verified, is the classic…
What you'll learn
- explaining mass assignment: when a framework binds every field in a request body straight onto a server object, a user can set properties the API never meant to expose
- building a tiny vulnerable Flask profile-edit endpoint that does user.update(request.get_json()) and trusts whatever keys arrive
- escalating from a normal user to admin by adding a single "is_admin": true field to an otherwise legitimate profile-update request
- confirming the escalation against an admin-only endpoint that checks the is_admin flag you just set on yourself
- fixing it properly with an explicit allowlist of bindable fields (bind only display_name and email), so extra keys are ignored
- knowing why a blocklist ('just delete is_admin before saving') is the fragile fix and an allowlist is the robust one
- recognising mass assignment as a framework-wide bug class (Rails strong parameters, Spring @InitBinder/allowed fields, ASP.NET Bind/[BindNever], Django ModelForm fields) and where it hides — any create/update that maps request bodies onto models
Steps in this lab
- What mass assignment is — the convenience that leaks power
- Build the vulnerable app (on your own machine)
- Do the honest thing first, and confirm you are NOT admin
- Exploit it: one extra field makes you admin
- Fix it the right way: an allowlist of bindable fields
- Re-run the exact attack and watch it fail
- Why allowlist beats blocklist, and where this hides