GitHub private vulnerability report template

Since 1 Oct 2026 GitHub’s report form asks for four things by default: a summary, the details, a proof of concept of at least 150 characters, and the impact. This template fills those four boxes, then the CWE and the AI-assistance box.

Download .md

Filled it in?

Bounty Operator argues against the draft the way a maintainer would, every claim checked against the code you add. Free in ChatGPT or Claude with no account, or once a day on your own AI key with a free account.

Challenge my draft

Rules checked 15 Oct 2026 · 6 sources

The template

The title line is the advisory’s short summary. Summary, Details, Proof of concept and Impact each go in their own box of the default form. Sections 6 to 10 have no box of their own: put the CWE in its field, tick the AI box if it applies, and paste the rest at the end of Impact. A repository’s own form can ask for more. Answer every box it shows.

Platformasked for in GitHub’s published guidance. Addedanswers the two objections that close reports late: overclaiming and known issues.

github-private-vulnerability-report.md10 sections
01Platform

Title

A report is filed as an advisory with a short summary line of its own, apart from the description: the REST API calls it summary. One line: the weakness, where it is, what it lets an attacker do.

Weakness in function, endpoint or file lets attacker what they can do

02Platform

Summary

One of the four boxes the default form requires. GitHub joins the four answers into the advisory description, so this paragraph opens what the maintainer reads.

What is wrong, in which component and versions, and who is affected. Two or three sentences, no code.

03Platform

Details

Required. Pin the code: the package, the affected and patched versions, and the file and lines at a release tag or commit. Then the root cause and the path from input to effect. The REST API takes the ecosystem, the package, the version range and the affected functions as fields of their own.

  • Package: ecosystem package name
  • Affected versions: range in Advisory Database syntax, for example < 2.4.1
  • Patched versions: version, or "no fix released"
  • Source: repository URL at release tag or 40-character commit
  • Location: path/to/file lines start-end, function name

Root cause: the line or missing check that opens the path, and why the surrounding code does not stop it

{The smallest excerpt that shows the root cause, with its line numbers}

Path:

  1. Attacker sends exact input to entry point. What the code does with it.
  2. The next step, with the value it carries.
  3. The effect: the data read, the command run, the check skipped.
04Platform

Proof of concept

Required, with at least 150 characters in the default form, and a repository’s own form can set a higher minimum. GitHub added the field to get a reproducible proof of concept: the exact input, the command and the output, on a version the maintainer can install.

Tested on package version, operating system and runtime version, with configuration: the defaults, or the setting that has to be on.

  1. Install or check out the affected version: the exact command
  2. Start it with the configuration above
  3. Send the input: the exact request, file or call
{The script, request or test that triggers it}

Output:

{Pasted output that shows the effect}

On the patched version: the same steps, and what they show now

05Platform

Impact

Required. Who is affected and how, in the setup they actually run: GitHub’s own example form asks exactly that. Name every precondition, such as a setting that is off by default, a role or an action by the victim.

  • Who is affected: users of which feature, in which configuration
  • What an attacker gains: read, write, run code or deny service: the concrete effect
  • Preconditions: none, or each one: a setting, a role, an action by the victim
  • Not affected: the configurations or versions where this does not apply
06Platform

Weakness and severity

Fields of their own on the advisory. A repository can require a CWE before you submit, on the web form and over the API. Pick the CWE for the root cause, not the symptom. The API takes a severity or a CVSS vector, not both.

  • CWE: CWE-number, name
  • Severity: critical, high, medium or low, or the CVSS vector CVSS:3.1/AV:N/AC:L/...
07Platform

AI assistance

A checkbox near the end of the form reads: I used AI assistance to find or write up this report. Maintainers are told to review the report together with any disclosure of AI assistance. Tick it when a model found the bug or wrote the text, and say what you checked by hand.

  • AI assistance: none, or what the model did: found the bug, wrote the text, wrote the proof
  • Checked by hand: what you ran or read yourself to confirm each claim
08Platform

Suggested fix

Optional. After you submit you can start a temporary private fork to work on the fix, and only the maintainer can merge from it. A diff here shows you found the root cause.

The change, in the file and function it belongs to.

- {vulnerable line}
+ {fixed line}
09Added

Limits and non-claims

State what the report does not claim before the maintainer asks. A claim kept inside what the proof shows leaves nothing to argue down.

  • Not claimed: what this report does not say, for example no effect on the default configuration
  • Mocked or assumed: each mock and assumption, or "nothing: every step runs the released code"
  • Stops working when: the condition that breaks the path
10Added

Known issues checked

Search the repository before you file: its published advisories, issues, pull requests and changelog. Name the nearest one and say why this is a different root cause.

  • Published advisories for this repository: what you searched, the nearest one, why this differs
  • Issues, pull requests and commits: what you searched, the nearest match, the difference
  • Security policy: the rule in SECURITY.md this report falls under, for example the supported versions
Markdown sourcegithub-private-vulnerability-report.md
github-private-vulnerability-report.md
> GitHub private vulnerability report template from https://bountyoperator.com/templates/github-private-vulnerability-report. Platform rules checked 15 Oct 2026.
> Replace every {placeholder}. Delete this note before you submit.
> Before you submit, paste the filled draft at https://bountyoperator.com/templates/github-private-vulnerability-report?ref=template#check for a free check.

# {Weakness} in `{function, endpoint or file}` lets {attacker} {what they can do}

## Summary

{What is wrong, in which component and versions, and who is affected. Two or three sentences, no code.}

## Details

- Package: {ecosystem} `{package name}`
- Affected versions: `{range in Advisory Database syntax, for example < 2.4.1}`
- Patched versions: {version, or "no fix released"}
- Source: {repository URL} at `{release tag or 40-character commit}`
- Location: `{path/to/file}` lines {start}-{end}, function `{name}`

Root cause: {the line or missing check that opens the path, and why the surrounding code does not stop it}

```
{The smallest excerpt that shows the root cause, with its line numbers}
```

Path:

1. {Attacker} sends {exact input} to `{entry point}`. {What the code does with it.}
2. {The next step, with the value it carries.}
3. {The effect: the data read, the command run, the check skipped.}

## Proof of concept

Tested on {package} {version}, {operating system and runtime version}, with {configuration: the defaults, or the setting that has to be on}.

1. {Install or check out the affected version: the exact command}
2. {Start it with the configuration above}
3. {Send the input: the exact request, file or call}

```
{The script, request or test that triggers it}
```

Output:

```text
{Pasted output that shows the effect}
```

On the patched version: {the same steps, and what they show now}

## Impact

- Who is affected: {users of which feature, in which configuration}
- What an attacker gains: {read, write, run code or deny service: the concrete effect}
- Preconditions: {none, or each one: a setting, a role, an action by the victim}
- Not affected: {the configurations or versions where this does not apply}

## Weakness and severity

- CWE: CWE-{number}, {name}
- Severity: {critical, high, medium or low}, or the CVSS vector `{CVSS:3.1/AV:N/AC:L/...}`

## AI assistance

- AI assistance: {none, or what the model did: found the bug, wrote the text, wrote the proof}
- Checked by hand: {what you ran or read yourself to confirm each claim}

## Suggested fix

{The change, in the file and function it belongs to.}

```diff
- {vulnerable line}
+ {fixed line}
```

## Limits and non-claims

- Not claimed: {what this report does not say, for example no effect on the default configuration}
- Mocked or assumed: {each mock and assumption, or "nothing: every step runs the released code"}
- Stops working when: {the condition that breaks the path}

## Known issues checked

- Published advisories for this repository: {what you searched, the nearest one, why this differs}
- Issues, pull requests and commits: {what you searched, the nearest match, the difference}
- Security policy: {the rule in SECURITY.md this report falls under, for example the supported versions}

What gets this closed on GitHub

Each reason comes from a page GitHub publishes. The repository’s own security policy and report form add rules on top, and those win.

  1. Closed as not a security risk

    A maintainer who decides the problem is not a security risk closes the advisory, and GitHub asks them to comment why where they can. A report that reads as a bug, a hardening wish or a misconfiguration ends here. Show the security boundary that breaks and who stands on the other side of it.

    Source Managing privately reported security vulnerabilities

  2. A required box left out, or a proof under the minimum

    The default form takes no report without a summary, details, a proof of concept of at least 150 characters and an impact. A repository’s own form can require more boxes and longer answers with min_length, and a report sent through the REST API has to match that form.

    Source Structured forms for private vulnerability reports, Configuring private vulnerability reporting for a repository

  3. No CWE where the repository requires one

    A repository can require at least one CWE on every new report, on the web form and over the API. Name the weakness behind the root cause.

    Source Configuring private vulnerability reporting for a repository, Structured forms for private vulnerability reports

  4. Too many new reports in a day

    Each account has a daily limit on new reports, to one repository and across GitHub, and administrators can set their own daily limit for a repository. A reporter at the limit is asked to try again later. Comments on an advisory you already filed are not limited, and trusted reporters can be put on an allow list.

    Source Rate limits for private vulnerability reports

  5. A report that reads as generated

    GitHub replaced the single free-text box because it made low-quality and AI-generated reports easy to send. Maintainers are told to review any disclosure of AI assistance with the report. Tick the box when a model helped, and send a proof they can run.

    Source Structured forms for private vulnerability reports, Managing privately reported security vulnerabilities

  6. Skipping the security policy

    If the repository has a SECURITY.md, GitHub shows it above the form so you read the maintainer’s guidance before you submit. It is that repository’s own rulebook. Read it before you write.

    Source Privately reporting a security vulnerability, Structured forms for private vulnerability reports

  7. Private reporting is turned off

    You can report privately only where the maintainers turned the feature on. Elsewhere, follow the repository’s security policy, or open an issue that asks for a security contact and nothing more.

    Source Privately reporting a security vulnerability

Challenge the filled draft

Paste the report once every placeholder is replaced. The button below opens a review with Challenge a draft report selected. It argues against each claim: the impact row, the proof, the severity, the known issues. You decide what to rewrite.

The draft stays in this browser. It is sent only when you run a review.

Triager simulation ranks the three reasons a maintainer would close this report. It needs a free account: one passkey prompt, no email, no card.

Run the Triager simulation

Sources

Primary sources only, read on 15 Oct 2026. Rules change. Read the repository’s security policy on the day you submit.

Check the filled draft before you submit

Paste it under Challenge the filled draft. The review marks each claim confirmed, overstated, contradicted or unverifiable, with the line that decides it.