- George
- Posts
- Spending 2 hours a night looking for BAC bugs on Hackerone & Bugcrowd
Spending 2 hours a night looking for BAC bugs on Hackerone & Bugcrowd
2-Hour Nightly Plan to Find BAC Bugs in Modern RESTful APIs
Goal: Hunt BAC vulnerabilities (e.g., IDORs, unauthorized access) in HackerOne/Bugcrowd programs with RESTful APIs, where user/resource IDs are obscured (e.g., UUIDs like 550e8400-e29b-41d4-a716-446655440000
) and passed in paths, bodies, or headers.
Step 1: Pick a Juicy Target (10 min)
Choose a Program:
Log into HackerOne or Bugcrowd.
Select public programs with broad scopes (e.g.,
*.target.com
) or private invites for less competition.Target apps with RESTful APIs and user-driven features:
E-commerce: Order retrieval, account settings (e.g., APIs for cart, wishlist).
SaaS Platforms: User dashboards, team management (e.g., APIs for projects, reports).
Social Apps: Profiles, posts, messages (e.g., APIs for feeds, DMs).
Why? These apps manage user-specific resources (orders, files, teams) and roles (user, admin), ripe for BAC flaws despite obscured IDs.
Check bounty tables: Look for payouts for “Unauthorized Access,” “IDOR,” or “Privilege Escalation” to confirm BAC is valued.
Glance at recent reports (if public) for API-related bugs to gauge potential.
Select a Juicy URL:
Focus on API endpoints (e.g.,
api.target.com
,app.target.com/v1
) or main apps with heavy JavaScript (React, Vue) that call REST APIs.Avoid non-API assets (e.g., static
marketing.target.com
)—check scope in program policy.If possible, check the target’s API docs (e.g.,
api.target.com/docs
, Swagger UI) or blog for new endpoints (e.g., “We launched /api/v2!”)—new APIs often skip access checks.Pro Tip: Subdomains like
beta.target.com
orgraphql.target.com
may expose less-tested APIs, but confirm they’re in scope.
Step 2: Set Up and Collect Logs (40 min)
Configure Burp Suite (5 min):
Open Burp Suite (Community/Pro).
Proxy your browser through Burp.
Set scope to the target (e.g.,
https://api.target.com
) to reduce noise.Enable HTTP history logging (Proxy > Options > Log all requests).
Interact with the App (30 min):
Create Two Accounts: Register as
[email protected]
and[email protected]
(use disposable emails if needed) to test horizontal BAC later.Explore RESTful Features:
Navigate core functions: view profiles, fetch orders, manage teams, download files, or post content.
Trigger API-heavy actions: search, sort, export data, or update settings (e.g., change email, add teammate).
Look for single-page app (SPA) behavior (URL doesn’t change much)—these rely on APIs like
GET /api/v1/users/me
orPOST /api/v2/orders
.
Force API Exposure:
Open browser DevTools (Network tab) alongside Burp to spot API calls (e.g.,
fetch('/api/v1/files/550e8400...')
).Try invalid inputs (e.g., paste a random UUID in a URL like
/files/xyz
) to trigger error responses that leak endpoints.Check for GraphQL (e.g.,
/graphql
)—queryuser(id:"abc")
often exposes IDs.
Switch Accounts: Log in/out as
hunter1
andhunter2
to capture different tokens (e.g.,Authorization: Bearer xyz
). If roles exist (e.g., user vs. manager), test both.Goal: Generate Burp logs with 10–20 RESTful requests, focusing on:
Path-based IDs:
GET /api/v1/orders/550e8400-e29b-41d4-a716-446655440000
.JSON Bodies:
POST /api/v1/files
with{"file_id":"abc123"}
.Headers:
X-User-Id: def456
orAuthorization: Bearer ...
.
Quick Log Review (5 min):
In Burp’s HTTP history, filter for:
API Paths:
/api
,/v1
,/v2
,/graphql
.UUIDs/Hashed IDs: Look for long strings (e.g.,
550e8400...
,abc123xyz
) in URLs, bodies, or headers.Sensitive Methods: GET (fetch data), POST/PUT (update), DELETE (remove).
Search for keywords:
user
,account
,order
,file
,admin
,settings
.Tag 2–3 requests with obscured IDs or admin-like paths (e.g.,
GET /api/v1/users/abc123
,POST /api/v2/team
).
Step 3: Test for BAC (60 min)
Analyze Logs (10 min):
Select 2–3 requests from Burp’s logs with:
Obscured IDs: UUIDs or hashes in paths (e.g.,
/orders/550e8400...
), bodies (e.g.,{"user_id":"abc123"}
), or headers (e.g.,X-Account-Id: def456
).Admin Endpoints:
/api/v1/admin/*
,/api/v2/settings
,/api/users/list
.Sensitive Data: Responses with user info (e.g.,
{"id":"abc123","email":"[email protected]"}
) or resources (orders, files).
Ignore generic requests (e.g.,
/api/health
,200 OK
with no data).
Test Horizontal Privilege Escalation (25 min):
What: Accessing another user’s resources (e.g.,
hunter1
viewshunter2
’s files) by swapping obscured IDs.How:
Identify a request with an obscured ID, e.g.:
GET /api/v1/profile/550e8400-e29b-41d4-a716-446655440000 HTTP/1.1 Host: api.target.com Authorization: Bearer hunter1_token
Response:
{"id":"550e8400...","email":"[email protected]"}
(hunter1’s profile).
Find
hunter2
’s ID:Log in as
hunter2
, repeat the same action (e.g., view profile), and check Burp logs for their ID (e.g.,GET /api/v1/profile/6ba7b810-9dad-11d1-80b4-00c04fd430c8
).Or, if the app exposes IDs (e.g., via
/api/v1/users/me
), notehunter2
’s UUID.
Send to Repeater:
Use the original request (
/profile/550e8400...
) withhunter1
’s token (Bearer hunter1_token
).Replace the ID with
hunter2
’s (e.g.,/profile/6ba7b810...
).
Send the request.
Check Response: If you get
{"id":"6ba7b810...","email":"[email protected]"}
, it’s an IDOR—hunter1
accessedhunter2
’s data.Test Updates:
If logs show a POST, e.g.:
POST /api/v1/profile HTTP/1.1 Host: api.target.com Authorization: Bearer hunter1_token {"profile_id":"550e8400...","email":"[email protected]"}
Try
{"profile_id":"6ba7b810...","email":"[email protected]"}
withhunter1
’s token.If it updates
hunter2
’s profile, it’s a critical BAC bug.
Alt Test: If IDs are in headers (e.g.,
X-User-Id: abc123
), swaphunter1
’s ID forhunter2
’s and check for leaks.
Validate: Log in as
hunter2
(if ethical) to confirm their data was exposed (e.g., view their profile).Burp Tip: Use Comparer to diff responses (e.g.,
hunter1
’s ID vs.hunter2
’s ID) for unauthorized data.
Test Vertical Privilege Escalation (25 min):
What: Accessing admin or restricted features as a normal user (e.g.,
hunter1
lists all users).How:
Find a potential admin endpoint in logs, e.g.:
GET /api/v1/admin/users HTTP/1.1 Host: api.target.com Authorization: Bearer hunter1_token
Likely found via errors, DevTools, or clicking “Settings.”
Send to Repeater with
hunter1
’s token (normal user).Send unchanged.
Check Response: If you get
200 OK
with sensitive data (e.g.,[{"id":"xyz","email":"[email protected]"}]
), it’s a vertical BAC bug—the API didn’t enforce admin privileges.Alt Test:
Try without a token (remove
Authorization
header). A200
response means no auth check—huge flaw.If logs show role-based bodies (e.g.,
POST /api/v1/roles
with{"role":"user"}
), try{"role":"admin"}
withhunter1
’s token.
GraphQL Check (if applicable):
If logs show
/graphql
, look for queries like:POST /graphql HTTP/1.1 {"query":"{ user(id:\"abc123\") { email } }"}
Try
hunter2
’s ID or an admin-like query (e.g.,{ allUsers { email } }
) withhunter1
’s token.
Validate: Test the same endpoint with
hunter2
’s token to ensure it’s not a false positive (e.g., meant for all users).
Burp Tip: Use Copy/Paste Token in Repeater to swap
hunter1
/hunter2
tokens quickly.
Step 4: Document and Save (10 min)
If You Find BAC:
Screenshot Burp’s request/response (e.g.,
hunter1
accessinghunter2
’s UUID-based profile).Note: Endpoint (e.g.,
/api/v1/profile/6ba7b810...
), ID used, impact (e.g., “Leaked another user’s email”).Draft a report in HackerOne/Bugcrowd but verify before submitting (e.g., reproducible with both accounts).
No Bug?:
Save Burp project (
File > Save Project
) to pick up tomorrow.Tag untested endpoints (e.g.,
/api/v2/files/xyz
) for the next session.
Ethical Note: Avoid modifying data (e.g., updating
hunter2
’s profile) unless explicitly allowed. Focus on read-only tests.
Key Tips for RESTful APIs with Obscured IDs
Target Selection: Pick API-heavy programs (check for
/api
in scope). If they mention GraphQL or REST, even better.Log Focus: Search Burp for UUIDs (32+ chars, hex/dashes) or hashes (e.g.,
abc123xyz
) in:Paths:
/users/550e8400...
.Bodies:
{"file_id":"abc123"}
.Headers:
X-Resource-Id: def456
.
ID Hunting:
Obscured IDs aren’t guessable like
123
, so rely on your two accounts. Gethunter1
’s andhunter2
’s IDs from logs (e.g.,/api/v1/me
).If IDs are missing, check responses for lists (e.g.,
/api/v1/orders
may return[{"id":"xyz","user":"[email protected]"}]
) or errors leaking IDs.
Testing Speed: Test 1–2 endpoints per night (1 horizontal, 1 vertical). Repeater is key for swapping UUIDs/tokens.
Burp Hacks:
Use regex in HTTP history:
[0-9a-f]{8}-[0-9a-f]{4}
for UUIDs.Filter for
application/json
responses to spot RESTful APIs.Save tokens in Burp’s Session Handling to auto-apply
hunter1
/hunter2
.
REST Nuance: Modern APIs use PATCH or PUT for updates (e.g.,
PATCH /api/v1/users/abc123
). Test these like POSTs for unauthorized changes.
Example Night
8:00–8:10: Pick
api.target.com
(SaaS, $1,000 for IDORs, RESTful API).8:10–8:50: Register
hunter1
/hunter2
, fetch profiles, tag:GET /api/v1/users/550e8400...
(hunter1’s UUID).GET /api/v1/admin/stats
(error response hinted at admin).
8:50–9:50:
Horizontal: In Repeater, use
hunter1
’s token, swap UUID tohunter2
’s (/users/6ba7b810...
). Get{"email":"[email protected]"}
—IDOR!Vertical: Test
/api/v1/admin/stats
withhunter1
’s token. Returns{"total_users":1000}
—unauthorized access!
9:50–10:00: Screenshot Burp, save project, note findings.