Angry Teacher
Mr. Garrison's grading system has a few security shortcuts. You're a student with four failing grades and a parent-teacher conference looming — find the leak, change your grades, walk out with the flag.
The Scenario
South Park Elementary's grading portal is held together by a single developer's bad day. You log in as one of Mr. Garrison's struggling students, see all your failing grades, and somewhere on the page is a thread to pull. The teacher's API key is around here somewhere; once you find it, the rest writes itself.
Lab Intel
Synopsis
A static API key shipped to the browser via console log and HTML comment grants access to a backend PUT endpoint that authenticates the key but never checks resource ownership — a classic credential leak chained with broken object-level authorisation.
Architecture
An easy-difficulty three-container lab: a React frontend, a Node.js + Express backend backed by SQLite, and an nginx gateway routing both. The lab is built around the gap between authentication (proving who you are) and authorisation (proving you should be allowed to act on a given resource): the backend trusts any request that carries the right Authorization header, regardless of which user is being modified.
Who It's For
Designed for beginners learning client-side reconnaissance and authorisation flaws. You should be comfortable with HTTP requests and the basics of browser DevTools — the Console and Elements tabs specifically. No prior React or Node.js experience required; everything you need is reachable from the browser.
Skills You'll Practice
- Reading the browser console and inspecting page source for credentials that should never have shipped to the client
- Distinguishing authentication from authorisation when auditing API access control
- Crafting PUT requests from the browser with custom Authorization headers using fetch()
- Recognising Insecure Direct Object Reference (IDOR): a key that works for any object id it is pointed at
- Treating client-side artefacts (console logs, HTML comments, source maps) as a public surface, not a hidden one
What You'll Gain
- A mental model for why any secret shipped to a browser is, by definition, public
- Recognition that 'requires API key' is an authentication check, not an authorisation check
- Understanding why per-user tokens with scoped permissions beat a single shared API key for any endpoint that mutates resources
- Practical experience using browser DevTools as a primary reconnaissance tool, not just a debugger
- Awareness of how a stateless API design can collapse if the key carries no notion of subject or scope