Bug Bounty & Responsible Disclosure
Sometimes you find a security problem in software or a website that you do not own. Maybe a mobile app shows other users' data, or a college portal leaks marks through its API. What you do next matters a great deal, both for the people affected and for you legally. Responsible disclosure (also called coordinated disclosure) is the professional way to report it so it gets fixed before anyone can misuse it.
In this lesson you will learn how vulnerability disclosure programmes and bug bounties work, how to read a programme's scope and rules, how organisations publish a security.txt file, how to write a report that gets fixed, and which official channels exist in India.
Disclosure programmes and bug bounties
- A vulnerability disclosure programme (VDP) is an organisation's public promise: "If you find a problem, here is how to tell us, and here are the rules." It may or may not pay.
- A bug bounty programme is a VDP that pays rewards for valid, in-scope findings, usually more for higher severity.
Many companies run their programmes on platforms such as HackerOne, Bugcrowd, Intigriti and YesWeHack, which handle submissions, triage and payments. Others run them on their own websites.
The key difference from random testing: a programme gives you permission, but only within its written rules. Outside those rules, the law treats your testing like any other unauthorised access. In India, section 43 of the IT Act applies even when your intentions are good, and there is no general legal "safe harbour" for security researchers. Read every rule before you send a single request.
Reading a programme policy
Every programme policy answers the same questions. Read them all:
| Section | What to look for |
|---|---|
| In scope | Exact domains, apps and APIs you may test, for example *.shop.example and the Android app |
| Out of scope | Excluded systems (third-party services, staging, a partner's payment page) and excluded issue types |
| Rules of engagement | No denial of service, no social engineering of staff, no physical attacks, request rate limits, use only your own test accounts |
| Data handling | Stop as soon as you see other users' data; do not download, keep or share it |
| Safe harbour | The organisation's promise not to take legal action for good-faith testing within the rules |
| Rewards and severity | How findings are rated and paid, and what counts as a duplicate |
| Disclosure | Whether and when you may publish details after a fix |
Scope rules often use wildcards. A small checker helps you avoid testing something excluded:
from fnmatch import fnmatch
IN_SCOPE = ["shop.example", "*.shop.example", "api.payments.example"]
OUT_OF_SCOPE = ["blog.shop.example", "*.staging.shop.example", "status.shop.example"]
def check(host):
if any(fnmatch(host, pattern) for pattern in OUT_OF_SCOPE):
return "OUT OF SCOPE (excluded)"
if any(fnmatch(host, pattern) for pattern in IN_SCOPE):
return "in scope"
return "OUT OF SCOPE (not listed)"
for host in ["shop.example", "m.shop.example", "blog.shop.example",
"v2.staging.shop.example", "payments.example", "api.payments.example"]:
print(f"{host:<26} {check(host)}")shop.example in scope m.shop.example in scope blog.shop.example OUT OF SCOPE (excluded) v2.staging.shop.example OUT OF SCOPE (excluded) payments.example OUT OF SCOPE (not listed) api.payments.example in scope
Exclusions are checked first, because they always win over a broad wildcard. If anything is unclear, ask the programme before testing.
security.txt
How does a researcher know whom to contact? RFC 9116 (published in 2022) defines a simple text file at /.well-known/security.txt on a website. Two fields are required: Contact (an email address or web form) and Expires (a date after which the file should not be trusted). Optional fields include Policy, Encryption, Acknowledgments, Preferred-Languages, Canonical and Hiring. Every organisation should publish one; it costs nothing and gets reports to the right people.
from datetime import datetime, timezone
security_txt = """# Security contact for shop.example
Contact: mailto:security@shop.example
Contact: https://shop.example/security/report
Policy: https://shop.example/security/policy
Preferred-Languages: en, hi
Expires: 2027-03-31T18:30:00Z"""
fields = {}
for line in security_txt.splitlines():
if line.startswith("#") or ":" not in line:
continue
name, value = line.split(":", 1)
fields.setdefault(name.strip().lower(), []).append(value.strip())
today = datetime(2026, 11, 10, tzinfo=timezone.utc)
for required in ["contact", "expires"]:
print(f"{required:<8} {'present' if required in fields else 'MISSING (required by RFC 9116)'}")
expires = datetime.fromisoformat(fields["expires"][0].replace("Z", "+00:00"))
print("Expired?", "yes" if expires < today else f"no, valid for {(expires - today).days} more days")
print("Report to:", fields["contact"][0])contact present expires present Expired? no, valid for 141 more days Report to: mailto:security@shop.example
Writing a report that gets fixed
The people reading your report are busy. Make it easy to confirm and fix:
Title: Order details of any customer visible via /api/orders/{id}
Asset: https://api.shop.example (in scope per policy section 2)
Severity: High (my estimate, CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N)
Summary: A logged-in customer can read other customers' orders by changing the order ID.
Steps: 1. Create two test accounts, A and B (both mine).
2. As B, place an order; note its ID (5521).
3. As A, request GET /api/orders/5521 with A's session.
4. B's name, address and items are returned.
Impact: Exposure of customer names, addresses and purchase history.
Evidence: Request/response for my own test accounts only (attached, tokens redacted).
Fix idea: Check that the order belongs to the logged-in user on every request.Good habits:
- Prove impact with your own accounts. Two test accounts are enough to demonstrate most access control bugs without touching anyone else's data.
- Stop at the first proof. If you accidentally see another person's data, stop, do not save it, and mention it in your report.
- One issue per report, clear steps, and screenshots or requests with secrets redacted.
- Be patient and polite. Fixes take time. Many programmes and researchers work with a disclosure deadline of about 90 days, but follow the programme's own policy.
- Never demand payment as a condition for not publishing or for sharing details. Asking for money in exchange for silence is extortion, a crime, not a bug bounty.
Reporting in India
- CERT-In published a Responsible Vulnerability Disclosure and Coordination Policy in 2021 and coordinates fixes between researchers and vendors. CERT-In is also a CVE Numbering Authority for products designed and made in India.
- NCIIPC (National Critical Information Infrastructure Protection Centre) runs a Responsible Vulnerability Disclosure Program for critical information infrastructure such as power, banking, telecom and transport. Reports go through the form on its website to
rvdp@nciipc.gov.in. - For a company with no programme and no
security.txt, try its official security or support contact, or ask CERT-In to coordinate. Do not keep testing while you wait.
Check the official websites for the current process before you report, since policies are updated from time to time.
Getting started the right way
Bug bounty work is competitive, and the easy bugs are found quickly. Build skill first in your lab (Juice Shop has a score board of challenges), on CTF platforms and with the OWASP Web Security Testing Guide. Then start with programmes that welcome beginners, read their past public reports to learn what they value, and focus on understanding one application deeply instead of running scanners against many. Automated scanning is banned or rate-limited by many programmes anyway.
Common mistakes
- Testing before reading the policy, or testing subdomains that are explicitly excluded.
- Running heavy automated scans against programmes that forbid them.
- Accessing real users' data to "prove" impact instead of using your own test accounts.
- Publishing details before a fix or before the agreed disclosure date.
- Reporting scanner output without verification, such as missing headers with no real impact, which most programmes mark as informational.
Key points
- Responsible disclosure means reporting privately and giving time to fix before any publication.
- A VDP gives a reporting channel and rules; a bug bounty adds rewards. Both give permission only within scope.
- Read scope, exclusions, rules, data handling and safe harbour before testing; exclusions win over wildcards.
security.txt(RFC 9116) lives at/.well-known/security.txtand must includeContactandExpires.- Good reports have clear steps, minimal proof using your own accounts, impact and a fix idea.
- In India, CERT-In coordinates disclosure and NCIIPC runs an RVDP for critical infrastructure.
Exercise
Extend the security.txt checker so that it also warns when the Expires date is more than one year after today (RFC 9116 recommends keeping it under a year) and when there is no Policy field. Test it with a file whose Expires is 2028-01-01T00:00:00Z and which has no Policy line.
Show solution
from datetime import datetime, timezone
text = """Contact: mailto:security@college.example
Expires: 2028-01-01T00:00:00Z"""
fields = {}
for line in text.splitlines():
name, value = line.split(":", 1)
fields[name.strip().lower()] = value.strip()
today = datetime(2026, 11, 10, tzinfo=timezone.utc)
expires = datetime.fromisoformat(fields["expires"].replace("Z", "+00:00"))
if (expires - today).days > 365:
print("Warning: Expires is more than a year away")
if "policy" not in fields:
print("Warning: no Policy field, researchers cannot see the rules")Both warnings print. A far-future expiry means the file may go stale without anyone noticing, and a missing policy leaves researchers guessing about scope and rules.
Quick Quiz
1. What does a bug bounty programme give a researcher?
Permission is limited to the written scope and rules; outside them, testing is unauthorised.
2. Which two fields are required in a security.txt file?
RFC 9116 requires Contact and Expires; the rest are optional.
3. You notice another customer's address while testing an in-scope bug. What should you do?
Prove impact minimally, ideally with your own test accounts, and never keep others' data.
4. Where should vulnerabilities in Indian critical information infrastructure be reported?
NCIIPC runs an RVDP for critical information infrastructure.
Learn Cyber Security with a mentor
Free lessons get you started. Our Ethical Hacking & Cyber Security training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
