Broken Object Property Level Authorization (BOPLA) happens when an API lets a caller read or change individual fields of an object that the caller is allowed to see, but should not be allowed to see or set those particular fields. OWASP created API3:2023 by merging two 2019 risks, Excessive Data Exposure and Mass Assignment, because both come from the same missing check at property level. This guide goes beyond the summary in the Top 10 API Security Risks: it explains what OWASP requires, how to design response and request contracts per role, the framework features that cause and prevent mass assignment, how to test and evidence the control, and why tokens and secrets are the most damaging fields to over-expose. It is for API developers, architects, application security engineers and testers.
Key takeaways
- Two directions, one root cause. Over-exposure is reading fields you should not (formerly API3:2019); mass assignment is writing fields you should not (formerly API6:2019). Both are missing field-level authorisation.
- Never serialise the domain object. Generic methods such as
to_json()return every property, including ones added later; build explicit response objects per endpoint and role. - Bind input to an allow-list, not the model. Use data transfer objects or framework allow-lists so only the fields intended for that action can be set; block-lists fail when a new sensitive field is added.
- The client is not a filter. Hiding a field in the app or front end does nothing if the API still returns it; filtering must happen on the server.
- Secrets and tokens are the worst fields to leak. API keys, session tokens, password hashes and internal flags in a response turn a minor leak into account or service takeover.
What it is and who it applies to
OWASP's test is direct: when an endpoint lets a user access an object, it must also validate that the user has access to the specific properties being read or changed. An endpoint is vulnerable if it exposes properties that are sensitive and should not be read by that user, or if it lets the user change, add or delete the value of a property they should not be able to access.
| Aspect | Excessive data exposure (read) | Mass assignment (write) |
|---|---|---|
| 2019 name | API3:2019 Excessive Data Exposure | API6:2019 Mass Assignment |
| CWE cited by OWASP | CWE-213 Exposure of Sensitive Information Due to Incompatible Policies | CWE-915 Improperly Controlled Modification of Dynamically-Determined Object Attributes |
| Typical cause | Generic serialisers, "return everything and let the client filter", GraphQL types exposing every column | Automatic binding of request bodies to model objects (called autobinding in Spring MVC and ASP.NET MVC, object injection in PHP) |
| OWASP example | A reportUser GraphQL mutation returns the reported user's fullName and recentLocation | A host adds total_stay_price to an approve_booking call; a user sets "blocked": false on their own video |
| Typical impact | Personal data disclosure, token leakage | Privilege escalation, price or status tampering, account takeover |
OWASP rates API3:2023 as Easy to exploit, Common in prevalence, Easy to detect and Moderate in technical impact, with privilege escalation or partial or full account takeover possible in some cases. Reading responses is enough to find over-exposure; hidden writable properties are found by fuzzing extra fields and watching for side effects.
How it differs from API1 and API5: in BOPLA the caller may legitimately access the object and the function. In OWASP API Top 10 API1 Broken Object Level Authorization Guide terms, the object check passes; the failure is one level finer. If the extra field lets a user call an admin-only operation, that also overlaps with the OWASP API Top 10 API5 Broken Function Level Authorization Guide.
Who it applies to: any API whose objects have fields with different sensitivity or ownership: user profiles (role, email verified, credit), orders (price, discount, status), content (moderation flags) and any resource that carries internal metadata. REST APIs are most exposed because they tend to return whole objects; GraphQL needs crafted queries but exposes field names through its schema.
Structure and key requirements
The OWASP entry lists six prevention measures. ASVS 5.0 turns them into verifiable requirements.
| OWASP prevention measure | Engineering interpretation | ASVS 5.0 anchor |
|---|---|---|
| Make sure the user should have access to the properties you expose | Field-level read rules per role and relationship, documented with the resource | V8.1.2 (field-level read and write rules), V8.2.3 (L2, field-level access to mitigate BOPLA) |
Avoid generic methods such as to_json() and to_string() | Explicit response DTOs or serialiser views per endpoint and role | V15.3.1 (L1, return only the required subset of fields) |
| Avoid functions that automatically bind client input to internal objects | Bind to input DTOs, or configure allow-lists per controller and action | V15.3.3 (L2, mass assignment countermeasures per controller and action) |
| Allow changes only to properties the client should update | Writable-field allow-list per action and role; reject or ignore unknown fields consistently | V15.3.3, V8.2.3 |
| Implement schema-based response validation as an extra layer | Validate outgoing responses against the published schema at the service or gateway | Supports V15.3.1 |
| Keep returned data structures to the bare minimum | Data minimisation by default; add fields only on a stated requirement | V15.3.1 |
Framework features to know
The OWASP Mass Assignment cheat sheet names the mechanisms that matter. Use the allow-list form in each case.
- Spring MVC: an
@InitBindermethod callingbinder.setAllowedFields(...);setDisallowedFields(...)is the weaker block-list form. Binding to a DTO avoids the problem entirely. - Laravel Eloquent:
$fillable(allow-list) rather than$guarded(block-list) on the model. - Node.js with Mongoose: pick allowed fields explicitly from the request body (the cheat sheet shows
_.pick(req.body, ...)) before creating or updating the document. - Ruby on Rails: Strong Parameters, which require permitted attributes to be declared before mass assignment.
- Schema contracts: in OpenAPI, mark server-controlled fields
readOnlyand secretswriteOnly, and setadditionalProperties: falseon request schemas so unknown fields are rejected by validators. - GraphQL: the OWASP GraphQL cheat sheet says field access must be checked so a requester only fetches fields they may read; resolvers can enforce this, and interfaces or unions can return fewer properties to less privileged callers. Disable introspection in production for public APIs, while remembering field names can still be guessed. See the GraphQL Security Guide.
Identity and NHI requirements
Property-level authorisation is where identity data most often leaks, because user, account and integration objects carry the most sensitive fields.
| Sensitive property | Read risk | Write risk |
|---|---|---|
role, isAdmin, permissions, tenantId | Reveals privileged users to target | Self-promotion to admin or move into another tenant |
| API keys, client secrets, webhook signing secrets | Direct service impersonation. See the API Key Management Guide. | Attacker sets a known secret on an integration |
| Session, refresh or password reset tokens | Account takeover | Session fixation style abuse |
| Password hash, MFA secret, recovery codes | Offline cracking or MFA bypass | Replace a victim's MFA seed |
email, emailVerified, ownerId | Personal data disclosure | Hijack recovery flows or transfer ownership |
- Secrets are write-once: return an API key or client secret only at creation, then return a masked value or a prefix and last-four characters. Never include secret fields in list or read responses for any role.
- Service accounts need field scope too: a reporting integration or AI agent that only needs order totals should get a response view without customer contact details. Least privilege for non-human identities includes the fields they receive, not only the endpoints. See the OWASP NHI Top 10 NHI5 Overprivileged NHI Guide.
- Agents amplify over-exposure: anything an API returns to an AI agent can end up in model context, logs or output. Return minimal fields to agent tools. See the OWASP LLM Top 10 LLM02 Sensitive Information Disclosure Guide.
- Do not take authorisation attributes from the body: role, tenant and owner must come from the validated credential and the stored object, never from a request property, which is exactly what mass assignment exploits.
Implementation steps
- Classify fields. For each resource, tag every property: public, owner-readable, role-restricted, internal-only, secret; and separately: client-writable on create, client-writable on update, server-controlled. Store the tags with the schema so they drive code and tests.
- Define response views per role. Create explicit response objects (or serialiser views) for each endpoint and caller type, such as public profile, owner view and admin view. Remove generic whole-object serialisation from handlers.
- Define input DTOs per action. Create and update often need different writable fields; a status transition endpoint should accept only the fields that transition uses. Configure the framework allow-list where DTOs are not practical.
- Enforce the contract at runtime. Validate requests against schemas with unknown fields rejected, and validate responses against the published schema in the service or at the gateway. Start response validation in report-only mode, review violations for a release cycle, then block. See the API Gateway Security Guide.
- Decide unknown-field behaviour. Rejecting unknown fields with HTTP 400 surfaces probing and client bugs; silently ignoring them is gentler for older clients. Pick one per API version, document it and log the occurrences either way.
- Test both directions in CI. For each role, assert that responses contain no fields outside the allowed view, and that requests adding server-controlled fields (
role,price,status,blocked,tenantId) do not change them. Generate the cases from the field classification. - Roll out and roll back. Introduce new response views behind an API version or feature flag, monitor client errors, and keep the previous view available for a short deprecation window so a broken client can be restored without re-exposing fields to everyone.
Choosing controls by organisation size
| Control | Small team or single API | Large estate or platform |
|---|---|---|
| Response shaping | Hand-written DTOs per endpoint | Schema-driven views generated from field classification |
| Input control | Framework allow-lists and DTOs | Shared validation library plus additionalProperties: false in all request schemas |
| Runtime enforcement | Request validation in the service | Gateway request and response schema validation as a second layer |
| Testing | Targeted tests for sensitive fields | Generated property tests per role, contract tests in CI, periodic authorised testing |
Schema validation at a gateway is cheap to add but cannot know relationships (such as "only the owner sees this field"), so it complements and never replaces field rules in the service.
Evidence and assessment
- Design evidence: documented field-level read and write rules per resource (ASVS V8.1.2) and the field classification.
- Code evidence: review or static analysis rules that flag generic serialisation of domain objects, model binding without allow-lists and use of block-list features.
- Test evidence: CI results for per-role response field tests and mass assignment tests, following the authorisation matrix approach in the OWASP Authorization Testing Automation cheat sheet.
- Manual testing: authorised testers compare responses across roles, add undocumented fields to requests and check side effects, and query GraphQL types for fields not used by the client. See the API Penetration Testing Guide.
Detection signals and metrics
| Signal or metric | Why it matters |
|---|---|
| Requests containing properties not in the request schema, per client | Probing for mass assignment shows as unknown fields such as role or isAdmin |
| Response schema violations at the gateway | Detects new fields leaking after a release |
| Average response size per endpoint, before and after each release | A jump often means a new field or nested object is being serialised |
| Secret patterns detected in API responses or logs | Should be zero; any hit is an incident |
| Percentage of endpoints using explicit response DTOs and input allow-lists | Measures structural adoption of the control |
| Mean time to fix BOPLA findings | Easy-to-exploit issues need short targets |
Mapping to other frameworks
| Framework | Reference | Relevance to API3 |
|---|---|---|
| OWASP ASVS 5.0 | V8.1.2, V8.2.3, V8.3.1, V15.3.1, V15.3.3 | Field-level rules, field-level access, server-side enforcement, minimal responses, mass assignment |
| MITRE CWE | CWE-213, CWE-915 | Exposure through incompatible policies; uncontrolled modification of object attributes |
| MITRE CAPEC | CAPEC-122 | Privilege abuse |
| NIST SP 800-53 Rev 5 | AC-3, AC-6, AC-21, SI-10, SA-11 | Access enforcement, least privilege, information sharing, input validation, developer testing |
| NIST CSF 2.0 | PR.AA-05, PR.DS-01, PR.PS-06 | Least privilege permissions, data protection, secure development |
| ISO/IEC 27001:2022 Annex A | 8.3, 8.11, 8.26, 8.28 | Information access restriction, data masking, application security requirements, secure coding |
| CIS Controls v8.1 | Control 3, Control 16 | Data protection; application software security |
See the OWASP ASVS Guide for how to scope ASVS levels across an API estate.
Common pitfalls
- Returning tokens with records: in the McHire default password flaw, the applicant record returned by the vulnerable API reportedly included an auth token that could log in as the candidate, so an object-level flaw became account access as well.
- Filtering in the client: the mobile app shows only a name, but the API response includes location, email and internal notes for anyone with a proxy.
- Block-lists that age badly:
$guardedorsetDisallowedFieldsprotects the fields known at the time; the next sensitive column added to the model is bindable by default. - One DTO for create, update and admin: a shared input object lets ordinary users set fields only admins should, such as
statusorverified. - GraphQL types mirroring database tables: every column becomes a queryable field with no per-field resolver check, and introspection publishes the list.
- Silent ignore without logging: unknown fields are dropped quietly, so probing for mass assignment is invisible to the SOC.
Practitioner checklist
- Classify every property of every resource for read sensitivity and write control.
- Replace generic object serialisation with explicit response objects per endpoint and role.
- Bind input to per-action DTOs or framework allow-lists; never rely on block-lists alone.
- Mark server-controlled fields
readOnly, secretswriteOnly, and setadditionalProperties: falsein request schemas. - Take role, tenant and owner only from the validated credential and stored object, never from the request body.
- Return secrets once at creation and mask them afterwards for every caller type, human or machine.
- Enforce field-level checks in GraphQL resolvers and restrict introspection on public production APIs.
- Add per-role response field tests and mass assignment tests to CI.
- Validate responses against the schema in report-only mode first, then block.
- Log unknown request fields and response schema violations, and alert on secret patterns in responses.
Standards and references
- OWASP: API3:2023 Broken Object Property Level Authorization
- OWASP: API Security Top 10 2023
- OWASP: Application Security Verification Standard 5.0
- OWASP Cheat Sheet Series: Mass Assignment
- OWASP Cheat Sheet Series: GraphQL
- OWASP Cheat Sheet Series: Authorization Testing Automation
- MITRE: CWE-915 Improperly Controlled Modification of Dynamically-Determined Object Attributes
- MITRE: CWE-213 Exposure of Sensitive Information Due to Incompatible Policies
Related NHI Mgmt Group resources: Top 10 API Security Risks · API Security Guide · Secure API Design Guide · Authorisation Models Guide · OWASP API Top 10 API1 Broken Object Level Authorization Guide