Skip to content

Add OpenAPI spec and gate the navigation on session state - #21

Merged
krishnareddypadala merged 1 commit into
masterfrom
feat/openapi-and-nav
Jul 29, 2026
Merged

krishnareddypadala merged 1 commit into
masterfrom
feat/openapi-and-nav

Conversation

@krishnareddypadala

Copy link
Copy Markdown
Owner

Two requested changes. 77 tests passing.

OpenAPI 3.1 spec

  • GET /api/v2/openapi.json — the document, unauthenticated
  • GET /docs — Swagger UI

Hand-written rather than generated, because the useful part isn't the request shapes — it's these two annotations on every operation:

  • x-vuln — the lessons that operation carries (VULN-01, VULN-11, …)
  • x-auth-enforced — whether authentication is actually required

Where x-auth-enforced is false, the endpoint needs no auth and should. Labelling those turns the broken-access-control lessons into something a student can enumerate from the spec rather than stumble across. A generator would produce the request shapes and miss this entirely.

Serving the inventory unauthenticated is itself worth noticing — a complete machine-readable list of every endpoint including the webshell. Real deployments leak exactly this (OWASP API9). Here it's deliberate, because the map is the teaching material.

Swagger UI loads from a CDN, so /docs degrades on an air-gapped lab to a table built from the locally-served spec. The spec endpoint never depends on the CDN.

Navigation gated on session

Signed-out visitors now see only Login, Register and API Docs.

This is presentation only and it closes nothing. NavigationVisibilityTest pins that down — with no session at all it asserts that account lookup, admin activation, the KYC listing and the webshell are all still reachable:

$this->getJson('/api/v2/accounts/2')->assertOk();
$this->post('/api/v2/admin/activate', ['user' => 'srikanth'])->assertOk();

If someone later adds auth middleware to those routes to "match" the nav, that test fails and the lessons survive.

It arguably sharpens VULN-12. Previously every link was visible, so "the UI is not a control" was easy to assume. Now the interface genuinely looks gated and the endpoints still aren't — a learner has to notice that hiding a link changed nothing, which is the whole point of broken function-level access control.

Drift protection

OpenApiSpecTest fails in both directions: an API route missing from the spec, or a spec path that doesn't exist. A hand-written document's main failure mode is quiet decay, so that's now a test failure instead.

🤖 Generated with Claude Code

OpenAPI 3.1 document at /api/v2/openapi.json, plus a Swagger UI page at
/docs. Hand-written rather than generated, because the useful part is
not the request shapes -- it is the x-vuln annotation naming the lessons
each operation carries, and x-auth-enforced showing whether the endpoint
actually requires authentication. A generator produces the former and
misses the latter entirely.

Where x-auth-enforced is false the endpoint requires no authentication
and should. Labelling those is the point: it turns the broken access
control lessons into something a student can enumerate rather than
stumble across.

Swagger UI loads from a CDN, so the page degrades on an air-gapped lab
to a table built from the locally served spec. The spec endpoint itself
never depends on the CDN.

Navigation now renders from session state -- signed-out visitors see only
Login, Register and API Docs.

This is a UI change ONLY and it closes nothing. NavigationVisibilityTest
pins that down: it asserts, with no session at all, that account lookup,
admin activation, the KYC listing and the webshell are all still
reachable. If someone later adds auth middleware to those routes to
"match" the nav, that test fails and the lessons are preserved.

It arguably sharpens VULN-12. Previously every link was visible, so "the
UI is not a control" was easy to assume. Now the interface genuinely
looks gated and the endpoints still are not, so a learner has to notice
that hiding a link changed nothing.

Also adds OpenApiSpecTest, which fails if the spec drifts from the real
route table in either direction -- undocumented routes or documented
routes that do not exist.

Suite is now 77 tests.
@krishnareddypadala
krishnareddypadala merged commit 11de2b8 into master Jul 29, 2026
3 checks passed
@krishnareddypadala
krishnareddypadala deleted the feat/openapi-and-nav branch July 29, 2026 21:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant