API Authentication Flaws
A token the server forgot to verify, a key committed to GitHub, a login with no rate limit.
What you will learn
- -Break weak JWT handling including alg none and weak secrets
- -Find leaked API keys and understand what access they grant
- -Attack login, reset, and token flows that skip the basic checks
Most auth is one signed doing all the work. Break how that token is issued or verified and you skip the login entirely. This is API2 on the OWASP list, right behind BOLA, and it fails in a handful of predictable ways that you can check in minutes.
Start with the , because it is everywhere. A Web Token is three base64url chunks joined by dots: , , . Paste one into jwt_tool or just decode the middle chunk and read it. It is not encrypted. Anyone holding it can see the inside, including the alg, the role, and the expiry.
$echo 'eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiYm9iIiwicm9sZSI6InVzZXIifQ.sig' | cut -d. -f2 | base64 -dThe JWT mistakes worth checking
The classic is alg:none. The JWT spec allows an unsigned token where the algorithm is literally none and the signature is empty. If the honors it, you forge any token you like: set "role":"admin", strip the signature, send it.
$jwt_tool <token> -X a$jwt_tool <token> -C -d rockyou.txt$jwt_tool <token> -X k -pk public.pemWeak is the next one. If the token is signed with HS256 and the developer used a guessable secret like secret or changeme, you crack it offline with jwt_tool or hashcat -m 16500 against rockyou.txt, then sign your own forged tokens with the recovered key. No further access to the server needed.
Algorithm confusion is the subtle one. A server that expects RS256 (public/ pair) but verifies with a function that also accepts HS256 can be tricked: sign a forged token with using the server's as the secret. The server verifies with the same public key and accepts it. Look for this when the public key is downloadable, which it usually is.
Then check the boring stuff that wins anyway. Does the token actually expire? Copy a token, wait, resend an hour later. Does logout invalidate it server-side, or does the token keep working after you sign out? A token that lives forever means one leak is permanent.
Leaked keys
Static API keys do not expire and do not care where they come from, which makes a leaked one pure gold. They land in public GitHub repos, in bundles served to the browser, in mobile app binaries, in error messages.
$trufflehog git https://github.com/target/repo$gitleaks detect --source . -v$curl -s https://target.tld/main.js | grep -Eo '(sk_live|AKIA|ghp_)[A-Za-z0-9]+'Prefixes tell you what you found. sk_live_ is a Stripe live secret key, AKIA starts an AWS id, ghp_ is a GitHub personal , xoxb- is a Slack bot token. Check the commit history, not just the current files, because a key deleted in a later commit is still sitting in the git for anyone who clones.
The login flow itself
Auth breaks at the around the token too. The most common miss is no rate limit on POST /login, which hands you unlimited stuffing and spraying. Fire a few hundred attempts and watch whether anything slows you down. Nothing slowing down is the finding.
Password reset is the other soft spot. A reset token that is short, sequential, or derived from a timestamp is guessable. A reset flow that leaks whether an email exists (different response for a known versus unknown address) hands you a valid-user list to spray against.
Cracking tokens, forging JWTs, and brute-forcing logins are all real attacks with real legal weight. Run them only against OWASP crAPI, VAmPI, PortSwigger labs, or systems you are contracted to test. A leaked key you find in a public repo is not permission to use it: report it, do not log in with it.
A JWT arrives with header alg:HS256. You resend it with the header changed to alg:none and the signature removed, and the server accepts it. What did you just prove?