Bug bounty payout benchmarks (2025–2026)
Selected program totals and per-finding payout ranges

Five real disclosed bug-bounty payouts from 2025–2026 — a $24,000 Meta OAuth chain, a critical SSRF in HackerOne's own platform, two IDOR/BOLA findings (one paying $15,000), and a WAF documentation flaw — each broken down by vuln class, program, and the skill ladder a beginner needs to get there.

| # | Vuln class | Platform | Program | Payout |
|---|---|---|---|---|
| 1 | OAuth / session theft chain | HackerOne | Meta (Facebook/Instagram) | $24,000 |
| 2 | SSRF via analytics webhook | HackerOne | HackerOne (self) | Critical / disclosed |
| 3 | IDOR in OOO calendar API | HackerOne | Nextcloud | Disclosed |
| 4 | IDOR in user profile API | Private program | Anonymous | $15,000 |
| 5 | WAF config logic flaw | Google VRP | Google Cloud Armor | $500 |
Note: The original planned time window had limited fresh disclosures at press time. This inaugural issue draws on disclosed reports from late 2025 and early 2026 to demonstrate the format. Starting with Issue #2, coverage will tighten to a rolling 7-day window.
datr) through crafted OAuth/Graph API batch requests. The datr cookie is what Meta uses to recognize a device as "trusted" — once an attacker holds it, they can trigger trusted-device account recovery and bypass secondary verification, including by supplying AI-generated identity documents. The fix required tightening which API endpoints could surface device identifiers in batch responses.| Level | What you need | Resources |
|---|---|---|
| 0 → Beginner | Understand OAuth 2.0 flows (authorization code, implicit) | PortSwigger OAuth labs |
| 1 → Intermediate | Learn Meta's Graph API batch request format; read old Graph API write-ups | Meta developer docs |
| 2 → Practitioner | Understand "trusted device" recovery flows; map which endpoints touch device identifiers | Sammouda's full writeup at ysamm.com |
| 3 → Advanced | Chain access across account recovery + AI-generated bypass vectors | Practice on bug-bounty-style sandboxes |
169.254.169.254, GCP metadata server, etc.). A server-side fetch to these addresses returns temporary credentials, internal IPs, and configuration data. An SSRF that reaches metadata is typically rated Critical because it's a near-direct path to credential theft.| Level | What you need |
|---|---|
| 0 → Beginner | Understand HTTP request flow: what a server-side fetch looks like vs client-side |
| 1 → Intermediate | Learn cloud metadata endpoint structure (AWS IMDSv1 vs v2, GCP); practice SSRF labs on PortSwigger |
| 2 → Practitioner | Identify where apps make outbound requests: webhooks, PDF renderers, URL preview features, analytics exporters |
| 3 → Advanced | Bypass SSRF filters: IP encoding, DNS rebinding, open-redirect chains |
/ocs/v2.php/apps/dav/api/v1/outOfOffice/{userId} and .../outOfOffice/{userId}/now checked authentication but not authorization. An authenticated user could read another user's private OOO settings — including vacation dates, travel status, and personal message — by substituting any valid userId in the path. In the researcher's proof of concept, they read Alice's OOO data (vacation dates December 20, 2025 – January 5, 2026, travel destination) from Bob's account with no privileged role.| Level | What you need |
|---|---|
| 0 → Beginner | Understand the difference between authentication (who are you) and authorization (what are you allowed) |
| 1 → Intermediate | Learn OWASP API Top 10 — API1 Broken Object Level Authorization; practice on PortSwigger API labs |
| 2 → Practitioner | Intercept API calls in Burp Suite; identify object identifiers in URL paths and request bodies; test substitution |
| 3 → Advanced | Enumerate IDs systematically; test across API versions; find endpoints where sensitive data (PII, business logic) sits behind BOLA |
userId parameter that was not enforced against the authenticated session; any authenticated user could view, modify, or delete any other user's private profile data by changing the ID.if (request.headers['host'].lower().contains('test.example.com')) { allow all; }test.example.com.attacker.com would pass the contains() check and bypass all WAF rules. The correct pattern — endsWith('.example.com') — was absent from the published docs. Google fixed the documentation and paid $500.| Level | What you need |
|---|---|
| 0 → Beginner | Learn WAF/firewall logic: how rules are evaluated, string matching vs regex |
| 1 → Intermediate | Read vendor documentation critically — test whether the examples actually work as described |
| 2 → Practitioner | Understand hostname parsing edge cases; contains() vs startsWith() vs endsWith() vs regex |
| 3 → Advanced | Systematically audit documentation for patterns that produce insecure defaults when followed literally |
Add more perspectives or context around this Post.