Web Security (OWASP Top 10:2025) Module 16 – Vulnerability disclosure and CERT-In reporting
Reporting a vulnerability: law, scope and CERT-In
Decide whether you may test, keep every test in scope, choose where to send a finding, and use CERT-In's coordination policy: its 72 working hours and 120 days.
What you will learn
- Decide whether you may test a system, and keep every test inside its scope
- Explain what sections 43, 66 and 70B of the IT Act mean for a reporter, and when to ask a lawyer
- Choose where to send a finding, and use CERT-In's coordination policy for what to send and what to expect
- Write a report that a developer can reproduce, with the least proof that shows the flaw
- Handle a finding that touches other people's data by stopping, recording and telling the owner
Before you start
What you’ll learn · Before you start
What you will learn
- Decide whether you may test a system, and keep every test inside its scope
- Explain what sections 43, 66 and 70B of the IT Act mean for a reporter, and when to ask a lawyer
- Choose where to send a finding, and use CERT-In's coordination policy for what to send and what to expect
- Write a report that a developer can reproduce, with the least proof that shows the flaw
- Handle a finding that touches other people's data by stopping, recording and telling the owner
Before you start
On this page
You are checking your own marks on your college portal when you notice that changing the number at the end of the address shows another student’s marks. You have seen one record that is not yours, and what you do in the next ten minutes decides whether the owner receives a report or a complaint about you.
The short answer has four parts: stop at the first sign, stay inside written permission, send the finding to its owner first and to a coordinator such as CERT-In when the owner stays silent, and keep what you send to the least that shows the flaw. Laws and policies here are education and not legal advice.
Decide first whether you may look, and where your permission stops
The first lesson of this track gave three questions to ask before any test. A finding that arrives by accident adds a fourth: what is the least you can do now? Stop at the first sign. One response that showed a stranger’s record is an observation. A second, a third and a fortieth request to see how many records leak is a test, and nobody allowed it.
A programme’s rules put the line in writing. The code below holds the rules of a made-up programme and eight planned tests, and names the rule that stops each test that cannot go ahead:
// A security program lists what a researcher may do. This check reads a program's rules and eight planned tests and says
// for each one whether the program allows it and which rule stops it. Hosts use the reserved names of RFC 2606.
const PROGRAM = {
inScope: ['shop.example', 'api.shop.example'],
techniques: ['manual', 'own-accounts', 'scanner'],
forbidden: ['denial-of-service', 'social-engineering', 'third-party-systems'],
maxRequestsPerSecond: 5,
maxOthersRecords: 0, // records of people other than you that a test may read
};
const PLANNED = [
{ what: 'read the response headers of the home page', host: 'shop.example', technique: 'manual', action: 'none', rate: 1, others: 0 },
{ what: "ask for customer B's order while signed in as your own second account", host: 'api.shop.example', technique: 'own-accounts', action: 'none', rate: 1, others: 0 },
{ what: 'run a scanner against the staging server', host: 'staging.shop.example', technique: 'scanner', action: 'none', rate: 5, others: 0 },
{ what: 'send 500 requests a second to the search page', host: 'shop.example', technique: 'scanner', action: 'denial-of-service', rate: 500, others: 0 },
{ what: 'phone a support agent and ask for a password reset', host: 'shop.example', technique: 'manual', action: 'social-engineering', rate: 1, others: 0 },
{ what: "open the payment provider's hosted page to look for flaws", host: 'pay.provider.example', technique: 'manual', action: 'third-party-systems', rate: 1, others: 0 },
{ what: 'open 40 other customers\' orders to count how many leak', host: 'api.shop.example', technique: 'manual', action: 'none', rate: 1, others: 40 },
{ what: 'scan the API at the program\'s own rate limit', host: 'API.shop.example', technique: 'scanner', action: 'none', rate: 5, others: 0 },
];
function verdict(program, test) {
const host = test.host.toLowerCase();
if (!program.inScope.includes(host)) return `the host ${host} is not listed in the scope`;
if (program.forbidden.includes(test.action)) return `${test.action} is forbidden`;
if (!program.techniques.includes(test.technique)) return `the technique ${test.technique} is not listed`;
if (test.rate > program.maxRequestsPerSecond) return `${test.rate} requests a second is over the limit of ${program.maxRequestsPerSecond}`;
if (test.others > program.maxOthersRecords) return `it reads ${test.others} records of other people, and the limit is ${program.maxOthersRecords}`;
return null;
}
let allowed = 0;
PLANNED.forEach((test, i) => {
const why = verdict(PROGRAM, test);
if (!why) allowed += 1;
console.log(`${i + 1}. ${why ? 'NOT ALLOWED' : 'allowed '} ${test.what}${why ? `\n because ${why}` : ''}`);
});
console.log(`${PLANNED.length} planned tests: ${allowed} allowed, ${PLANNED.length - allowed} not allowed`); Output
1. allowed read the response headers of the home page 2. allowed ask for customer B's order while signed in as your own second account 3. NOT ALLOWED run a scanner against the staging server because the host staging.shop.example is not listed in the scope 4. NOT ALLOWED send 500 requests a second to the search page because denial-of-service is forbidden 5. NOT ALLOWED phone a support agent and ask for a password reset because social-engineering is forbidden 6. NOT ALLOWED open the payment provider's hosted page to look for flaws because the host pay.provider.example is not listed in the scope 7. NOT ALLOWED open 40 other customers' orders to count how many leak because it reads 40 records of other people, and the limit is 0 8. allowed scan the API at the program's own rate limit 8 planned tests: 3 allowed, 5 not allowed
Recorded with Node.js 24.21.0 on macOS 26 arm64. To run it yourself: mise exec node@24.21.0 -- node scope_check.mjs
Runs on this device, in your browser. The first run downloads JavaScript (about 0.6 MB), which is kept for the next runs.
Your run, in this browser
Three tests are allowed: reading headers, using your own second account, and scanning the API at the programme’s own limit of 5 requests a second. Five stop at a rule: a staging host that is not listed, a flood of requests, a call to a support agent, a payment provider’s page, and 40 other customers’ orders. The last is the one a curious reporter most wants to run, and exactly what the limit of 0 other people’s records forbids.
What the Information Technology Act says
The Information Technology Act, 2000 makes a person who, without the permission of a computer’s owner or the person in charge, accesses it, copies its data or disrupts it liable to pay compensation (section 43). Done dishonestly or fraudulently, the same acts are offences punishable by up to three years in prison, a fine of up to five lakh rupees, or both (section 66). Section 70B makes CERT-In the national agency for incident response. Ask a lawyer before you test anything you do not own.
Checkpoint
Check: Permission, scope and the first sign
Send the finding to the owner first, and to a coordinator when that fails
The owner can fix a flaw fastest, so its own route comes first: the address in its security.txt, the form in its policy, or the programme it runs on a bounty platform, with that programme’s rules. A project on GitHub may take private reports from its Security tab, once its maintainers have switched the feature on. A coordinator: An organisation that takes a report on the reporter's behalf, finds the vendor, keeps the details private and agrees when to publish. A national CERT such as CERT-In does this, and a project host may do it for its own repositories. is for the owner you cannot find or who does not answer: it locates the vendor and keeps the report private. Four questions choose the route:
Answer the questions above: the table then marks what fits your case and says why the rest does not.
| Route | Who can act on it | Rules you accept |
|---|---|---|
| The owner's own contact How you send it: its security.txt or policy | Good the team that runs the system and can fix it fastest | Mixed the scope and conduct lines of its policy |
| A bug-bounty programme How you send it: its platform and its rules | Good a triage team that passes the report on | Mixed the programme's scope, conduct and reward terms |
| CERT-In How you send it: email or its reporting form | Mixed it finds and contacts the vendor for you, which takes longer | Good its published policy, and your own duty to obey the law |
| A project's private report How you send it: the repository's security policy | Good the maintainers, in private, before anyone else knows | Good the project's own security policy |
How the answers decide
- “Do you know who runs the system?” No, or it is many organisations: rules out The owner's own contact, A bug-bounty programme and A project's private report. You have nobody to write to yet. A coordinator can find the vendor, which is the reason it exists.
- “Do you know who runs the system?” Yes and “Does the owner publish a security contact or a programme?” Yes and “Has the owner ignored you for longer than its own stated time?” No, or I have not tried yet: rules out CERT-In. The owner has a route and has not failed you yet. Use its route first, and keep a copy of what you send.
- “Does the owner publish a security contact or a programme?” No and “Has the owner ignored you for longer than its own stated time?” No, or I have not tried yet: adds a caveat to The owner's own contact. Without a published route, write to the organisation's general address, say it is a security report and keep a copy. If nothing comes of it, turn to a coordinator.
- “Has the owner ignored you for longer than its own stated time?” Yes, I have heard nothing past its time: rules out The owner's own contact, A bug-bounty programme and A project's private report. You used the owner's route and waited its stated time. A coordinator is the next step, and your log of messages is what it needs.
- “Is it open-source software with a security policy?” Yes: rules out The owner's own contact and adds a caveat to A bug-bounty programme and CERT-In. For open-source software the project's private channel is the owner's route. A programme or a coordinator comes only if the project is silent.
- “Is it open-source software with a security policy?” No: rules out A project's private report. There is no repository policy to follow, so the owner's route, a programme or a coordinator applies.
Send one report to one place at a time, and keep a copy of every message.
Checkpoint
Check: Where to send a finding
What CERT-In asks for, and what it promises
CERT-In’s policy covers a report about any product. You write to vdisclose@cert-in.org.in, encrypted with PGP if you wish,
or use the form the policy page links. It expects the product and exact version, the vendor, a description with concise steps and evidence, and the impact. First check that the
flaw reproduces on the latest supported version and is not already known. Then follow the report:
- Day 0
You send the report
By email, encrypted with PGP if you wish, or with the form linked from the policy page. The policy asks you to check first that the flaw reproduces on the latest supported version and that it is not already known.
- 72 working hours
CERT-In acknowledges promised
The policy promises an acknowledgement within 72 working hours of receipt. It does not say what a working hour is. Read as eight-hour working days, that is nine working days, so allow about two weeks before you ask where your report is.
- After validation
It decides whether to coordinate
CERT-In examines the report and tells you whether it will coordinate. If it will, it contacts the vendor, you and anyone else who must take part, and it tries to keep the details to a minimum.
- Vendor contact
The 120 days start target
The policy counts its target from the date of initial vendor contact, which is not the day you wrote. CERT-In endeavours to have the issue resolved within 120 days of that date.
- Shorter or longer
When the target changes
The time can change if the flaw is being actively exploited, was reported by several sources, is exceptionally serious, such as a threat to public safety, or if you, CERT-In and the vendor agree another time. The policy assigns no fixed deadline.
- No resolution
If the vendor goes quiet
Where the issue is not resolved in 120 days, for example through disagreement or a vendor that does not respond, CERT-In may close the issue and tell you, or make the vulnerability public and stop coordinating with the vendor.
- After the fix
Note, credit and rewards
CERT-In publishes a vulnerability note or advisory after the fix or at a time it agrees with those involved, and names you in it if you want that. If the vendor wishes to reward you, CERT-In can introduce you but takes no part in the talks.
The timeline has 7 events, from Day 0 to After the fix.
Two numbers matter: 72 working hours to acknowledge, and a target of 120 days, counted from CERT-In’s first contact with the vendor. The policy gives no fixed deadline and no exemption from the law: the discloser answers for how they found the flaw.
Three skills decide whether a finding reaches a fix. A report a developer can reproduce gives the product, the version, numbered steps and the The least evidence that shows a flaw is real.. A finding that touches other people’s data is handled by stopping, noting what you saw and telling the owner. Silence is handled with a log of every attempt and the owner’s stated time.
Checkpoint
Check: What CERT-In asks and promises
A report a developer can reproduce, with the least proof that works Pro: opens with a Pro, Premium or Ultimate pass
A report that cannot be reproduced is closed, however serious the flaw. This part lists what a developer needs, shows what minimal proof is for the common kinds of flaw, and checks ten sample reports with a linter that ran.
In this part:
- What a developer needs from a report, field by field
- Minimal proof is the least that shows the flaw, from your own data
- Ten sample reports through a linter
- Lint a vulnerability report before you send it
- Results of the sample tests
- A rubric to score your own report
1 runnable example (Python) · 1 exercise with sample tests · about 7 minutes
Opening this part with your pass…
This part opens with any MySmartCoPilot pass.
- Pro pass · 1 week₹79$2.99
- 30 days₹179$5.99
- 1 year₹1,699$45
One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.
Passes can’t be bought right now, so this part can’t be opened at the moment. The free part above stands on its own. If you have a pass, enter your licence key.
It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).
When a finding touches other people's data: stop, record, tell Pro: opens with a Pro, Premium or Ultimate pass
Some findings put a stranger’s data in front of you before you meant to see it. This part sets out the first ten minutes, how to describe an exposure without copying it, what to do if you already hold a copy, and what to say to the owner.
In this part:
- The first ten minutes: stop, do not repeat, do not save
- Describe the exposure without copying it
- One finding, from the first minute to the fix
- If you already hold a copy
1 diagram · about 5 minutes
Opening this part with your pass…
This part opens with any MySmartCoPilot pass.
- Pro pass · 1 week₹79$2.99
- 30 days₹179$5.99
- 1 year₹1,699$45
One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.
Passes can’t be bought right now, so this part can’t be opened at the moment. The free part above stands on its own. If you have a pass, enter your licence key.
It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).
Silence, deadlines and going public: keep a log, wait, then escalate Pro: opens with a Pro, Premium or Ultimate pass
Most reports fail through silence and not refusal. This part keeps a dated log, gives a plan for each stage of an owner’s silence, and explains why going public is a late step and rarely the reporter’s alone.
In this part:
- A plan written before you are annoyed
- What a log holds
- Going public is a late step
1 runnable example (JavaScript) · about 3 minutes
Opening this part with your pass…
This part opens with any MySmartCoPilot pass.
- Pro pass · 1 week₹79$2.99
- 30 days₹179$5.99
- 1 year₹1,699$45
One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.
Passes can’t be bought right now, so this part can’t be opened at the moment. The free part above stands on its own. If you have a pass, enter your licence key.
It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).
Practise: decide whether a programme allows a test
Write the scope check yourself. It returns the code of the first rule a test breaks. The sample tests run in your browser, in JavaScript or Python:
Exercise · Easy · JavaScript, Python
Decide whether a program allows a planned test
Write decide(program, test), the check of the lesson's scope program for one planned test. It returns 'allowed', or the code of the first rule the test breaks.
A program has inScope (the hosts it covers), techniques (the techniques it lists), forbidden (the actions it bans), maxRequestsPerSecond and maxOthersRecords (how many records of other people a test may read). A test has host, technique, action ('none' or the name of something forbidden), rate (requests a second) and others (records of other people that it reads).
Check the rules in this order and return the first code that applies:
'host': the test's host is not ininScope. Hosts ignore case, and a subdomain is a different host:staging.shop.exampleis not covered byshop.example.'forbidden': the action is inforbidden.'technique': the technique is not intechniques.'rate': the rate is abovemaxRequestsPerSecond. A rate equal to the limit is allowed.'data':othersis abovemaxOthersRecords. A number equal to the limit is allowed.
Do not change program or test. The starter compares the host as written and checks nothing else.
JavaScript · Starter code · scope.mjs
/** 'allowed', or the code of the first rule the planned test breaks (see the prompt). */
export function decide(program, test) {
// Starter: it compares the host as written and checks nothing else.
return program.inScope.includes(test.host) ? 'allowed' : 'host';
} The sample tests · scope.test.mjs
import { test, assert } from 'mysmartcopilot:test';
import { decide } from './scope.mjs';
const program = () => ({
inScope: ['shop.example', 'api.shop.example'],
techniques: ['manual', 'own-accounts', 'scanner'],
forbidden: ['denial-of-service', 'social-engineering'],
maxRequestsPerSecond: 5,
maxOthersRecords: 0,
});
const plan = (change = {}) => ({ host: 'shop.example', technique: 'manual', action: 'none', rate: 1, others: 0, ...change });
test('a listed host with a listed technique is allowed', () => {
assert.equal(decide(program(), plan()), 'allowed');
assert.equal(decide(program(), plan({ host: 'api.shop.example', technique: 'own-accounts' })), 'allowed');
});
test('hosts ignore case, and a subdomain is a different host', () => {
assert.equal(decide(program(), plan({ host: 'API.Shop.Example' })), 'allowed');
assert.equal(decide(program(), plan({ host: 'staging.shop.example' })), 'host');
assert.equal(decide(program(), plan({ host: 'notshop.example' })), 'host');
});
test('a forbidden action is refused whatever else is fine', () => {
assert.equal(decide(program(), plan({ action: 'social-engineering' })), 'forbidden');
assert.equal(decide(program(), plan({ action: 'denial-of-service', technique: 'scanner' })), 'forbidden');
});
test('a technique that is not listed is refused', () => {
assert.equal(decide(program(), plan({ technique: 'phishing-kit' })), 'technique');
});
test('a rate equal to the limit is allowed and one above it is not', () => {
assert.equal(decide(program(), plan({ technique: 'scanner', rate: 5 })), 'allowed');
assert.equal(decide(program(), plan({ technique: 'scanner', rate: 6 })), 'rate');
});
test('records of other people: the limit itself is allowed, one more is not', () => {
assert.equal(decide(program(), plan({ others: 0 })), 'allowed');
assert.equal(decide(program(), plan({ others: 1 })), 'data');
const lenient = { ...program(), maxOthersRecords: 1 };
assert.equal(decide(lenient, plan({ others: 1 })), 'allowed');
assert.equal(decide(lenient, plan({ others: 2 })), 'data');
});
test('the first broken rule wins, in the order host, forbidden, technique, rate, data', () => {
const everything = plan({ host: 'elsewhere.example', action: 'denial-of-service', technique: 'x', rate: 500, others: 40 });
assert.equal(decide(program(), everything), 'host');
assert.equal(decide(program(), { ...everything, host: 'shop.example' }), 'forbidden');
assert.equal(decide(program(), { ...everything, host: 'shop.example', action: 'none' }), 'technique');
assert.equal(decide(program(), { ...everything, host: 'shop.example', action: 'none', technique: 'manual' }), 'rate');
assert.equal(decide(program(), { ...everything, host: 'shop.example', action: 'none', technique: 'manual', rate: 1 }), 'data');
}); Python · Starter code · scope.py
def decide(program, test):
"""'allowed', or the code of the first rule the planned test breaks (see the prompt)."""
# Starter: it compares the host as written and checks nothing else.
return "allowed" if test["host"] in program["inScope"] else "host" The sample tests · test_scope.py
from scope import decide
def program():
return {
"inScope": ["shop.example", "api.shop.example"],
"techniques": ["manual", "own-accounts", "scanner"],
"forbidden": ["denial-of-service", "social-engineering"],
"maxRequestsPerSecond": 5,
"maxOthersRecords": 0,
}
def plan(**change):
return {"host": "shop.example", "technique": "manual", "action": "none", "rate": 1, "others": 0, **change}
def test_a_listed_host_with_a_listed_technique_is_allowed():
assert decide(program(), plan()) == "allowed"
assert decide(program(), plan(host="api.shop.example", technique="own-accounts")) == "allowed"
def test_hosts_ignore_case_and_a_subdomain_is_a_different_host():
assert decide(program(), plan(host="API.Shop.Example")) == "allowed"
assert decide(program(), plan(host="staging.shop.example")) == "host"
assert decide(program(), plan(host="notshop.example")) == "host"
def test_a_forbidden_action_is_refused_whatever_else_is_fine():
assert decide(program(), plan(action="social-engineering")) == "forbidden"
assert decide(program(), plan(action="denial-of-service", technique="scanner")) == "forbidden"
def test_a_technique_that_is_not_listed_is_refused():
assert decide(program(), plan(technique="phishing-kit")) == "technique"
def test_a_rate_equal_to_the_limit_is_allowed_and_one_above_it_is_not():
assert decide(program(), plan(technique="scanner", rate=5)) == "allowed"
assert decide(program(), plan(technique="scanner", rate=6)) == "rate"
def test_records_of_other_people_the_limit_itself_is_allowed_one_more_is_not():
assert decide(program(), plan(others=0)) == "allowed"
assert decide(program(), plan(others=1)) == "data"
lenient = {**program(), "maxOthersRecords": 1}
assert decide(lenient, plan(others=1)) == "allowed"
assert decide(lenient, plan(others=2)) == "data"
def test_the_first_broken_rule_wins_in_the_order_host_forbidden_technique_rate_data():
everything = plan(host="elsewhere.example", action="denial-of-service", technique="x", rate=500, others=40)
assert decide(program(), everything) == "host"
assert decide(program(), {**everything, "host": "shop.example"}) == "forbidden"
assert decide(program(), {**everything, "host": "shop.example", "action": "none"}) == "technique"
assert decide(program(), {**everything, "host": "shop.example", "action": "none", "technique": "manual"}) == "rate"
assert decide(program(), {**everything, "host": "shop.example", "action": "none", "technique": "manual", "rate": 1}) == "data" A hint
Lower-case the test's host once, and compare it with the lower-cased hosts of inScope by looking for an exact match, not by checking whether one ends with the other. Then write the other four checks one after another, each returning as soon as it fails, so the order of the prompt decides which code wins when a test breaks several rules.
Results of the sample tests
| Test | Result | Details |
|---|
What your code printed
The sample tests run on this device, in your browser (QuickJS, Pyodide): nothing is sent to mysmartcopilot.com. The first run of each language downloads it: JavaScript (about 0.6 MB) or Python (about 13.5 MB), which is kept for the next runs. A check in your browser is feedback for you, not proof that the code is right for every input.
Then check yourself, weakest idea first:
Practice that adapts to you
Practise this lesson
11 questions about 7 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.
Interview questions
Warm-up: what does CERT-In’s policy promise a reporter, and what does it not?
It promises an acknowledgement within 72 working hours, a decision on whether it will coordinate, contact with the vendor, and a note after the fix, with credit if you want it. It aims for resolution within 120 days of its first contact with the vendor, a target that can change. It promises no fixed deadline, no reward and no exemption from the law.
-
Fresher to senior
While checking your own marks on your college portal, you notice that changing the number in the address shows another student's marks. You have seen one record. What do you do next, what do you not do, and whom do you tell?
-
Mid to senior
You found a serious flaw on a municipal service's website. It lists no security contact, and an email to its general address got no reply in three weeks. Where do you go next, what do you send, and what do you not do?
-
Mid to staff
While testing a company's bug-bounty programme inside its rules, you notice that a response includes other customers' phone numbers, and your browser has saved it. What do you do in the next hour, and what do you tell the programme?
Flashcards · 5 cards
Recall it, then check
Say the answer to yourself before you look: recalling it is what makes it stick.
-
What do you do when you find a flaw by accident, such as another student's marks on a portal?
Stop at the first sign. One response that showed a stranger's record is an observation; a second, a third and a fortieth request to see how many records leak is a test that nobody allowed. Stay inside written permission, send the finding to its owner first and to a coordinator such as CERT-In if the owner is silent, and keep what you send to the least that shows the flaw.
-
How does a programme's scope settle a planned test?
Its rules put the line in writing: which hosts, a request rate and a limit on other people's records. In the lesson three tests were allowed (reading headers, using your own second account, scanning at the programme's limit of 5 requests a second) and five stopped at a rule: an unlisted staging host, a flood of requests, a call to a support agent, a payment provider's page, and 40 other customers' orders.
-
Where does a finding go first, and when does a coordinator step in?
To its owner: the address in its security.txt, the form in its policy, or its bounty programme, following that programme's rules (a GitHub project may take private reports from its Security tab once its maintainers switch the feature on). A coordinator is for the owner you cannot find or who does not answer: it locates the vendor and keeps the report private. Send one report to one place at a time and keep a copy of every message.
-
How do you report to CERT-In, and what does it promise?
Write to vdisclose@cert-in.org.in, encrypted with PGP if you wish, or use the form on its policy page, with the product and exact version, the vendor, a description with concise steps and evidence, and the impact, after checking that the flaw reproduces on the latest supported version. CERT-In acknowledges within 72 working hours and aims for 120 days from its first contact with the vendor. It promises no fixed deadline, no reward and no exemption from the law.
-
What makes a report one a developer can reproduce?
The product, the version, numbered steps and the minimal proof, the least evidence that shows the flaw is real. A finding that touches other people's data is handled by stopping, noting what you saw and telling the owner; silence is handled with a log of every attempt and the owner's stated time.
Key takeaways
- Stop at the first sign: a second and a fortieth request turn an observation into a test, and a programme’s scope decides line by line what you may test.
- The IT Act penalises accessing, copying and disrupting without permission, so ask a lawyer before testing what you do not own.
- Send the finding to the owner first and to a coordinator such as CERT-In when the owner is silent; CERT-In acknowledges within 72 working hours and aims for 120 days from its first contact with the vendor.
Terms in this lesson
- coordinator
- An organisation that takes a report on the reporter's behalf, finds the vendor, keeps the details private and agrees when to publish. A national CERT such as CERT-In does this, and a project host may do it for its own repositories.
- minimal proof
- The least evidence that shows a flaw is real: one observation, made with accounts and data you created for the test, with every secret masked. When proving the flaw would take other people's records, you describe it instead.
References
- Responsible Vulnerability Disclosure and Coordination Policy (Indian Computer Emergency Response Team (CERT-In))
- Information Technology Act, 2000 (as amended): sections 43, 66 and 70B (Legislative Department, Ministry of Law and Justice, Government of India (India Code))
- RFC 9116: A File Format to Aid in Security Vulnerability Disclosure (IETF (RFC Editor))
- Vulnerability Disclosure Cheat Sheet (OWASP Foundation)
- Privately reporting a security vulnerability (GitHub Docs)
Related tools
Report a problem with this lesson
Kept only in this browser. Your Learn progress