phphackfix
Self-host

Run your own copy

The checker on this site is a single Cloudflare Pages Function — about 200 lines, no database, no dependencies. Copy it into your own project and it is yours: your rate limits, your logs, your schedule, no shared queue.

Why this page exists. A public endpoint that everyone points their scripts at is a denial-of-service waiting to happen — the tool would fall over exactly when a lot of people need it. So the public one takes 25 domains at a time, sequentially. If you have a real inventory, run your own: it takes ten minutes and costs nothing at this scale.

What you need

1. Make a project

mkdir my-checker && cd my-checker
mkdir -p functions/api public
echo '<!doctype html><title>checker</title><p>POST /api/check</p>' > public/index.html

2. Drop in the function

Save this file as functions/api/check.js. It is plain JavaScript — Cloudflare runs it at the edge.

Open the source

MIT licensed — use it, change it, ship it commercially. No attribution required, though a link back is appreciated.

3. Deploy

npx wrangler login
npx wrangler pages project create my-checker --production-branch main
npx wrangler pages deploy public --project-name my-checker --branch main

You get a URL like https://my-checker.pages.dev. That is the whole deployment.

4. Prove it works

curl -s -X POST https://my-checker.pages.dev/api/check \
  -H 'content-type: application/json' \
  -d '{"url":"example.com"}'

A GET on the same path returns usage notes. A private address (127.0.0.1, 169.254.169.254) must be refused — the function blocks loopback, private, link-local and .internal hosts so it cannot be used as an SSRF proxy.

5. Run a list, one domain at a time

This script checks sequentially with a pause between requests and writes a CSV. Keep it serial: parallel checks look like an attack from the other end and get you blocked by the firewall you are trying to assess.

Open the script

ENDPOINT=https://my-checker.pages.dev ./check-domains.sh domains.txt results.csv

domains.txt is one host per line. DELAY=2 raises the pause. The output has three verdicts and one rule: unknown is not a pass.

6. Protect it (optional but sensible)

Cloudflare dashboard → your zone (or the pages.dev project) → Security → WAF → Rate limiting rules:

If you are on *.pages.dev without a zone, put a shared secret in the function instead — add a header check against a value in env and call it with curl -H "x-key: …".

What this cannot do

A note on etiquette and the law

One GET per domain is what a browser does, and passive version reading is broadly tolerated — but "broadly tolerated" is not "permission". Check sites you own or have written authorisation for, respect robots.txt and rate limits, and do not point this at third parties to build a list of targets. The ownership checkbox in the public UI is not decoration: it is the boundary that keeps a defensive tool defensive.