# h1domains: turning HackerOne scope pages into a list you can work from

> h1domains runs one command and produces the domains that HackerOne programmes list as in scope, filtered into plain and with-bounty variants and into text and comma separated forms. The output is more precise than a hostname list, with wildcard prefixes, path-scoped URLs and a placeholder top level domain, and the entries carry the fingerprints of programmes that have grown large.

**zricethezav/h1domains** — HackerOne "in scope" domains

- Repository: https://github.com/zricethezav/h1domains
- Website: https://www.hackerone.com/
- Stars: 533 · Forks: 133
- Language: Python
- License: not declared
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/zricethezav-h1domains

## One command produces the scope list

h1domains collects HackerOne in-scope domains, and the entire usage is one line:

```bash
`python3 hackerone.py`
```

That is the whole instruction. There is no configuration, no arguments and no setup described, which tells you the tool is intended to be run and its output consumed rather than configured and used.

The listing that results is headed Domains with Bounties, and it carries a timestamp in the heading itself, the last updated line giving a day, a date, a time and the year in UTC. That timestamp is the single most important piece of metadata in the repository, because the list of what a bug bounty programme will accept changes constantly, and a scope list without a date is worse than no list at all.

The repository top level shows what else is produced alongside the list. There is domains.txt and domains.csv, and a domains_with_bounties.txt. There is a matching set for source code, source_code.txt, source_code.csv and source_code_with_bounties.txt. And there is a run.sh alongside the script itself.

So the design separates two things that a bug bounty researcher needs to keep apart. The domains are the targets, the hosts whose in-scope assets the programme covers. The source code entries are the programmes themselves, the repositories and code that are offered for review. Both are output in both a plain text and a comma separated form, and both have a variant filtered to the ones that actually carry a bounty.

The distinction between the two filtered and two unfiltered variants is the part that makes the tool useful rather than a raw dump, because a programme can be listed for visibility without being open for reward.

## The scope entries are more precise than hostnames

A list of domains is easy to write and usually wrong, and this one shows the awkward cases in the open.

Most entries are plain hostnames. But a substantial number carry a wildcard prefix, which means every subdomain of that host is in scope rather than the host alone. And a smaller number are not hostnames at all but full URLs including a path, which scopes a single endpoint rather than a whole service.

```text
store.playstation.com
*.grab-sure.com
npmjs.org
https://ebctest.cybersource.com/tss
*.audible.(TLD)
aebddc74953f248bc8455665b0f7d47b-78af959a11e5d0c1.elb.us-east-1.amazonaws.com
```

The path-scoped entries are the interesting ones. An entry like a URL ending in a particular API path means the programme has granted a bounty on that endpoint and not on the rest of the service, which is a common arrangement for payment and identity providers who want testing focused on one integration surface.

One entry uses a literal placeholder for the top level domain, which is a way of expressing a rule rather than a host. It means every top level domain is covered, which is what a programme says when its scope is a pattern rather than a list, and it is the kind of rule that a naive parser would choke on.

There are also entries that are clearly not hostnames at all, a bare path on a well known host in one case and a string that looks like a load balancer target in another. Those come from programmes whose scope is written as a resource path or a specific internal endpoint rather than as a public domain, and they are a reminder that the source of truth is a text field entered by a human in a web form.

This is where the timestamp earns its keep. The precision of the entries varies because the programmes write them by hand, and they change as programmes are updated, as assets are acquired and as policies are revised.

## One programme family dominates the list

Read across the list and one customer appears over and over, and the pattern is instructive about how bug bounty scope is actually written.

A large cluster of entries belongs to a single sports organisation's properties, and the cluster is not one host but dozens. They are spread across several distinct properties, and they are split by environment.

The split is the notable part. There are production hosts, and alongside them there are quality assurance hosts, development hosts and staging hosts, each with a distinguishing prefix such as a QA or dev or UAT marker in the subdomain. One entry even carries a hyphenated environment marker rather than a dotted one.

That is what a large scope list actually looks like when a programme has grown. The scope is not a nice small set, it is every environment the company runs, including the ones that are supposed to be unreachable, because a bug bounty researcher is exactly the person who will find the way to reach them.

The same shape appears for a payments provider, with a single entry carrying a placeholder for the top level domain, and for a sports league's properties, with the same environment-prefixed pattern repeated across its teams.

So the list is a cross-section of large programme portfolios rather than a curated shortlist, and the clustering reveals which programmes have made scope decisions at scale and which have not.

## Why this is worth automating at all

The obvious question is why a script is needed to produce a list of domains, and the answer is that the list does not exist anywhere as a list.

Scope on a bug bounty platform is a field inside a programme. Each programme has an asset type, and each asset has a set of instructions which may or may not include the domains that are in scope. Across a large number of programmes, those instructions collectively contain a few hundred domain strings, buried in prose written for a human to read, and no single place lists them.

So the useful operation is not fetching a page but extracting and normalising. Once the domains are extracted, the second useful operation is joining them against which programmes actually carry a bounty, because a programme with a bounty is the one you want and a programme without one is a distraction.

That is what the four filtered and unfiltered output files encode. The with_bounties variants are the working set, and the plain variants are the complete picture, which is what you need when you want to know whether a domain is out of scope everywhere or simply not funded right now.

The comma separated output is there for the same reason as the plain text, and both are kept because the two have different uses. A text file is what you grep, and a comma separated file is what you load into a spreadsheet or a script that is doing something systematic with the data.

There is a third category of output in the repository, and it is the one that changes the character of the project. Alongside the domains there are entries for source code, which means the tool also gathers the repositories and code that programmes offer for review, that is the vulnerability disclosure side that runs alongside the asset side.

A researcher looking for work is usually looking for one of three things, a target to test, a codebase to read, or a program with a bounty that has room in its payout structure. This repository is a starting point for all three, and the filtering is what turns a large platform into a shortlist.

## What the repository does not tell you

It is worth being clear about the boundaries of this project, because the name suggests something more conclusive than it is.

First, the output is a scope list, not an authorisation. A domain appearing here does not mean the programme wants you to test it, and it certainly does not mean you may. What it means is that the programme lists that domain as in scope, which is the first filter any responsible researcher applies and not the last one. The instructions attached to each programme, including the rules of engagement and the testing limits, are what actually govern what you may do, and those are not reproduced here.

Second, a domain that is absent may still be in scope, because a programme may describe its scope in prose without listing a hostname, or may list it in a field the script does not read. The list is a superset of nothing and a subset of everything.

Third, the list is only as fresh as the last run. The timestamp in the heading tells you when it was generated, and the fact that the run is a single command with no built-in scheduling means freshness depends on somebody running it.

Fourth, the entries are raw text from the programmes, which is why there is a placeholder top level domain in one of them and a path that is not a hostname in another. Nothing in the output validates the shape of an entry.

The licence is not recorded in the repository metadata, which matters for a project that scrapes another platform's public content, and the project is MIT in spirit by the look of the repository but that is not a claim to make without the file.

The last push was on 2026-10-20, and the timestamp on the listing in the readme matches that date, so the committed list was generated from a run on the same day it was last touched. The repository is not archived and there are no GitHub releases, so the list in the readme is the version to compare against.

## Conclusion

h1domains suits a bug bounty researcher who wants a working list of targets rather than reading every programme page, and the with_bounties filtering plus the separate source code output are what make it more than a domain scrape. It does not suit you as a substitute for reading a programme's own rules, because a domain in the list is not an authorisation to test it and a missing domain may still be in scope. Before you act on any entry, read the programme instructions attached to it, and check the timestamp in the listing heading against the last push, because the data is only as fresh as the last run and there is no scheduled refresh.

## FAQ

### What does the h1domains project do?

It collects HackerOne in-scope domains. Running python3 hackerone.py produces domains.txt and domains.csv alongside domains_with_bounties.txt, and a matching set for source code entries, with the plain files covering everything and the with_bounties files filtered to the programmes that actually carry a reward.

### Why do some of the h1domains entries include a full URL path rather than just a hostname?

Because the programme scopes a single endpoint rather than a whole service, which is common for payment and identity providers who want testing focused on one integration surface. Some entries also carry a wildcard prefix to cover every subdomain, and one uses a placeholder for the top level domain to express a rule rather than a host.

### Does appearing in the h1domains list mean I am allowed to test that domain?

No. The list records what programmes state as in scope, which is a first filter and not an authorisation. The rules of engagement and testing limits are attached to each programme and are not reproduced in this repository, and a domain absent from the list may still be in scope if the programme describes it in prose.

### How does h1domains handle environment specific subdomains?

It lists them individually. The committed list contains many hosts with a quality assurance, development or UAT marker in the subdomain for the same organisation, alongside production hosts, which is what a programme with a large internal estate looks like when it lists every environment it runs.

### How current is the h1domains data?

The listing carries a last updated timestamp in its heading, and the committed list was generated from a run on the same date as the last push to the repository, 2026-10-20. There are no GitHub releases and the run is a single command with no scheduling, so freshness depends on it being run.

## Sources

- [Issues](https://github.com/zricethezav/h1domains/issues)
- [Project website](https://www.hackerone.com/)
- [README](https://github.com/zricethezav/h1domains/blob/master/README.md)
- [zricethezav/h1domains on GitHub](https://github.com/zricethezav/h1domains)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/zricethezav-h1domains
