# Function and Property Level Authorization — Routebase

> API5:2023 and API3:2023, meaning the admin endpoint that forgot its role check and the response or request body that carries fields this caller has no business with.

Canonical page: https://routebase.dev/guides/api-security/function-and-property-level-authorization/
Chapter 2 of 12 · API Security · Last reviewed 2026-09-13 · The Routebase Team

The previous chapter was about the object. This one is about the two authorization checks that sit on either side of it, meaning the function being called and the individual fields moving in and out.

## Function level, or the admin endpoint nobody linked

**API5:2023 Broken Function Level Authorization** is an operation that verifies the caller is somebody without verifying that they are allowed to do this. Its OWASP references name [CWE-285](https://cwe.mitre.org/data/definitions/285.html), Improper Authorization.

It is common because administrative surfaces grow differently from public ones. An internal tool gets an endpoint, the endpoint is never linked from the customer-facing client, and the absence of a link starts doing the job of an access control. In a web application that is weak, while in an API it is nothing at all, since the path is written down in the specification you publish.

The probe is a privilege gap rather than a tenant gap. Call the administrative operation with an ordinary member's credentials and assert that it refuses. A 401, 403 or 404 is the endpoint working, and a 2xx is the finding.

OWASP's guidance for the category is worth quoting on the default. It asks that the enforcement mechanism "deny all access by default, requiring explicit grants to specific roles for access to every function". A deny-by-default design turns a forgotten check into a locked door rather than an open one.

## Property level, in both directions

**API3:2023 Broken Object Property Level Authorization** merges two categories that the 2019 edition kept apart, namely excessive data exposure and mass assignment. The merge makes sense, because both are a missing check on a property. Its references name [CWE-213](https://cwe.mitre.org/data/definitions/213.html) for exposure and [CWE-915](https://cwe.mitre.org/data/definitions/915.html) for the modification side.

**Reading too much** happens when a response is a serialised storage model. The client only renders three fields, so nobody notices that eleven went over the wire, and the extra eight include an internal note and a partner's tax identifier. The generic fix is a projection per operation, so a field reaches a response because somebody put it there.

**Accepting too much** is mass assignment. A write endpoint binds the incoming body onto the model, and a caller sets a property the interface never offered, such as a role, a price or a verification flag. The fix is an allow list of writable properties per operation, because a deny list is one new column away from being wrong.

Both directions need the same test shape. Read an object as a low-privilege identity and inspect the response for fields that identity should never see. Then send an update containing a field that identity may not set, and check that the service ignored it rather than applied it.

## Sensitive field names are a signal, not a verdict

Field names carry intent, and a property called `passwordHash` or `creditCardNumber` in a public response is worth a look before anything else in the sprint.

The signal is genuinely useful and it is not proof on its own. A field named `token` is sometimes a pagination cursor, and a field named `apiKey` on a self-service settings endpoint may be exactly the caller's own key, which they are entitled to read. Name matching finds candidates quickly and the context decides.

This is also the one place in the category where a check can run before anything is deployed. A field name lives in the schema, so a rule over the specification can object while the design is being written rather than after the response has been served to somebody.

## In Routebase

Two scanners cover this ground, and both need personas with a privilege gap rather than a tenant gap.

`api5-bfla` classifies endpoints as administrative by path and by specification tag, matching segments such as `/admin`, `/internal`, `/management` and `/system`, then calls each one with the assigned normal-user persona. A 2xx is a Critical finding, while 400, 401, 403 and 404 are recorded as the endpoint refusing correctly. Endpoints with `admin` in the path that are meant to be public, such as a health probe, are the usual false positive. Scope the scan to a specification that reflects the surface you want tested.

`api3-property-auth` walks each JSON response per persona and matches property names against a dictionary in two confidence tiers. Names like `password`, `passwordHash`, `ssn`, `creditCard`, `apiKey` and `refresh_token` raise High, while names like `internalNote`, `tax_id`, `phone_number` and `date_of_birth` raise Medium. Matched values are truncated to fifty characters in the evidence, so the finding never becomes a second copy of the data it is warning you about.

The design-time half is a style guide rule. `no-sensitive-fields-in-schema` inspects top-level schema property names for terms including `password`, `secret`, `token`, `apikey`, `creditcard`, `ssn` and `taxid`, and it flags them while the schema is being edited. It ships at warning severity, and severity is set per organisation and overridable per project, so you decide whether it informs or blocks. See the [Scanner Reference](https://docs.routebase.dev/scanner-reference/) and the [Style Guide](https://docs.routebase.dev/style-guide/), while [consistency across an API](/guides/api-design/consistency-across-an-api/) covers how a convention becomes a check that runs without a reviewer.

## Frequently asked questions

### What is broken function level authorization?

It is an operation that enforces authentication but not role, so an ordinary user who knows the path can call an administrative function. OWASP lists it as API5:2023 and its references name CWE-285, Improper Authorization. It usually appears when an admin area is protected by not being linked anywhere, which protects nothing in an API because the paths are published in the specification.

### What is broken object property level authorization?

It is the same authorization failure moved down to the field. OWASP made it API3:2023 by merging two older categories, namely excessive data exposure and mass assignment, because both are a missing check on a property rather than on an object. Its references name CWE-213 for the read direction and CWE-915 for the write direction.

### What is mass assignment in an API?

Mass assignment is a write endpoint that binds an incoming JSON body straight onto a model. A caller can then set fields the interface never offered them, such as a role, a price or an account balance. The defence is an explicit allow list of writable properties per operation. A deny list fails the first time somebody adds a field to the model and forgets the list.

### How do you stop an API returning fields a caller should not see?

Shape the response for the caller instead of serialising the storage model and hoping. That means an explicit projection per operation and per role, so a new column on a table cannot become a new field in a public response by accident. The check that catches the rest is reading the same object as a low-privilege identity and comparing what comes back.

---

[Routebase](https://routebase.dev/) — [Sign up](https://app.routebase.dev/): Every account starts with a 14-day Pro trial — no credit card required.
