Subscribe to the Non-Human & AI Identity Journal

What breaks when object-level authorisation is missing in web applications?

The application may let a valid session read or modify records that belong to someone else. This usually happens when the backend trusts object IDs, address IDs, or order IDs without rechecking ownership. The result is cross-account data exposure even when login, role checks, and UI permissions appear to work.

Why This Matters for Security Teams

Object-level authorisation failures are one of the most common ways a web application turns a valid login into a data breach. The user may be authenticated, the UI may hide sensitive actions, and role checks may look correct, yet the backend still trusts a record ID and returns data that belongs to another account. That is why object-level checks sit alongside broader access control expectations in NIST SP 800-53 Rev 5 Security and Privacy Controls, not as a cosmetic UI control but as a server-side enforcement requirement.

When this control is missing, attackers do not need to defeat authentication. They only need to alter an address ID, order ID, ticket number, or document key and observe whether the application returns someone else’s object. This is why broken object-level authorisation often appears in API-driven systems, mobile backends, and microservices where object references travel cleanly between services but ownership is never revalidated. The same pattern has shown up repeatedly in identity and secrets incidents, including the conditions described in NHIMG’s ASP.NET machine keys RCE attack, where trust in the wrong object or secret boundary becomes an escalation path. In practice, many security teams discover this only after a tenant has already read another tenant’s records, rather than through intentional access testing.

How It Works in Practice

In a secure design, the backend never treats an object identifier as proof of access. It first resolves the requested object, then checks whether the current session, token, or service identity is allowed to act on that exact record. The check must happen server-side on every read, update, delete, and export action. This aligns with the object-level and authorization guidance in NIST control families and with the broader defensive model in the Ultimate Guide to NHI, where trust boundaries are enforced through verification rather than assumption.

Practitioners usually implement this in one of three ways:

  • Query scoping, where the database query includes the caller’s tenant, user, or account constraint.
  • Policy checks, where the application evaluates ownership or membership before returning the object.
  • Indirect references, where external IDs map to internal records only after authorization succeeds.

For APIs, this matters even more because front-end controls can be bypassed completely. If a token grants access to the application, object-level checks decide whether that token can touch a specific row, file, address, or invoice. Good logging also matters: without object-specific audit trails, investigators may know a request succeeded but not which record was exposed. OWASP’s access control guidance remains a useful reference point for application teams, and NIST’s control model reinforces the expectation that enforcement is applied at the system boundary, not in the user interface.

These controls tend to break down when applications use shared endpoints for multi-tenant data, because ownership logic becomes inconsistent across services and developers assume the session already proves enough.

Common Variations and Edge Cases

Tighter object-level checks often increase development and testing overhead, requiring organisations to balance granular enforcement against release speed. That tradeoff is real, but current guidance suggests the cost of a missed check is far higher than the cost of adding a policy layer.

There is no universal standard for implementation details yet. Some teams centralise enforcement in middleware, while others embed ownership rules in every repository or service layer call. The safer choice depends on architecture, but the principle stays the same: the decision must be evaluated at runtime for the specific object being requested. This becomes harder in service-to-service workflows, asynchronous jobs, and delegated admin portals where one account can legitimately act on behalf of another. In those cases, the policy needs to distinguish between direct ownership, delegated authority, and system-level access.

Teams should also watch for edge cases where list endpoints are protected but detail endpoints are not, or where read access is scoped correctly but export, update, and delete operations are left open. The attack surface can also widen when object IDs are sequential, predictable, or leaked through logs, emails, and client-side telemetry. NHIMG’s research shows how often secret and identity exposure persists in real environments, and the same operational slippage often underpins broken access control. The lesson is simple: protect the object, not just the session, because authenticated access is not the same as authorised access.

Standards & Framework Alignment

This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.

OWASP Non-Human Identity Top 10 address the attack and risk surface, while NIST CSF 2.0, NIST SP 800-63, NIST Zero Trust (SP 800-207) and NIST AI RMF set the governance and control requirements practitioners need to meet.

Framework Control / Reference Relevance
OWASP Non-Human Identity Top 10 NHI-01 Missing object checks let identities access records beyond intended scope.
NIST CSF 2.0 PR.AC-4 Object-level authorization is a core least-privilege access control requirement.
NIST SP 800-63 Authenticated identity does not prove authority over a specific object.
NIST Zero Trust (SP 800-207) AC-6 Zero Trust requires continuous verification, not implicit trust after login.
NIST AI RMF Governance of access decisions needs accountable, context-aware enforcement.

Treat login as identity proof only, then require separate authorization for each object action.