Skip to content
Categoria: Pentest8 min read

REST and GraphQL API Pentest: Technical Checklist for Legal Bug Bounty

Por Lucas Andrade ·

Hands-on methodology for testing REST and GraphQL APIs in authorized programs, focused on IDOR, authentication bypass and malicious introspection.

REST and GraphQL API Pentest: Technical Checklist for Legal Bug Bounty

APIs became the most lucrative surface in any serious bug bounty program, and also the most ignored by pentesters still chasing XSS in contact forms. An IDOR on /api/v3/users/{id}/invoices can pay three to eight thousand dollars on HackerOne, while a reflected XSS on a marketing page closes at 250. The Basilisk OffSec team compiled in this checklist the exact flow we use in authorized engagements and public programs like GitLab, Shopify and Reddit. Before anything else: read the scope, confirm the brand domain, and never touch endpoints outside the list. Everything here assumes written authorization, and everything is framed against the OWASP API Security Top 10 (2023).

Authorization and scope first, always

Before any tool starts, only one question exists: am I allowed to touch this. Bug bounty without scope confirmation is not a pentest, it is an incident. Read the policy document, note the in-scope domains, the explicitly excluded endpoints (often /admin or payment flows) and the forbidden techniques (almost always DoS and social engineering). Record the date, the program version and your test account. This discipline is not bureaucracy, it is the difference between a paid bounty and a criminal complaint. Legal bug bounty is discipline before creativity.

Map the attack surface before firing any payload

The starting point is never Burp open on your face. It is surface mapping. Grab the mobile app with apktool, extract URL strings, load them into Burp as a manual sitemap. Run ffuf with the api-endpoints-res.txt wordlist from SecLists against paths like /api/, /v1/, /internal/, /graphql, /gql, /query. Wayback Machine via gau and waybackurls surfaces deprecated endpoints nobody patched. In a recent engagement we found a /api/v1/admin/export inherited from 2019 that accepted a regular user token, similar to what we describe in Web Pentesting From Scratch: Building a Safe Lab with DVWA, Juice Shop and Burp Suite. Document each endpoint with method, expected content-type and required role before throwing any payload.

During mapping it pays to compare behavior per version and per client. Older API versions (/api/v1 alongside /api/v3) often carry weaker authorization because they are kept alive for legacy clients; that is exactly where the forgotten endpoints sit. Also compare the web versus the mobile response of the same endpoint: mobile backends frequently return more fields (internal IDs, email, roles) because the client supposedly filters them. For each endpoint, note which role may call it, which parameters it accepts, and whether it has a second context (for example a URL fetched server-side later) - that secondary context is the root of many SSRF and injection chains. A complete map is worth more than any single payload because it tells you where to even look.

IDOR/BOLA: the most expensive REST bug

IDOR remains bug number one in REST APIs for a simple reason: developers trust the ID from the JWT but read the ID from the URL. Create two accounts on the target app, capture both sessions in Burp, and use the Autorize or Auth Analyzer extension to replay every request from account A with account B cookie. Watch for 200 responses with different bodies, not just status codes. UUIDs are not protection: enumerate them via search endpoints, CSV exports or notifications. Test the write side too: PUT and DELETE with a foreign ID, because read IDOR is info disclosure but write IDOR is account takeover.

Injection logic also applies in APIs, as we covered in SQL Injection in Practice: Exploiting, Detecting and Mitigating in a Controlled Lab, especially on sort, order and search filters that end up as SQL concatenation. A ?sort=name)-- or a boolean delay in the JSON body often reveals that the parameter flows unprotected into the query. Never report a SQLi without a reproducible, non-destructive proof (no DROP, no UPDATE), just extraction of a harmless value like the DB version.

GraphQL changes the game

GraphQL changes the game. Start by probing introspection on /graphql with the query {__schema{types{name fields{name}}}}. If open in production, you already have half the report written. Tools like InQL, GraphQL Voyager and clairvoyance reconstruct schemas even with introspection disabled via field stuffing. Hunt for exposed mutations like adminUpdateUser, impersonate, exportAllData. Batch queries bypass rate limits: send 1000 login mutations in a single HTTP request. Alias overloading breaks naive validators. Unlike what we covered in Modern XSS: DOM, Stored and Reflected With Real Examples in a Test Lab, here impact is almost always logic-based, not script injection.

Auth bypass goes far beyond the none algorithm

Authentication bypass in this context goes beyond the classic none algorithm in JWT. Test jku and kid injection, swap RS256 to HS256 using the public key as secret, and refresh tokens that never expire. Headers like X-Original-URL, X-Rewrite-URL, X-Forwarded-For and X-User-Id frequently bypass auth middleware when the API sits behind a misconfigured gateway. In GraphQL, verify the @auth directive covers every field or if some nested resolver leaks data without checks. Also test token expiry logic: a revoked token still accepted after logout is a clean, well-paid report.

SSRF, mass assignment and business logic

SSRF also appears in APIs that accept a URL as a parameter for webhooks or avatars, a pattern detailed in SSRF Demystified: Exploiting Cloud Metadata in a Local AWS Lab with exploits against AWS IMDS. For mass assignment, add fields like isAdmin:true, role:owner, verified:true to any PATCH or PUT; frameworks like Rails and NestJS with incomplete whitelists hand admin on a plate. Business logic is the class scanners never find: negative quantities, currency swaps between price calculation and charge, double coupon application. These bugs require you to understand the business flow, not just the protocol.

Rate limiting and race conditions

Rate limiting, tested properly, is rarely a bounty on its own, but the multiplier for other bugs: missing on the OTP or login endpoint means a 6-digit code is brute-forced in minutes. For race conditions on coupon or withdrawal endpoints, use Turbo Intruder with James Kettle single packet attack, firing 30 simultaneous requests; if a 50-dollar coupon redeems five times, you have a financial impact report. Combine race with business logic: the classic double withdrawal where the balance check and the debit are not atomic.

File uploads, deserialization and hidden parameters

Two bug classes often go unchecked in API testing and pay well. First, file uploads: test every upload endpoint for content-type confusion (a PHP or SVG payload declared as image/png), path traversal in the filename (../../avatar.php), missing size and MIME validation, and, when image processing happens server-side, ImageMagick or ffmpeg chains that lead to RCE or SSRF. Second, deserialization: APIs that accept serialized objects in cookies, headers or bodies (Java, .NET, PHP, Python pickle, Ruby Marshal) are a direct path to RCE if a gadget chain exists. Look for base64 blocks that start with known magic bytes (rO0 for Java, ac ed in hex). Add parameter mining with Arjun or param-miner: many APIs process undocumented fields like debug=true, preview or internal that never appear in the official docs and bypass authorization checks. All three classes need a clean, non-destructive PoC and belong only in authorized targets.

Reporting: why impact pays, not technique

Document impact with the number of records exposed, estimated financial value and a reproducible curl PoC. Programs pay for demonstrated impact, not for technique. Build a report template with CWE title, numbered steps, raw request, truncated response and one-line fix suggestion. Submit early, before duplicates land, but never without confirming scope. A clean, concise report with clear impact is paid faster and higher than a wall of text full of speculative scenarios.

Practical checklist

(1) scope and authorization confirmed in writing. (2) surface fully mapped (mobile, Wayback, ffuf). (3) IDOR/BOLA read and write with two accounts. (4) GraphQL introspection, batch, alias, exposed mutations. (5) JWT: alg confusion, kid/jku, expiry, revocation after logout. (6) mass assignment on every write endpoint. (7) SSRF on every URL parameter. (8) rate limit on auth flows and race on money flows. (9) business logic against the real flow. (10) report with impact, PoC and fix.

FAQ: What should a beginner start with?

With IDOR/BOLA. It is the most common, easiest to prove and well-paid bug, and it only needs two test accounts and Burp with Autorize. Build intuition first in your own lab, like our DVWA/Juice Shop setup, before touching a real program. Once you find IDOR reliably, extend into GraphQL and JWT misconfigurations, which are technically related and often appear together in modern APIs.

FAQ: How do I avoid accidentally breaking scope?

Configure Burp with a strict target scope and enable "Drop out-of-scope requests" so no tool accidentally hits foreign hosts. Skip automated active scanners if the policy does not allow them, and never fire high-volume attacks (which can count as DoS). When in doubt, ask the program through the official channel before testing. The most expensive mistake is not a missed bug but a test outside authorization.

Conclusion

Legal bug bounty is discipline before creativity, and in that discipline Basilisk builds reputation across programs like Mercado Livre and Nubank. The flow is reproducible: scope, mapping, systematic pass through the API bug classes, clean impact report. Whoever internalizes this process finds more and better bugs than someone throwing payloads blindly, and does it within the rules, which long term is the only path that pays.

Related posts

Nenhum comentário ainda

Seja o primeiro a comentar.

Deixe seu comentário

Entre com sua conta Canverly para comentar. Você pode usar a mesma conta em qualquer site da rede.

Entrar com Canverly