liveBook · Manning

User-based security

As explained in Secure APIs

An authorization model that grants permissions directly according to individual user identities.

User-based security authorizes requests according to the individual user identity behind an access token. It answers whether this user may access this resource or perform this operation, rather than relying only on valid authentication. A request with valid credentials but insufficient permission should receive 403 Forbidden. section 7.0 section 12.4

The central failure is accepting an authenticated identity without checking ownership or permission. Attackers can exploit this as broken object-level authorization, access another user’s data, reuse another user’s coupon, or reach an administrative endpoint. section 12.4 section 12.5

Testing ownership at an endpoint

Create a token for one student, request a registration belonging to another student, and assert a 403 response. Apply the same pattern to user-specific vouchers and business operations: authenticate as one identity, submit another identity’s resource, and verify that the operation is denied. section 12.4 section 12.5

Use these checks when applying user-based security:

  • Test every endpoint that applies user-based access controls, not only authentication failures. section 12.4
  • Verify that non-admin identities receive 403 from administrative endpoints; a successful 200 response indicates privilege escalation. section 12.4
  • Run these unit tests on every code change so unexpected authorization behavior is caught early. section 12.5
Listing 12.3 Implementing a BOLA test
# file: ch12/tests.py
[...]
from models import Course, CourseRegistration, Student
[...]

client = TestClient(server)
[...]

def test_bola():
    with session_maker() as session:
        student = session.scalar(select(Student))
        registration = session.scalar(
            select(CourseRegistration).where(
                CourseRegistration.student_id != student.id
            )
        )
    token = create_access_token(sub=str(student.id))    #1
    response = client.get(
        f"/registrations/{registration.id}",
        headers={     #2
            "Authorization": f"Bearer {token}"
        }
    )
    assert response.status_code == 403

This focused test shows the essential pattern: create an identity-specific bearer token, request another user’s registration, and require 403 Forbidden. section 12.4

How Secure APIs covers it

How deep it goes
Demonstrates token-based tests for ownership, administrative permissions, and business-flow access, stopping short of implementation fixes.
Examples
Uses student registrations, admin student listings, vouchers, coupon reuse, bearer tokens, pytest tests, and 403 assertions.
What it assumes
Assumes basic API requests and access tokens while establishing authentication before authorization.
What you can do after
Diagnose authorization flaws by writing regression tests for cross-user access, privilege escalation, and business-flow abuse.
How it connects
Connects authentication, authorization, access tokens, BOLA, role-based access control, privilege escalation, and business flow vulnerabilities.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Secure APIs. The section links point to the parts of the book it draws on.