A bug bounty programme is a written invitation from an organisation to test specific systems, under specific rules, and report what you find in exchange for recognition or a reward. The invitation is everything: the same request that earns a reward inside a programme’s scope can be a criminal offence outside it. So the first skill in bug bounty isn’t hacking. It’s reading.
This guide covers how programmes work, how to read a programme brief, what safe harbour does and doesn’t protect, the platform rules that get beginners banned, and a report format that triage teams can act on. It deliberately says nothing about how much you might earn. Rewards vary enormously, most beginners earn little or nothing in their first months, and anyone promising otherwise is selling something.
How do bug bounty programmes work?
Three models are worth knowing:
- Vulnerability disclosure programme (VDP). The organisation publishes a way to report security issues and promises not to pursue good-faith reporters. There is usually no cash reward. Many governments and companies run these; the US Cybersecurity and Infrastructure Security Agency publishes a VDP template that shows the typical sections: authorisation, guidelines, test methods, scope and reporting.
- Public bug bounty. Anyone who accepts the rules can test and may be rewarded for valid, in-scope, non-duplicate findings.
- Private bug bounty. Invitation only, usually offered to researchers with a track record on the platform.
Most programmes run on a platform that handles registration, triage and payment. HackerOne, Bugcrowd, Intigriti and YesWeHack are well-known examples. Some large organisations run their own programmes directly. Many organisations also publish a security.txt file at /.well-known/security.txt (standardised in RFC 9116) saying where to send reports.
If you’ve no idea where a company stands, disclose.io maintains an open directory of known disclosure and bounty programmes, including scope and safe-harbour details.
How to read a programme brief before you touch anything
Treat the programme page like a contract, because it effectively is one. Copy it into your notes and answer these questions in writing before you send a single request.
1. What exactly is in scope?
Look for an explicit list of domains, apps and API hosts. Notice the difference between app.acme-fintech.test (one host) and *.acme-fintech.test (a wildcard, but often with exclusions listed underneath). If an asset isn’t listed, assume it is out of scope.
2. What is explicitly out of scope? Typical exclusions: third-party services (a hosted helpdesk, a payment provider), corporate email, physical offices, staff.
3. Which test methods are banned? Almost every programme bans denial of service, social engineering of staff, physical testing and spam. Many cap automated scanning or ban it outright.
4. Which vulnerability types won’t be rewarded? Lists of “non-qualifying” issues often include missing security headers without demonstrated impact, self-XSS, clickjacking on pages with no sensitive actions, and rate-limit issues on non-sensitive endpoints. Reading this list saves you days.
5. What are the account and data rules? Use only accounts you created, usually with a platform-supplied email alias. Never access another real user’s data beyond the minimum needed to prove the issue, and stop as soon as you’ve proved it.
6. What are the disclosure rules? Most programmes forbid public disclosure without written permission. Some allow it after the fix through the platform’s disclosure process.
Here is a fictional brief, written the way real ones read, so you can practise:
Acme Fintech (fictional) bug bounty In scope:
app.acme-fintech.test,api.acme-fintech.test(v2 only), Acme Android app. Out of scope:status.acme-fintech.test(third-party),blog.acme-fintech.test, any*.corp.acme-fintech.testhost. Prohibited: DoS, social engineering, automated scanning above 5 requests per second, testing payment flows with real cards. Test accounts: register with your@wearehackerone.com-style platform alias.
Quick self-test: is api.acme-fintech.test/v1/users in scope? No, only v2 is listed. Is a stored XSS on the blog rewarded? No, the blog is excluded. Can you run a full-port scan of the API host? Only if you stay under the rate limit, and many programmes would still prefer you didn’t.
What is safe harbour, and does it protect you?
A safe harbour clause is a promise from the organisation not to take legal action against researchers who follow the programme rules in good faith. HackerOne describes its Gold Standard Safe Harbor as protection for good-faith testing that avoids harm, and it excludes activity like extortion (HackerOne). disclose.io publishes standard safe-harbour language that many organisations adopt.
Understand its limits:
- It covers only what the programme authorises. Step outside scope or break a rule and the protection may not apply.
- It’s a promise from the organisation, not from the state. It can’t override criminal law where you live. Computer-misuse laws such as Nigeria’s Cybercrimes (Prohibition, Prevention, etc.) Act 2015 and the UK’s Computer Misuse Act 1990 make unauthorised access an offence; the programme’s written authorisation is what makes your testing authorised.
- It doesn’t cover third parties. If an in-scope app sends you to a third-party service, that third party hasn’t agreed to anything.
Only test systems you own or have written permission to test. A bug bounty brief is that permission, for exactly the assets and methods it lists, and nothing more.
Platform rules that get beginners banned
Platforms protect their customers first. The quickest ways to lose your account:
- Testing out-of-scope assets, even “just to look”.
- Running loud scanners against production with default settings, ignoring rate limits.
- Duplicate-spam: submitting the same low-quality finding to many programmes.
- Threatening or pressuring a programme over a reward decision. Any hint of “pay me or I publish” is extortion.
- Disclosing publicly before you’re allowed.
- Using real customer data beyond what’s needed to prove impact, or keeping it afterwards.
- Multiple accounts to game reputation or reports.
Also learn the outcome labels. Reports are commonly closed as resolved (valid), duplicate (someone found it first), informative (true but no action needed), not applicable (out of scope or not a vulnerability) or spam. Platforms track your ratio, and a run of N/A closures can limit your access to programmes. Quality beats volume from day one.
What skills do you need before your first programme?
Bug bounty is mostly web and API testing, so the foundations are:
- HTTP: methods, status codes, cookies, headers, how sessions work.
- The OWASP Top 10 categories, especially broken access control, which our OWASP Top 10 guide explains with examples.
- An intercepting proxy (Burp Suite Community Edition is free).
- Enough scripting to repeat requests and compare responses.
PortSwigger’s Web Security Academy is free and has labs for each of these. A sensible bar before your first live programme: you can solve the Apprentice-level labs for access control, authentication and SQL injection without reading the solution.
A worked example: finding and proving an IDOR in a lab
This is the kind of flaw beginners realistically find: an insecure direct object reference (IDOR), where the API trusts an ID from the client without checking ownership. The demo uses our own lab, styled as fictional Acme Fintech, with two test accounts we created: alice (user 1041) and bob (user 1042).
Logged in as alice, the app fetches her statements:
curl -s https://api.acme-fintech.test/v2/accounts/1041/statements \
-H “Authorization: Bearer $ALICE_TOKEN” | jq ‘.[0]’
{
“statement_id”: “st_88213”,
“account_id”: 1041,
“period”: “2026-09”,
“closing_balance”: “152400.00”
}
Change the ID to bob’s account, still using alice’s token:
curl -s https://api.acme-fintech.test/v2/accounts/1042/statements \
-H “Authorization: Bearer $ALICE_TOKEN” | jq ‘.[0].account_id’
1042
Bob’s statements coming back to alice’s token means alice can read any customer’s statements. Notice what we didn’t do: we didn’t loop through thousands of IDs to “show scale”. Two accounts you own prove the flaw. Enumerating real customers would breach most programme rules and possibly data protection law.
The report format triagers can act on
A triager reads many reports a day. Make yours reproducible in five minutes by someone who has never seen the app. This structure works on every major platform:
## Title
IDOR on /v2/accounts/{id}/statements lets any user read other customers' statements
## Asset
api.acme-fintech.test (in scope, API v2)
## Severity (your assessment)
CVSS 3.1 base score 6.5 (Medium): AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Business context: any logged-in user can read every customer’s financial
statements. I’d ask the programme to weigh this under its own rating scale.
## Summary
The statements endpoint returns data for any account_id supplied, without
checking that the account belongs to the authenticated user.
## Steps to reproduce
1. Register two accounts (A and B). Note B’s account_id from GET /v2/me.
2. Log in as A and capture the bearer token.
3. Send: GET /v2/accounts/{B’s id}/statements with A’s token.
4. Observe 200 OK and B’s statements.
## Proof
Request/response pair (tokens redacted), screenshot of B’s statement in A’s session.
## Impact
Confidential financial data of any customer is exposed to any registered user.
## Suggested fix
Enforce object-level authorisation server-side: compare the account owner with
the authenticated user before returning data. Return 404 for non-owned IDs.
## Notes
Tested only with my own two accounts. No other customer data accessed.
Notice the CVSS base score comes out as Medium even though the business impact feels severe; that’s normal, and it’s why the report states the business context separately. Programmes may use CVSS, which FIRST maintains, or their own scale; Bugcrowd, for example, publishes a Vulnerability Rating Taxonomy that ranks issue types from P1 (critical) to P5 (informational). State your view, show the vector so anyone can check the maths, and justify it, but accept that the programme makes the final call.
The same habits make a strong professional pentest report, which our guide to writing a penetration testing report covers in depth.
A realistic first 90 days
| Weeks | Focus | Output |
|---|---|---|
| 1–4 | Web Security Academy labs, Burp basics | Solved labs plus your own notes per vulnerability class |
| 5–8 | Practise on deliberately vulnerable apps in your lab | Three full write-ups in the report format above |
| 9–12 | One VDP or public programme with a broad, clear scope | Careful recon notes, then one or two well-written reports |
Starting with a VDP is underrated. There’s no reward pressure, the scope is often generous, and a resolved report is something real to discuss in interviews. If your long-term goal is a salaried testing role, bug bounty is good practice, not a substitute for it; our guide on how to become a penetration tester explains how the two connect.