cloudflare-hardening — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited cloudflare-hardening (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Cloudflare gives you a powerful edge layer for free, but its defaults are conservative — most of the protection is opt-in. This skill walks the security-relevant settings and the ones that catch people out.
Applies to Cloudflare's main product (DNS + Proxy + WAF + Workers/Pages/R2). Not Magic Transit / Spectrum specifics.
dnshistory, accidentally A-recorded)Before site settings, harden the account.
Account → Audit Log shows who did what; review monthlyAPI tokens: scope to specific zones + specific permissions. A common mistake is creating a "DNS edit" token at account level when only one zone needs it.
Zone → DNS → Recordsdirect.example.com or origin.example.com left overDNS → Settings. Requires DS record at the registrar.If your origin IP is known-leaked, rotate it — provider panel usually lets you re-assign. Pair with origin allowlist (next step).
Cloudflare proxy is useless if attackers can hit the origin IP directly. Two complementary controls:
1. Authenticated Origin Pulls — origin only accepts TLS connections that present Cloudflare's client cert.
Zone → SSL/TLS → Origin Server → Authenticated Origin PullsThen on your origin nginx:
ssl_client_certificate /etc/ssl/cloudflare/authenticated_origin_pull_ca.pem;
ssl_verify_client on;2. Firewall the origin to Cloudflare's IPs only — at the VPS, restrict 80/443 to CF's published ranges:
# Fetch and ufw-allow only Cloudflare IPs (refresh on a cron)
sudo ufw delete allow 80/tcp
sudo ufw delete allow 443/tcp
for ip in $(curl -s https://www.cloudflare.com/ips-v4); do
sudo ufw allow from "$ip" to any port 80,443 proto tcp comment 'cloudflare'
done
for ip in $(curl -s https://www.cloudflare.com/ips-v6); do
sudo ufw allow from "$ip" to any port 80,443 proto tcp comment 'cloudflare-v6'
done
sudo ufw reloadEither alone is acceptable; both is best. Without one of them, the proxy provides little hardening because attackers will bypass it.
Zone → SSL/TLSEdge Certificates → HSTS. max-age=31536000, includeSubDomains, preload only if you understand the lock-in.Zone → Security → WAFManaged Challenge# Block direct access to wp-admin from outside your country (adjust)
(http.request.uri.path contains "/wp-admin" or http.request.uri.path contains "/wp-login.php")
and ip.geoip.country ne "AT"
→ Action: Managed Challenge
# Block known abusive paths
http.request.uri.path in {"/.git/config" "/.env" "/wp-config.php.bak" "/server-status"}
→ Action: Block
# Tighten login endpoints
http.request.uri.path eq "/wp-login.php" and http.request.method eq "POST"
→ Action: Managed Challenge
# Hide xmlrpc unless you actually use it
http.request.uri.path eq "/xmlrpc.php"
→ Action: Blockhttp.request.uri.path eq "/wp-login.php" → 5 requests / 1 minute per IP → Block 10mYou can inject headers without touching the origin. Rules → Transform Rules → Modify Response Header:
Set: Strict-Transport-Security = max-age=31536000; includeSubDomains
Set: X-Content-Type-Options = nosniff
Set: Referrer-Policy = strict-origin-when-cross-origin
Set: Permissions-Policy = camera=(), microphone=(), geolocation=(), interest-cohort=()
Set: Content-Security-Policy = <see below — app-specific>CSP is too app-specific to template here. Start in `Content-Security-Policy-Report-Only` with a permissive baseline, watch the reports for a week, tighten, then promote to enforcing.
/wp-admin, /admin, /staging, /api/internal/* should not be reachable from the open internet for most projects. Cloudflare Zero Trust (free for ≤ 50 users) gives you SSO-gated access:
Cloudflare Zero Trust → Access → Applications → Add → Self-hosted*.example.com/wp-admin*Allow → emails in @yourcompany.com or specific listNow /wp-admin requires SSO before traffic reaches the origin at all. Brute-force on the WP login endpoint stops being your problem.
(New zones: Page Rules are being phased out in favor of Cache Rules, Configuration Rules, Origin Rules, and Single Redirects.)
Set-Cookie or auth headers/wp-admin/*, /wp-login.php, /cart/*, /checkout/*, /api/* — auth and per-user contentIf you use Pages:
NEXT_PUBLIC_* and similar prefixes still go to the browser. Audit which env vars exist and where they end up.Bucket → Settings → Public access.* unless you understand itZone → Security → Events
Zone → Analytics → SecurityOnce a quarter, walk through:
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.