Open-source project
projectdiscovery/public-bugbounty-programs avatar
projectdiscovery/public-bugbounty-programs

public-bugbounty-programs: a machine readable registry of disclosure programmes

Community curated list of public bug bounty and responsible disclosure programs.

1,354 stars391 forksGoMIT

At a glance

What is it?
This repository is a community curated list of public bug bounty and responsible disclosure programmes, stored as YAML, validated against a JSON schema and compiled into JSON so that reconnaissance tooling can consume it. It suits a security engineer who wants to know which programmes cover a domain before deciding whether a target is in scope, and it is a data project with a Go build around it.
Who is it for?
public-bugbounty-programs fits a security engineer running reconnaissance who needs a current, machine readable answer to whether a domain has a disclosure programme, because the data is compiled to JSON and checked for broken links and duplicate domains on every build.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 6 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 7, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • projectdiscovery/public-bugbounty-programs1,354 ★ · +0
Star history
Repository2026-10-172026-11-07
projectdiscovery/public-bugbounty-programs1.4k1.4k

0 Stars in the last 21 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

The output is JSON, and that is the point

This repo serves as the central management system for the public bug bounty programs used on Chaos by ProjectDiscovery.

The framing is a data project with a build system around it, and the data model is the interesting part. The source file is `src/data.yaml`, the schema is `src/data.schema.json`, and the data is generated in JSON format and can be found in `dist/data.json`.

So the pipeline is YAML in, JSON out, with a schema in between. That is not an incidental choice. A YAML file is pleasant to hand edit and pleasant to review in a pull request, and it is a poor format for a program to consume at scale, while JSON is the opposite. Splitting the two lets contributors work in the readable format and consumers work in the fast one, and the schema is the contract that keeps the two in step.

Each program entry includes four fields. `name` is a string, `url` is an http or https URL, `bounty` is a boolean, and `domains` is an array of root or apex domains. The example entry in the data file is exactly that:

yaml
- name: Example Bug Bounty Program
  url: https://example.com/bugbounty
  bounty: true
  domains:
    - example.com
    - example.org

The `bounty` boolean is the field that earns its place, because a responsible disclosure programme and a paid bug bounty programme are different things, and a tool deciding whether to keep scanning a domain needs to know which kind of relationship exists. A disclosure programme means reports are accepted and may or may not be paid, a bounty programme means there is a stated reward structure. A tool that cannot tell them apart will either miss paid programmes or report findings into a channel that does not pay.

The `domains` field being root or apex domains rather than full URLs is also deliberate. A programme covers a domain, and the tool wants to answer a domain-level question.

The Makefile is the real specification

The Makefile is where the project's guarantees live, and it is worth reading line by line because each target encodes a different failure mode.

There are three variables naming the three files, `DATA_IN` as `src/data.yaml`, `DATA_OUT` as `dist/data.json` and `DATA_SCHEMA` as `src/data.schema.json`, and then the targets.

`lint` runs `yamllint` on the source. That is a style check on the YAML, and it is what stops a contribution from arriving with tabs, trailing spaces or an inconsistent indentation style, which matters in a file where the whole point is that hundreds of people can edit it.

`compile` depends on `lint`, and then runs `yq eval -P -o=j` on the input piped into `jq -c`. So the YAML becomes JSON through yq and is then compacted by jq, which is why the output has one entry per line rather than pretty printed. That is a deliberate choice for a file that is read by machines, and it also makes diffs readable when a hundred lines change.

`test` runs `ajv test` against the schema with the data as the document, using `--valid --all-errors --errors text`. ajv is a JSON Schema validator, and the flags matter. `--valid` means the schema itself is checked, and `--all-errors` means every violation is reported rather than the first, which is the difference between one useful error message and a long tail of them.

Then there are three checks that go beyond the schema, and they are the most interesting part of the file.

`policy-checks` runs a Go program, `./cmd/httpx-tester/main.go`, against the compiled data with the output going to a temporary file, and if the file is not empty it prints the invalid URLs found. `validate-domains` does the same with `./cmd/validate-domains/main.go`.

And `duplicate-domains` is the one that enforces a policy. It extracts every domain with `jq -r '.programs[].domains[]'`, sorts and counts them with `sort | uniq -c`, and prints any that appear more than once with an `awk` filter on a count above one. If the temporary file is non-empty it prints the duplicates, removes the file, and exits 1.

So a domain that appears under two different programmes is a build failure. That is a stronger rule than most curated lists apply, and it makes sense here, because a duplicate means the tool cannot answer the question unambiguously.

The Go side exists to check things the schema cannot

The Go module explains the shape of the project better than any prose would, because the dependency list tells you exactly what the build needs.

The module is `github.com/projectdiscovery/public-bugbounty-programs` and it requires go 1.26. The direct dependencies are the ProjectDiscovery stack: `httpx` at v1.10.0, `retryabledns` at v1.0.115, `goflags` at v0.1.76, `gologger` at v1.1.72 and `utils` at v0.11.1, plus `yaml.v3` for parsing, `govalidator` for validation, `pkg/errors`, `testify` for tests, `golang.org/x/net` and `bytedance/sonic`.

The presence of httpx is the giveaway. httpx is a reconnaissance tool, and using it here means the URL check is a real HTTP request rather than a regex against a string. The `httpx-tester` program is making a request to each programme's URL and reporting the ones that do not answer, and `retryabledns` is there because a DNS failure should not be reported as a dead programme URL. That distinction matters: a programme whose domain fails to resolve today is usually a temporary DNS problem, and a list that removed entries on transient failures would be useless.

The repository layout follows the pipeline. There is `src/` with the data and the schema, `dist/` with the generated JSON, `cmd/` with the two Go programs, `internal/` for the Go code, `src/` for the data, plus a `Makefile`, a `.yamllint` configuration and a `LICENSE.md`.

The `sonic` dependency is a nice detail. It is a high performance JSON library, and it is a reasonable inclusion for a tool whose job is to parse a large JSON document quickly.

And the licence is MIT, with the last push on 2026-09-14 and no GitHub releases, which is consistent with a repository whose deliverable is a data file that is regenerated on every build rather than a versioned artefact.

Contributing, and the references the list was built from

The contribution model is stated in one paragraph, and it is a good description of what makes a list like this work.

We welcome your contributions to this list. If there are specific programs for which you would like to see reconnaissance data, please submit a pull request. Make sure to give the contributing guidelines a quick read first so everything runs smoothly.

The phrase that would like to see reconnaissance data is the interesting one, and it tells you what the list is for. A programme is not just a name and a link, it is a set of domains that a reconnaissance tool can check against to decide whether the target is in scope. So contributing an entry means asserting that this programme covers this domain, which is a claim with consequences, and the pull request review is where that claim gets checked.

The contributing guidelines live in `.github/CONTRIBUTING.md`, and the documentation repeats the pointer twice, once in the data section and once in the guidelines section at the end, which is a reasonable way to make sure a contributor who skims the page still finds it.

The references section is a good indicator of where this list sits relative to the others that exist. It names three: the arkadiyt/bounty-targets-data repository, the disclose/diodb program-list.json file, and firebounty.com.

Two of those are raw data and one is a service, which tells you the list is a curation of other people's curation rather than a from-scratch effort, and that the value it adds is the schema, the validation and the fact that it is compiled for a specific tool's consumption.

The community routes are the standard ProjectDiscovery set. GitHub Discussions for inquiries, suggestions or topics to discuss, the Discord community for more interactive discussion, the Twitter account for news, and a contact email address. The README closes by asking for contributions to help continually improve and expand the range of public bug bounty programs featured.

The last line is a nice touch, thanking contributors for their efforts in keeping the community dynamic and engaging, which is an accurate description of what the work actually involves. This list only stays useful if someone checks the links.

What the data can and cannot tell you

There is a limit to what a four-field entry can express, and it is worth being clear about it before anyone builds on the list.

The `bounty` boolean is a single bit. A programme can have a bug bounty for some products and only a disclosure programme for others, can have a bounty range that depends on the severity of the finding, and can have a policy that excludes certain classes of test entirely. None of that fits in a boolean, and none of it is captured here.

The `domains` field is a list of apex domains with no indication of which subdomains are excluded. Programmes frequently scope to a set of properties or apps and exclude everything else, and a tool that sees `example.com` in the list may treat an entire domain as in scope when the programme would not.

The `url` field can go stale. That is exactly why the build has a `httpx-tester` target, but the test only proves the page answers, not that the programme still exists, since a programme that has been quietly retired often leaves a page behind for a while.

So the list answers a narrow question well, does this domain have a disclosure programme, and it is a starting point rather than a source of scope. The security-relevant step is reading the programme's own policy, and the README points to the programmes rather than reproducing their terms, which is the right boundary for a list that anyone can contribute to.

There is also a scope question the data model does not address, and it is a design decision rather than an omission. The list contains public programmes only. A private programme, a bug bounty run through a third party platform, or a programme reachable only through a customer relationship is not represented, and a scanner consulting this list will treat those domains as having no programme at all.

The alternative approaches are worth naming. The references at the end of the README are the alternatives, and a commercial aggregator would be a third. The difference in approach is that this list is a data file with a schema and a build, which means it is reproducible and diffable, where an aggregator is a service you query and a raw list is a file you have to parse. For a tool that wants to embed the answer, the compiled JSON is the useful artefact, and for a person, the programme's own page is still the authority.

Editorial conclusion

public-bugbounty-programs fits a security engineer running reconnaissance who needs a current, machine readable answer to whether a domain has a disclosure programme, because the data is compiled to JSON and checked for broken links and duplicate domains on every build. Skip it if you want a one-off answer for a single domain, since the same information is on each programme's own page, and read each programme's scope before you rely on an entry, because a domain listed here means the programme claims it, not that your particular test is in scope. Before you contribute, read the contributing guidelines, and note the licence is MIT with the last push on 2026-09-14 and no GitHub releases, so the data file is the artefact to track.

Frequently asked questions

What is the public-bugbounty-programs repository?

It is a community curated list of public bug bounty and responsible disclosure programmes, described as the central management system for the public bug bounty programs used on Chaos by ProjectDiscovery, with the source in YAML and the output compiled to JSON.

What fields does each program entry contain?

Four: a name string, an http or https url, a bounty boolean, and an array of root or apex domains. The data lives in src/data.yaml, the schema in src/data.schema.json, and the generated JSON in dist/data.json.

How is the data validated in the public-bugbounty-programs build?

The Makefile runs yamllint on the YAML, compiles it with yq and jq, validates the result against the JSON schema with ajv, checks the URLs with a Go httpx-based program, validates the domains with a second Go program, and fails the build when a domain appears under more than one programme.

Can I contribute a programme to the list?

Yes, by opening a pull request, and the README asks you to read the contributing guidelines in .github/CONTRIBUTING.md first so that everything runs smoothly.

What licence does the public-bugbounty-programs list use?

MIT, with the licence in LICENSE.md. The repository has no GitHub releases and the last push was on 2026-09-14, so the compiled data file is the artefact to watch rather than a version number.

Official sources

  1. Issues
  2. License: MIT
  3. projectdiscovery/public-bugbounty-programs on GitHub
  4. Project website
  5. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/projectdiscovery-public-bugbounty-programs.svg)](https://hysenlabs.com/projects/projectdiscovery-public-bugbounty-programs)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/projectdiscovery-public-bugbounty-programs.svg)](https://hysenlabs.com/projects/projectdiscovery-public-bugbounty-programs)

Was this useful?