Blog / API Security

How to Test for Mass Assignment Vulnerabilities in REST APIs

Mass assignment lets attackers modify properties your API never intended to expose. Learn how to identify candidate fields, test them safely, verify impact, and fix the binding logic at its source.

A REST endpoint may display a harmless request schema while its backend accepts far more. If the application automatically copies every client-supplied property onto an internal object, an attacker can add fields such as isAdmin, accountStatus, or creditLimit and change state that should be controlled only by the server. This guide explains how mass assignment happens, how to test for it without damaging data, and how to replace unsafe binding with explicit property-level authorization.

This article was created with AI assistance and reviewed by the DastPilot team.

What is a mass assignment vulnerability?

Mass assignment occurs when application code binds an incoming object directly to a model, database entity, or domain object without restricting which properties the current user may change. The framework convenience is attractive: instead of assigning each supported field individually, the handler passes the whole request body into a generic update function.

The vulnerability is not that an API accepts JSON. It is that the server treats the client's property names as authorization decisions. Input validation may confirm that isAdmin is a Boolean, but only authorization can decide whether this user is allowed to change it.

Where mass assignment sits in the OWASP API Top 10

OWASP listed Mass Assignment as API6 in its 2019 API Security Top 10. In the 2023 edition, it became part of API3: Broken Object Property Level Authorization (BOPLA), alongside excessive data exposure. The newer category focuses on the shared root cause: missing authorization at the individual property level.

The familiar term remains useful because it describes the implementation failure precisely. A mass assignment test asks: can a client add or modify an object property that this operation, identity, or role should not control?

How a mass assignment attack works

Consider a profile endpoint that legitimately allows a customer to change a display name and time zone:

PATCH /api/users/me
Authorization: Bearer <customer-token>
Content-Type: application/json

{
  "displayName": "Asha",
  "timezone": "Asia/Kolkata"
}

The response contains additional server-managed properties:

{
  "id": "usr_1842",
  "displayName": "Asha",
  "timezone": "Asia/Kolkata",
  "role": "customer",
  "emailVerified": false
}

An attacker replays the update with one of those properties added:

{
  "displayName": "Asha",
  "timezone": "Asia/Kolkata",
  "role": "admin",
  "emailVerified": true
}

If the backend performs a generic update such as Object.assign(user, request.body), both protected values may be persisted. A successful HTTP status alone does not prove the vulnerability; the tester must retrieve the object again or exercise the affected capability to verify that the unauthorized state change occurred.

Mass assignment vs BOLA and BFLA

These vulnerabilities all involve authorization, but they test different boundaries. Keeping them separate makes both test plans and remediation clearer. For a deeper authorization comparison, see our guide to BFLA vs BOLA.

Vulnerability Attacker changes Security question
Mass assignment / BOPLA A property in the request body May this identity modify this field?
BOLA An object identifier May this identity access this object?
BFLA An endpoint or operation May this role invoke this function?

Properties worth prioritizing

Any server-managed field deserves a negative test. Start with properties whose modification would create clear business impact:

  • Authorization fields such as role, permissions, isAdmin, and ownerId
  • Workflow fields such as approved, status, reviewedBy, and emailVerified
  • Financial fields such as price, discount, balance, plan, and creditLimit
  • Tenant boundaries such as organizationId, workspaceId, and accountId
  • Audit fields such as createdAt, updatedAt, createdBy, and soft-delete flags
  • Operational controls such as feature flags, moderation flags, rate-limit tiers, and internal notes

Candidate names often appear in API responses, OpenAPI response schemas, frontend code, mobile clients, error messages, and adjacent admin endpoints. Treat those sources as leads, not proof that the field is writable.

How to test for mass assignment step by step

Only test systems you own or are explicitly authorized to assess. Prefer an isolated test account and non-production environment because a successful test can alter permissions, billing, or tenant ownership.

1. Capture a valid baseline update

Start with a request that the API accepts normally. Record the response, then retrieve the resource separately so you know its state before testing. A valid baseline helps distinguish authorization behavior from schema, authentication, and workflow errors.

2. Build a candidate property list

Compare request and response schemas. Look for fields returned by the API but absent from the update request, properties accepted by higher-privilege operations, and internal names visible in client code. Include common naming variants, but keep the list relevant to the specific object rather than blindly sending thousands of keys.

3. Add one unauthorized property at a time

Submit the original valid request with a single candidate property. One-at-a-time testing makes the result attributable and avoids a rejected field masking another accepted field.

PATCH /api/users/me

{
  "displayName": "Asha",
  "role": "admin"
}

A well-defended API may reject the whole request with a 400 or 403 response, or ignore the unauthorized property while updating the permitted one. The contract should make that behavior predictable, and security tests should verify it.

4. Verify persisted state and side effects

Do not rely on the update response alone. Retrieve the resource with a separate request, sign in again if claims are cached in a token, or attempt a harmless operation that requires the changed property. Some APIs echo untrusted input without saving it; others save a field but omit it from responses.

5. Repeat across roles and update methods

Test low-privilege, partner, support, and administrator identities according to the intended permission matrix. Check POST, PUT, and PATCH operations independently: serializers and update code paths frequently differ. Also test nested objects, because unsafe binding may occur below the top level.

6. Record reproducible evidence

A useful finding includes the baseline request, modified request, identity and role used, before-and-after state, business impact, and the exact property that crossed the boundary. That evidence lets developers fix the binding rule without guessing.

Automating mass assignment testing

Automation needs more context than simply appending isAdmin=true to every request. A useful scanner must first construct a valid request, identify realistic candidate properties, authenticate as the right user, and verify whether a change persisted. Schema-aware testing is especially valuable because an accurate OpenAPI specification reveals object shapes, update operations, and response-only fields.

DastPilot reads OpenAPI and Swagger definitions, analyzes object relationships, and runs targeted API attacks for OWASP API Security Top 10 risks, including mass assignment and property-level authorization failures. Findings include request and response evidence so teams can separate a proven state change from a reflected value or generic success response.

How to prevent mass assignment

Allowlist writable fields

Define the properties each operation is allowed to change and copy only those values. Do not try to maintain a denylist of dangerous names; new sensitive fields can be added to the model later and become writable by accident.

// Unsafe: every client property reaches the model
Object.assign(user, request.body);

// Safer: this endpoint maps only its supported inputs
const { displayName, timezone } = request.body;
user.displayName = displayName;
user.timezone = timezone;

Use operation-specific input models

Separate public update DTOs or schemas from database entities and response models. A customer profile update, administrator account update, and billing adjustment should not share one broad input type merely because they touch the same record.

Authorize sensitive properties explicitly

Some fields are legitimately writable by certain roles. Enforce that rule in a centralized authorization layer and test both allowed and denied cases. Hiding a field from documentation or the frontend is not an authorization control.

Reject unexpected properties

Configure request validation to reject unknown keys and use schemas with explicit properties. In OpenAPI, additionalProperties: false can document this intent, but the server must actually enforce the request schema. Validation supports the allowlist; it does not replace property-level authorization.

Keep response models minimal

Return only the properties the client needs. This reduces candidate-field discovery and prevents the other half of BOPLA: unauthorized reading of sensitive properties. OWASP recommends explicitly selecting fields instead of serializing whole internal objects.

Mass assignment testing checklist

  • Inventory all create and update operations, including nested objects
  • Compare writable request fields with response and internal model fields
  • Test server-managed properties one at a time with a low-privilege account
  • Verify persisted state or a safe side effect after each attempt
  • Repeat the test across roles, tenants, and POST, PUT, and PATCH handlers
  • Confirm unknown properties are rejected or safely ignored by contract
  • Use operation-specific input schemas and allowlisted assignments
  • Add negative property-authorization tests to CI/CD

Final takeaway

Mass assignment is a small coding shortcut with an authorization-sized impact. The reliable fix is to stop treating incoming property names as trusted instructions: define operation-specific input models, allowlist writable fields, enforce role rules for sensitive properties, and test the negative cases continuously.

For testers, the key is verification. A 200 response or reflected JSON value is only a clue; a proven unauthorized change to persisted state is the finding.

Test REST API properties automatically

Use DastPilot to turn your OpenAPI specification into targeted OWASP API security tests with reproducible evidence.

Start Free Trial