WEB PENTESTING / VISUAL FIELD GUIDE / 01

Beyond the Login

A successful login answers who you are. It does not decide which records you may read or which actions you may take. Learn to see the boundary.

By Botnet Security5 min read
Beyond the Login: a signed-in identity meets an independent authorization gate before protected records.

Inspired by generalized themes from a Botnet Security education-sector assessment. Campus Demo, its users, records, messages and code are fictional teaching examples—not customer evidence or an exploitable application.

The student is signed in. The document exists. Neither fact answers the important question: should this student be allowed to read it?

That gap is where many application security findings begin. Before thinking about payloads, learn to describe the decision the server should make. This guide follows a fictional education portal through three moments: opening a record, completing sign-in and explaining the evidence.

01 / A login is not a permission

Campus Demo separates students into school tenants. Maya belongs to North School. Her session is valid, but it grants no general right to read South School records. The mock screen below illustrates a policy failure: the application has displayed a synthetic record outside her permitted scope.

● CAMPUS DEMO / RECORD VIEWERFICTIONAL UI

Admission record

Signed in as Maya · student

Session tenant
North School
Record tenant
South School
Record data
Synthetic sample only
Policy
Own school + own record
Boundary failure: the session is valid, but this record must not be visible to this actor.

The issue is not that a record has an identifier. It is that the server did not enforce the relationship between actor, action and object. An opaque identifier may reduce guessability; it cannot grant or deny permission.

A valid session reaches a record lookup. Without an object policy check, protected data can escape. With the policy check, the disallowed request is denied before data is returned.
FIG 01 The missing decision sits between identifying the user and releasing the record. View full size ↗

Object-level authorization asks whether Maya may read this record. IDOR describes a common exposure of a missing object check; BOLA is the broader API risk. Function-level authorization asks whether she may perform the action at all—for example, approving an admission. A hidden approval button does not enforce that rule on the server.

The repair belongs in the service handling the operation. Derive identity and tenant membership from validated authentication, apply the action policy and keep data retrieval within the allowed scope. Exports, downloads, background jobs and cache entries need the same boundary. A student-only ownership rule also needs a deliberate alternative for legitimately delegated staff access.

Pause and check: if changing an identifier produces a different response, what is still missing? The expected access policy, the object's ownership and evidence that protected data or state crossed that policy. A response difference alone is not enough.

02 / Sign-in has intermediate states

A login flow may accept a password and still require an additional factor. During that interval, the application can legitimately issue a short-lived challenge token. The problem is not the existence of that token; it is granting protected privileges before verification is complete.

Anonymous, password accepted, additional factor pending and fully authenticated are separate states. Only the fully authenticated state proceeds to a protected action's authorization check.
FIG 02 Completing authentication unlocks the next decision: authorization. It does not replace it. View full size ↗

This fictional request/response shows the expected defensive behavior. An incomplete sign-in cannot retrieve documents. The placeholder is not a real credential, and the example domain does not identify a target.

ILLUSTRATIVE HTTP / CORRECT REJECTION
GET /api/me/documents HTTP/1.1
Host: campus.example
Authorization: Bearer <fictional-challenge-token>

HTTP/1.1 403 Forbidden
Content-Type: application/json
Cache-Control: no-store

{
  "error": "authentication_incomplete",
  "next_step": "complete_required_factor"
}

The exact status and error shape depend on the API contract. What matters is that no protected data or side effect is available. Similarly, a 200 may contain a legitimate rejection, while a 429 alone does not prove the operation was blocked. Read the application outcome alongside the status.

Verification challenges need an expiry, purpose and account binding, single-use handling and server-enforced attempt limits. Resending a code must not silently create unlimited verification attempts. Recovery and cooldown design must also avoid making legitimate accounts easy to lock out.

A public record-recovery screen has a related trap. A name or email identifies a possible record; it rarely proves entitlement to read it. Verify the requester through an appropriate channel, check entitlement and minimize the response. Rate limiting reduces repeated use but cannot fix excessive disclosure in even one response.

03 / Report the broken rule

Write the finding around a contradiction, not around a tool. In the fictional screen above: “A North School student received a South School record despite a same-school, own-record policy.” That sentence identifies the actor, object, rule and consequence.

Keep the claim bounded. One unauthorized record establishes that disclosure, not unrestricted access to every tenant. Use synthetic data and minimum sufficient evidence within written scope. Avoid retaining personal data simply to make a report look more convincing.

  • Before the fix: document the policy, actor, object and actual server decision.
  • After the fix: disallowed access returns no protected content and causes no unauthorized state change.
  • Also verify: legitimate owners and delegated roles can still complete permitted work.

Take this with you: identify the user, complete the required authentication state, then authorize the specific action on the specific object. Three separate decisions—not one login check.

CONTINUE TO PART 02From Input to Attack Chain 6 min read · Input, execution and evidence
NEXT STEP

Find the decision that failed.

Build an assessment around your application's roles, data boundaries and workflows. Testing begins with scope and written authorization.