Authentication and Authorization Attacks
Concepts
Authentication vs. Authorization
Authentication is verifying who the user is - confirming the user is who they claim to be. Authorization (Access Control) is verifying what the user is allowed to do.
Analogy: At the airport you show your passport to check-in staff - that’s authentication. At the gate you show your boarding pass - that’s authorization. Two separate checks, two separate controls.
Authentication Attacks
Brute Force (Single Parameter)
When a login form has no lockout or IP rate limiting, you can automate credential guessing with ffuf.
Steps:
- Enable Burp Suite intercept and submit any login request - observe the parameters and headers.
- Save the request: right-click → Copy to file → e.g.
auth0x01.req - Identify the parameter to fuzz (e.g.
username=jeremy&password=jeremy). - Replace the target parameter value with
FUZZ:username=jeremy&password=FUZZ - Run ffuf:
ffuf -request auth0x01.req -request-proto http -w /usr/share/wordlists/seclists/Passwords/Common-Credentials/xato-net-10-million-passwords-10000.txt:FUZZ -ac -c -v - Examine the result - look for a response with a different size or status code:
[Status: 200, Size: 1808, Words: 494, Lines: 47] * FUZZ: letmein
Tip:
-ac(auto-calibrate) filters out baseline responses automatically. If your wordlist is very small (<~100 entries), ffuf may not have enough data to calibrate - check size/status manually instead.
Cluster Bomb Brute Force (Unknown Username + Password)
Use this when you don’t know either credential. It tests every combination of username × password.
Important: If the application locks accounts after N failed attempts, keep your password list to N-1 entries (e.g. top 4 passwords) and iterate across many usernames instead of locking one account.
Steps:
- Enable Burp Suite intercept and submit a login request.
- Save the request to
auth0x03.req. - Replace both parameters with distinct keywords:
username=FUZZUSER&password=FUZZPASS - Create a short password list if needed:
printf '123456\npassword\npassword123\nletmein\n' > pass.txt - Run ffuf in cluster bomb mode:
ffuf -request auth0x03.req -request-proto http -w /usr/share/wordlists/seclists/Usernames/top-usernames-shortlist.txt:FUZZUSER -w pass.txt:FUZZPASS -mode clusterbomb -c -v - With a small wordlist, skip
-acand compare response sizes manually - a successful login will have a noticeably different size.
Attacking MFA
MFA adds a second verification step. Common weaknesses to test:
| Question | Attack |
|---|---|
| Is the code short / numeric only? | Brute force the token |
| Does the code expire? | Reuse a captured token |
| Can one token be used for multiple users? | Submit token with a different username |
| Is the username submitted again at the MFA step? | Intercept and swap it |
Intercept & Username Swap Attack:
- Log in with your own account (e.g.
jessamy:pasta) and reach the MFA step. - Obtain your valid MFA token.
- Before submitting, turn on Burp intercept.
- In the intercepted request, change the
usernamefield to the victim’s username (e.g.jeremy). - Forward the request - if the application validates the token independently of the username, you log in as the victim.
The root cause: the server trusts the
usernamevalue in the MFA POST body rather than binding the MFA session to the authenticated identity from step 1.
Authorization Attacks
Vertical vs. Horizontal vs. Context-Dependent Access Control
| Type | Definition | Example |
|---|---|---|
| Vertical | Restricts functions by role | Regular user can’t access admin panel |
| Horizontal | Restricts resources by owner | User A can’t read User B’s profile |
| Context-dependent | Restricts based on application state | Can’t check out with an empty cart |
When any of these controls is missing or bypassable → Broken Access Control.
IDOR - Insecure Direct Object Reference
Occurs when an application exposes an internal identifier (ID, number, filename) in a request and fails to verify the requester is authorized to access that object.
Example URL: http://target.com/account?id=1009
Best practice on bug bounties: Always use two accounts you control (User A and User B). Access User B’s data using User A’s session. This limits your blast radius to your own test accounts.
Brute-forcing IDs with ffuf:
Generate a number range:
seq 1000 9999 > 1000-9999.numFind all accessible accounts:
ffuf -u 'http://localhost/labs/e0x02.php?account=FUZZ' -w 1000-9999.num -c -vFind accounts with a specific attribute (e.g. admin):
ffuf -u 'http://localhost/labs/e0x02.php?account=FUZZ' -w 1000-9999.num -c -v -mr "Type: admin"When you find admin usernames via IDOR, treat them as targets for credential attacks - you now have a valid username list.
API note: In API-driven apps, IDOR is called BOLA (Broken Object Level Authorization) - same concept, different name.
Broken Access Control - Manual Test
Setup:
- Always create / use two accounts: User A and User B
- Capture both sessions/tokens
What to look for in requests:
- Any parameter identifying a user:
username,user_id,email,account_number,account - If present in the URL, body, or headers → it’s a candidate for testing
The Test:
- Perform an action as User A (view profile, update bio, access a resource)
- Intercept the request in Burp Suite
- Keep User A’s session token but change the user identifier to User B’s
- Send the request - if it succeeds → Broken Access Control
JWT Tokens
JSON Web Tokens are commonly used for API authentication.
Structure: header.payload.signature (each part is Base64-encoded, separated by dots)
eyJhbGciOiJIUzI1NiJ9 ← header
.eyJ1c2VyIjoiamVyZW15In0 ← payload (claims: user, role, etc.)
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c ← signature
- Decode manually:
echo "PAYLOAD_PART" | base64 -d - Or paste the full token into https://jwt.io
Where to find them in requests:
Authorization: Bearer <token>header- Cookies (e.g.
session=<token>) - Query string or request body
Key things to test:
- Is the signature verified? (If missing → tamper with claims)
- Can you change
role: stafftorole: admin? - Full JWT attack coverage → see API Hacking course or jwt.io docs
API Endpoints - Reference
Login:
curl -X POST -H "Content-Type: application/json" -d '{"username": "admin", "password": "password123"}' http://localhost/labs/api/login.phpGet account info:
curl -X GET "http://localhost/labs/api/account.php?token=<JWT>"Update account (PUT):
curl -X PUT -H "Content-Type: application/json" -d '{"token": "<JWT>", "username": "jeremy", "bio": "New bio."}' http://localhost/labs/api/account.phpBFLA (Broken Function Level Authorization): Using User A’s token to call a write endpoint targeting User B. Same idea as IDOR - just at the function/action level rather than the object level.
Autorize - Burp Suite Plugin
Autorize automates horizontal privilege testing across many endpoints. Instead of manually duplicating every request, it automatically replays each request using a second user’s token and flags whether authorization was bypassed or enforced.
Setup:
- Install Jython standalone JAR from jython.org
- In Burp Suite: Extensions → Extension Settings → set Jython JAR path
- BApp Store → install Autorize
- In the Autorize tab, paste User B’s session token/cookie into the token field → click OK → turn Autorize on
How to use:
- Browse the app as User A (normal actions: view profile, update bio, access restricted areas)
- Autorize automatically replays each request using User B’s token
- Review the results:
- Bypassed → User B can perform User A’s action → Broken Access Control finding
- Enforced → properly blocked
- Is enforced?? → status codes matched but response body differed → investigate manually
Autorize is especially valuable for large apps with 20+ endpoints where manual testing becomes error-prone.
Checklists
Authentication Testing Checklist
Login Form
- Is there a rate limit or lockout on failed attempts?
- Is the lockout per-IP, per-account, or both? (per-IP only → rotate IPs to bypass)
- Does the error message reveal whether the username or password was wrong? (username enumeration)
- Is there a username enumeration vector via response timing?
- Is there a “remember me” option? Where is the token stored, and how long does it last?
- Does the login endpoint accept JSON as well as form data? (potential WAF bypass)
Brute Force
- No lockout → brute force password for a known username
- Lockout present → cluster bomb with many usernames + top 3-4 passwords
- CAPTCHA present → test if it can be reused, removed, or bypassed
MFA
- How many digits is the OTP? (≤6 numeric → brute force candidate)
- Does the OTP expire? What is the window?
- Can the same OTP be used more than once?
- Is the username re-submitted at the MFA step? → swap it to another user
- Is there a fallback method (SMS, email, backup code)? Test each independently
- Can you skip the MFA step entirely by going directly to a post-login URL?
- Does the MFA session cookie work for a different account?
Password Reset
- Is the reset token guessable or short?
- Does the reset token expire?
- Can a reset token be used more than once?
- Is the token leaked in a
Refererheader when clicking a link in the reset email? - Can you reset another user’s password by manipulating a parameter (e.g.
email=victim@x.com)?
Registration
- Can you register with an existing username/email (account takeover via duplicate)?
- Is email verification enforced, or can you use a fake address?
Authorization / Access Control Checklist
Setup (always do this first)
- Create two accounts at the same privilege level: User A and User B
- If roles exist, also create/access an Admin account
- Capture all sessions/tokens before starting
Horizontal Privilege Escalation (IDOR / BOLA)
- Identify every parameter that references a resource by ID (
id=,account=,user_id=,file=, etc.) - Substitute User B’s identifier while authenticated as User A
- Test in URL query string, request body, and headers/cookies
- Test all HTTP methods: GET (read), POST (create), PUT/PATCH (update), DELETE
- Test indirect references too - e.g.
filename=report.pdf→ tryfilename=../other_user/report.pdf - For APIs: brute-force ID ranges to enumerate objects (ffuf +
-mr)
Vertical Privilege Escalation
- As a standard user, directly request admin-only URLs (e.g.
/admin,/dashboard/admin) - As a standard user, call admin-only API endpoints
- Remove or downgrade the role claim in a JWT and check if signature is verified at all
- Check if adding
?admin=trueor&role=adminto a request changes behaviour
Function-Level Authorization (BFLA)
- With User A’s token, call every write/delete endpoint targeting User B’s data
- Use Autorize plugin to automate replay of all requests with User B’s token
- Check if lower-privilege roles can access higher-privilege functions even if the UI hides them
State & Context
- Can you access a later step in a multi-step flow directly (e.g. skip payment, go to confirmation)?
- Can you replay a single-use action (e.g. re-submit a completed order)?
- Does the app enforce ownership checks on file downloads/exports?
JWT & Session Management Checklist
Token Discovery
- Where is the token stored? (Authorization header, cookie, localStorage, query string)
- Is it a JWT? Paste into https://jwt.io to inspect claims and algorithm
JWT-Specific Attacks
- Is the signature present? If not → freely tamper with claims
- Algorithm
noneattack: strip the signature and set"alg": "none"in the header - RS256 → HS256 confusion: if the server accepts both, sign with the public key as the HMAC secret
- Weak secret: try cracking with
hashcat -a 0 -m 16500 <token> wordlist.txt - Can you change
"role": "user"to"role": "admin"in the payload? - Does the
kid(key ID) header allow path traversal or SQL injection?
Session Tokens (non-JWT)
- Is the token random enough? Capture 10+ tokens and check for patterns
- Does the token change after login? (session fixation risk if not)
- Does the token change after privilege escalation (e.g. after MFA completes)?
- Is the token invalidated server-side on logout?
- Does the token expire? What is the idle and absolute timeout?
- Is the session cookie scoped with
HttpOnly,Secure, andSameSite?
Token Transmission
- Is the token ever sent in a URL query string? (exposed in logs, Referer headers)
- Is the token sent over HTTP anywhere?
API Access Control Checklist
- Create (or compromise) two accounts - User A and User B
- Capture both sessions/tokens
- With User A’s token, call every read endpoint targeting User B’s identifier
- With User A’s token, call every write endpoint targeting User B’s identifier
- Check if role claims in JWT can be tampered with
- Test vertical access: can a standard user reach admin-only endpoints?
- Test undocumented endpoints - try common paths (
/api/v1/admin,/api/users,/api/debug) - Test all HTTP methods on each endpoint - server may accept DELETE even if docs don’t mention it
- Check if API versioning exposes older, less-secured endpoints (
/api/v1/vs/api/v2/) - If successful → Broken Access Control (IDOR / BOLA / BFLA depending on context)