subfinder answers one question: what subdomains does this domain have? It never touches the target. Instead it asks passive sources in parallel, from certificate transparency logs (crt.sh, CertSpotter) and web archives to search and threat-intel services such as Shodan, Censys, VirusTotal, SecurityTrails, AlienVault OTX and GitHub code search, then merges and deduplicates the answers. Results come out as plain lines or JSON on stdout, which is the point: it is built to be the first command in a pipe.
It is the entry point of ProjectDiscovery's recon chain. A typical run is subfinder to find names, httpx to see which of them serve a website, and katana to crawl those sites; each tool reads the previous one's output on stdin. Where OWASP Amass builds a whole organisation graph, subfinder stays small and quick, and an optional -active flag resolves names to drop dead ones.
ProjectDiscovery, the company behind the Nuclei scanner, maintains it under the MIT licence. With about 14,700 stars, 141 contributors and 63 releases since 2018 it is one of the most used recon tools on GitHub, and the last push was on 28 October 2026, with v2.17.0 out on 8 October.
- Repository: github.com/projectdiscovery/subfinder
- Licence: MIT (MIT License)
- Language: Go. Stars: 14.7K. Forks: 1,642. Last push: Oct 28, 2026.
- Scan: safe, Oct 28, 2026, commit 98ef871
Who it is for
Security teams keeping an inventory of their own domains, bug bounty hunters starting recon on an in-scope target, and anyone who wants a quick list of a domain's public hostnames to feed into other tools.
Getting started
1. Install with Go (needs Go 1.26.10 or later; release binaries and a Docker image are also published)
go install -v github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest2. List the subdomains of a domain
subfinder -d example.com -silent3. Hand the names to httpx to see which ones serve a website
subfinder -d example.com -silent | httpx -silentIt works without keys, but many of the best sources need one: add them to provider-config.yaml in ~/.config/subfinder, which is created on first run. Each run also checks api.pdtm.sh for a newer version; add -duc to turn that off.
Safety scan
We cloned projectdiscovery/subfinder at commit 98ef871 on Oct 28, 2026 and ran the checks described on the GitHub Tools page: credential patterns, decode-and-execute code, install-time scripts, committed binaries, risky CI workflows, every host the code talks to, known vulnerabilities in pinned dependencies, and project hygiene. A person read every hit. This is what we found.
- No secrets, no pattern hits, no install hooks and no committed binaries across 144 files and about 18,000 lines of Go. The two bare-IP URLs use 8.8.8.8 in a code comment and a test about normalising pasted URLs; hosts like a.example.com and mock.invalid are test fixtures.
- The roughly 40 real hosts the scan lists are the passive sources, one Go file each under pkg/subscraping/sources. The tool only queries those services and never contacts the domain you are researching unless you add -active.
- The update check comes from ProjectDiscovery's shared utils library: it calls api.pdtm.sh with the OS, CPU architecture, Go version, subfinder version and a salted SHA-256 machine ID the code says is for rate limiting. It is documented in the help text as -disable-update-check, but not explained.
- go.mod lists 105 packages with 9 advisories, none rated: seven in golang.org/x/net (HTTP/2 server and HTML parser issues, while subfinder is only an HTTP client), a goldmark Markdown XSS and the deprecated openpgp package. All are indirect dependencies.
- Six workflows, none using pull_request_target; the 11 third-party action uses are pinned to tags, not commits. Dependabot and CodeQL are on, and the security policy is inherited from ProjectDiscovery's organisation, so the repository itself shows none.
What the scanner counted
| Check | Result |
|---|---|
| Secrets | None found. |
| Suspicious code | None found. |
| Install-time code | None: nothing runs at install beyond the package manager itself. |
| Committed binaries | None. |
| CI workflows | 6 workflows. None use pull_request_target. 11 of 11 third-party actions pinned to a tag rather than a commit. |
| Network hosts | 40 distinct hosts referenced from source; most often github.com, a.example.com, b.example.com, 2fa.example.com. 2 URLs to a bare IP address, listed under the raw findings. |
| Known vulnerabilities | 9 advisories across 105 pinned packages: 0 critical, 0 high, 0 moderate, 0 low, 9 unrated. go.mod: 105 packages, 9 advisories. |
| Project hygiene | Has automated dependency updates, CodeQL, licence file. Missing security policy, contributing guide. |
| OpenSSF Scorecard | 6.1 out of 10, as of Oct 19, 2026. |
The raw findings
Every hit the scanner wrote out, with a link to the exact line at the scanned commit. Secrets candidates are redacted.
URLs to bare IP addresses (2)
| Where | Rule | Match |
|---|---|---|
| pkg/runner/util.go:34 | ip-literal-url | // pasted as URLs (e.g. "https://8.8.8.8/foo?a=b") normalize to a bare host |
| pkg/runner/util_test.go:29 | ip-literal-url | {"ip with scheme", "https://8.8.8.8", "8.8.8.8"}, |
Worst known vulnerabilities (9 of 9)
| Advisory | Severity | Package | Summary |
|---|---|---|---|
| GHSA-c97m-vxhj-p7j6 | unknown | github.com/yuin/goldmark@1.7.4 | Cross-site Scripting (XSS) in github.com/yuin/goldmark |
| GO-2026-5932 | unknown | golang.org/x/crypto@0.57.0 | The golang.org/x/crypto/openpgp package is unmaintained, unsafe by design, and has known security issues |
| CVE-2026-78659 | unknown | golang.org/x/net@0.59.0 | HTTP/2 server memory exhaustion due to Trailer headers in net/http |
| CVE-2026-78660 | unknown | golang.org/x/net@0.59.0 | HTTP/2 transport accepts malformed framing-related headers in net/http |
| CVE-2026-78669 | unknown | golang.org/x/net@0.59.0 | Excessive CPU consumption from repeated initial window changes in net/http |
| CVE-2026-78663 | unknown | golang.org/x/net@0.59.0 | Double flow control refund on HTTP/2 server streams in net/http |
| CVE-2026-97032 | unknown | golang.org/x/net@0.59.0 | HTTP/2 server crash due to HPACK encoder race in net/http |
| CVE-2026-78661 | unknown | golang.org/x/net@0.59.0 | Avoid quadratic complexity when coalescing text nodes in html in golang.org/x/net |
| CVE-2026-97045 | unknown | golang.org/x/net@0.59.0 | Check all ancestor namespace transitions when rendering raw text in html in golang.org/x/net |
By the numbers
| Stars | 14.7K |
|---|---|
| Forks | 1,642 |
| Contributors | 141 |
| Commits | 2,302 |
| Open issues | 0 |
| Open pull requests | 1 |
| Releases | 63 |
| Latest release | v2.17.0 |
| Licence | MIT |
| Main language | Go |
| Project age | 8 years |
| Last push | Oct 28, 2026 |
| Tracked files | 144 |
| Lines of code | 18.4K |
| Checkout size | 2 MB |
Lines by language: Go 17.7K, YAML 371, Markdown 322.
Questions
Is subfinder free?
Yes. subfinder is MIT-licensed and free, commercial use included. Some sources it queries are paid services or have free tiers with monthly limits, and the project's disclaimer asks commercial users to follow each source's own terms.
Is it legal to use subfinder on any domain?
subfinder only reads public data that third-party services already hold, and sends nothing to the domain itself, so looking up hostnames is generally lawful. What you do next matters more: probing or scanning those hosts needs the owner's permission, or a bug bounty programme that lists them in scope.
Do I need API keys for subfinder?
No, but results improve a lot with them. Free keys from services like VirusTotal, SecurityTrails, Chaos and GitHub add sources that keyless runs skip. Run subfinder -ls to see every source and which ones need a key.
This post is part of GitHub Tools, where every repository is cloned and scanned before it is written up. The scan is a snapshot of one commit on one day; the repository has moved on since, so check it before you install.
