Route ProjectDiscovery's recon CLIs — katana, httpx, and subfinder — through ProxyHat residential proxies. A tiny helper CLI (and Go library) that prints a ProxyHat gateway URL with geo-targeting, rotation, and sticky sessions, ready to drop into each tool's -proxy flag.
Tip
Recommended proxies — ProxyHat residential IPs. Every feature in this package is tested end-to-end against ProxyHat and works great. First-class integration; also works with any proxy, or none.
katana, httpx, and subfinder each accept a single proxy flag but have no notion of residential rotation or geo-targeting. ProxyHat encodes all of that into the proxy username, so the integration is deliberately small: it emits one gateway URL — http://<user>-country-us:<pass>@gate.proxyhat.com:8080 — that you paste into any of the three. A fresh residential IP per request by default (50M+ IPs across 148+ countries), one pinned IP when you want a session, and country/region/city targeting baked in. No plugins, no config files, no per-tool glue.
go install github.com/ProxyHatCom/projectdiscovery-proxyhat/cmd/projectdiscovery-proxyhat@latestRequires Go 1.21+. Pure standard library — no third-party dependencies. The ProjectDiscovery tools themselves are installed separately (go install github.com/projectdiscovery/katana/cmd/katana@latest, etc.).
Emit a URL and feed it to a tool via command substitution. Note the flag differs by tool — katana and subfinder use -proxy, httpx uses -http-proxy (it also accepts -proxy as an alias):
export PROXYHAT_USERNAME=... PROXYHAT_PASSWORD=... # or PROXYHAT_API_KEY=...
# katana — -proxy "http/socks5 proxy to use"
katana -u https://example.com -proxy "$(projectdiscovery-proxyhat url -country us)"
# httpx — -http-proxy "proxy (http|socks) to use (eg http://127.0.0.1:8080)"
httpx -l hosts.txt -http-proxy "$(projectdiscovery-proxyhat url -country de)"
# subfinder — -proxy "http proxy to use with subfinder"
subfinder -d example.com -proxy "$(projectdiscovery-proxyhat url -country gb)"Each projectdiscovery-proxyhat url call prints exactly one line to stdout:
$ projectdiscovery-proxyhat url -country us
http://acme-country-us:s3cret@gate.proxyhat.com:8080
Get an API key at proxyhat.com.
| Tool | Flag | Upstream description |
|---|---|---|
| katana | -proxy |
http/socks5 proxy to use |
| httpx | -http-proxy (alias -proxy) |
proxy (http|socks) to use (eg http://127.0.0.1:8080) |
| subfinder | -proxy |
http proxy to use with subfinder |
Gateway auth uses a sub-user's proxy_username + proxy_password (not the account API key). Pass them via flags or environment variables — flags win over env:
| Flag | Env var | Notes |
|---|---|---|
-username |
PROXYHAT_USERNAME |
Explicit gateway proxy_username (skips the API) |
-password |
PROXYHAT_PASSWORD |
Explicit gateway proxy_password |
-api-key |
PROXYHAT_API_KEY |
Auto-selects an active sub-user with remaining traffic |
-sub-user |
PROXYHAT_SUBUSER |
Pick a specific sub-user by uuid or name (with an API key) |
With an API key, the CLI calls the management API (GET https://api.proxyhat.com/v1/sub-users) once and picks the first sub-user that isn't suspended and still has traffic. Prefer environment variables so credentials never land in your shell history.
projectdiscovery-proxyhat url \
-country us \ # ISO code; omit for no country constraint
-region california \ # state/region slug
-city new_york \ # city slug
-filter high \ # AI IP-quality tier
-socks5 # use the SOCKS5 gateway (port 1080) instead of HTTP (8080)-socks5 emits a socks5://... URL on port 1080 — accepted by katana and httpx (http|socks); subfinder is HTTP-proxy only, so leave it off there.
- Rotating (default): the username stays stable, so the gateway hands out a fresh residential IP per connection — ideal for spreading a scan across many IPs.
- Sticky:
-sticky(or-sticky-ttl 12h) mints a session id so every request through that URL exits from the same pinned IP for the TTL (default30m) — handy when a flow must look like one continuous client.
# One pinned IP for this run:
httpx -l hosts.txt -http-proxy "$(projectdiscovery-proxyhat url -country gb -sticky-ttl 30m)"Each invocation of url -sticky mints a new session id, so re-running gives a new pinned IP. Want several concurrent sticky identities? Generate several URLs and route each tool run to its own.
ProxyHat exposes a single gateway (gate.proxyhat.com, 8080 HTTP / 1080 SOCKS5). All targeting is encoded into the proxy username using ProxyHat's grammar:
<proxy_username>-country-<iso>[-region-<slug>][-city-<slug>][-sid-<16hex>-ttl-<dur>][-filter-<tier>]
The CLI resolves your sub-user credentials, mints a sticky session id if requested, and prints a *url.URL string like http://<user>-country-us:<pass>@gate.proxyhat.com:8080. The tool you hand it to sends the userinfo as Proxy-Authorization on every request. A rotating username carries no sid, so the gateway rotates the exit IP per connection; a sticky username carries a fixed sid, so the IP stays pinned.
The same builder is importable if you'd rather generate URLs in Go:
import proxyhaturl "github.com/ProxyHatCom/projectdiscovery-proxyhat"
u, err := proxyhaturl.URL(
proxyhaturl.Country("us"),
proxyhaturl.Sticky(),
)
// u == "http://<user>-country-us-sid-...-ttl-30m:<pass>@gate.proxyhat.com:8080"URL is offline with explicit/env credentials; it makes one management-API call only for the -api-key path. Use URLContext(ctx, ...) to govern that lookup. See examples/main.go.
The current integration is a URL emitter — the smallest thing that works across all three tools today. Planned follow-ups (tracked upstream, not yet attempted here):
- Native ProxyHat provider PRs so katana / httpx / subfinder can target geo and sessions directly (e.g.
-proxyhat-country us) without shelling out. - A
-tool {katana|httpx|subfinder}mode that prints the full flag (-proxy <url>/-http-proxy <url>) for the selected tool.
MIT © ProxyHat