In the Think pathway you learned to adopt the attacker's mindset. This is where it gets concrete: the actual moves an attacker makes against an application, in roughly the order they make them. None of this is exotic. It's a methodical playbook, and once you've watched it run against your own app a few times, you stop building the gaps it relies on.
They look before they touch
The first phase is reconnaissance: gathering intelligence before sending a single malicious request. Most of it comes from things you handed over freely.
| Where they look | What it gives them |
|---|---|
| Page source, JS files | API endpoints, framework version |
/robots.txt, /sitemap.xml | Hidden pages, admin panels |
| Error messages | Stack traces, the database type |
| HTTP headers | Server software, missing security headers |
| GitHub search | Leaked credentials, internal docs |
Work from the assumption that an attacker already knows your stack and your full API surface, because by this point they usually do.
They change the numbers
Once they've mapped the endpoints, they start altering the parameters to see what the server lets them get away with:
GET /api/orders/12345 # Their own order
GET /api/orders/12346 # Someone else's?
GET /api/admin/orders # An admin endpoint with a user's token?
GET /api/orders?userId=admin&status=all
The defence is the same one the Authorisation lesson hammers on: check permissions on every request based on who is asking, not merely on whether they hold a valid token.
They try to climb
Privilege escalation is the goal of much of this, and it comes in three flavours:
| Type | Example |
|---|---|
| Vertical | A user becomes an admin |
| Horizontal | User A reaches User B's data |
| Context | A free-tier account unlocks premium features |
The usual vectors: a role field in the request body, an unsigned JWT payload they can rewrite, admin endpoints hidden only by the UI, and race conditions in the window where a permission is being checked.
They chain small bugs into big ones
This is the part developers underestimate most. A finding marked "low" is only low on its own. Stack a few together and the severity multiplies:
Low: Username enumeration
+
Low: No rate limiting on password reset
+
Medium: Predictable reset token
=
Critical: Full account takeover
So don't dismiss a low-severity bug just because it can't hurt you in isolation. Attackers don't fight your bugs one at a time.
STRIDE as a checklist
When you want to be systematic rather than intuitive, walk every endpoint through STRIDE and answer each question honestly:
| Threat | The question to ask |
|---|---|
| Spoofing | Can I pretend to be someone else? |
| Tampering | Can I modify data I shouldn't? |
| Repudiation | Can I deny I did it? |
| Information disclosure | Can I see data I shouldn't? |
| Denial of service | Can I take it offline? |
| Elevation of privilege | Can I gain more access? |
Try it on your own app
You don't need a lab. Your browser's DevTools and an intercepting proxy are enough to start.
In DevTools: watch the Network tab to catalogue every request and its parameters, check the Application tab for tokens in cookies and localStorage, and read the Sources for anything hardcoded into the client.
With an intercepting proxy (Burp Suite, OWASP ZAP), capture a normal request and then mutate it:
- Change the user ID to another user's.
- Change the role from
usertoadmin. - Strip the auth header entirely.
- Add fields the API didn't ask for to the JSON body.
Watch what the server accepts. The best moment to run this playbook against your own code is while you're still writing it, because every gap you find now is one an attacker won't.
