How Modern APIs Work
The app you are testing is mostly a thin shell over an API doing all the real work.
What you will learn
- -Read a REST request and name every part that matters to an attacker
- -Explain how bearer tokens and API keys authenticate a request
- -Spot why the API tier is a bigger attack surface than the website
Open the tab on any modern web app and click one button. You will see a burst of requests to /api/v2/orders, /api/user/me, /graphql, all returning . The pretty page is a . The underneath is where the accounts, the orders, and the money live, and that is what you are actually attacking.
A API is with discipline. The names a thing, the method says what to do with it, and the body carries the data. That's the whole model, and once you see it you can read any on sight.
GET /api/v2/users/1042 read user 1042
POST /api/v2/users create a user
PATCH /api/v2/users/1042 update part of user 1042
DELETE /api/v2/orders/8890 delete order 8890
The method carries meaning that developers lean on for access , which is exactly why they it wrong. An app might block DELETE in the UI but leave the method live on the . Change the verb, keep the URL, and see what happens.
The pieces that matter
Every request has four parts you will poke at: the method, the path, the , and the body. The path holds object identifiers (/users/1042), and those numbers are the first thing you tamper with. The headers carry and content type. The body, usually JSON, holds the fields you will add, remove, and lie about.
$curl -i https://target.tld/api/v2/users/1042 -H "Authorization: Bearer eyJhbGciOiJIUzI1..."JSON is just keys and values, and it lies as easily as it reads. A registration endpoint might accept {"email":"you@x.tld","role":"user"}. Add "role":"admin" and resend. If the server trusts fields the UI never showed you, you just escalated. That is mass assignment, and it is common because developers bind the whole straight to a database object.
How the API knows who you are
HTTP is stateless. Every request stands alone, so the API re-checks who you are on each one, and it does that with a or a key you carry in a header.
A , usually a , is a signed blob the server hands you at login. You attach it to every request in Authorization: Bearer <token>. Whoever holds the token is the user, full stop, which is why a leaked token in a or a URL is game over.
An API key is a long static string like sk_live_51H... that identifies an app or account. Keys get committed to public GitHub repos constantly. That is not a rare mistake, it is a daily source of real breaches, and searching a target's repos for one is recon.
Practice against APIs built to be attacked: OWASP crAPI, the VAmPI project, PortSwigger's API labs, or an app you own. Sending crafted requests to a production API you are not cleared to test is unauthorized access under the CFAA and similar laws worldwide.
The reason APIs are the softer target: the browser front end funnels you through forms and buttons, but the API exposes hundreds of endpoints directly, many of them undocumented, most of them assuming a well-behaved . Nobody is a well-behaved client. You send the request the app never expected, and the checks it skipped become your way in.
An API uses Authorization: Bearer with a JWT. You find one of those tokens sitting in a server access log. What does that get you?