Add OpenAPI spec and gate the navigation on session state - #21
Merged
Merged
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two requested changes. 77 tests passing.
OpenAPI 3.1 spec
GET /api/v2/openapi.json— the document, unauthenticatedGET /docs— Swagger UIHand-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 requiredWhere
x-auth-enforcedisfalse, 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
/docsdegrades 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.
NavigationVisibilityTestpins that down — with no session at all it asserts 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 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
OpenApiSpecTestfails 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