Saltearse al contenido

Mass assignment

Muchos frameworks vinculan automáticamente los campos de la petición a las propiedades de un objeto (modelo). Si no se filtra qué campos son vinculables, el atacante añade campos que no debería controlar (role, isAdmin, balance, verified, user_id) y modifica datos privilegiados. Es la cara de escritura del control de acceso roto y una categoría propia del OWASP API Top 10 (a veces llamada autobinding u overposting).

Escalada de privilegios (role=admin), manipulación de estado (saldo, verificación, precio, propietario), y toma de cuenta.

user.update(req.body) o un model binder que mapea todo el JSON/formulario al objeto. El atacante inspecciona el modelo (respuestas de la API que devuelven más campos de los que se “aceptan”, documentación, código fuente) y envía los campos de más.

# Registro/actualización normal
{"name":"pepe","email":"a@b.c","password":"x"}
# Con campos inyectados
{"name":"pepe","email":"a@b.c","password":"x","role":"admin","isAdmin":true,"verified":true,"balance":99999}

Descubre los campos vinculables:

  • Comparando lo que la API devuelve vs lo que “acepta” (si devuelve role, prueba a enviarlo).
  • Por la documentación/OpenAPI o el código (modelos, migraciones).
  • Probando nombres habituales (admin, is_admin, role, status, approved, owner).
Rails : strong params (permit); el histórico attr_accessible/attr_protected
Spring : @ModelAttribute / DataBinder (setAllowedFields / @InitBinder)
Django : ModelForm Meta.fields/exclude ; serializers de DRF
Laravel : $fillable / $guarded en el modelo
.NET : [Bind(Include=...)] ; DTOs ; "overposting" en MVC/Web API

Burp Suite (añadir campos a la petición), arjun para descubrir parámetros, y análisis de respuestas de la API.

Escalada a admin, cambio de propietario de un objeto (combinable con IDOR), fraude (saldo/precio), y ATO.

Peticiones con campos no esperados para ese endpoint; cambios de rol/estado/propietario por rutas que no deberían permitirlos.

  1. Lista blanca de campos vinculables (DTOs, permit, $fillable, [Bind]), nunca enlazar el objeto entero.
  2. Campos sensibles (role, isAdmin, owner, balance) solo modificables por el servidor o un flujo autorizado explícito.
  3. Separar el modelo de entrada (DTO) del de persistencia.
  4. Validación de esquema (OpenAPI) que rechace propiedades desconocidas.

Revertir cambios no autorizados, corregir el binder (lista blanca), y auditar qué cuentas cambiaron de rol/estado.

  • El caso canónico es el mass assignment de GitHub (2012) en Ruby on Rails: un investigador añadió su clave pública al proyecto rails/rails añadiendo un campo no previsto, demostrando que podía comprometer repos ajenos. Popularizó la clase y cambió los defaults de Rails.
  • Sigue siendo común en APIs modernas (Node/Express, Laravel, Spring) que enlazan el cuerpo entero al modelo.

CVEs/incidentes en NVD (https://nvd.nist.gov/vuln/search) y GitHub Advisories (https://github.com/advisories).

  • Enviar campos extra (role, isAdmin, verified, owner) en registro/actualización.
  • Comparar campos aceptados vs devueltos por la API.
  • Probados nombres habituales de campos privilegiados.
  • Confirmada la modificación de un campo privilegiado (sin tocar cuentas reales).