This site is not affiliated with or endorsed by Cloudflare, Inc. It showcases deployable experiments across most Cloudflare products.
Network & Monitoring

Security Headers Grader

Grade HTTP security headers (HSTS, CSP, X-Frame-Options, and more) for any URL - security header audit from the edge

Fetch any URL from Cloudflare's edge and score its security headers with pass/warn/fail guidance.

Features

  • Grades HSTS, CSP, clickjacking protection, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, and Cross-Origin-Opener-Policy
  • Returns a numeric score (0–100) and letter grade (A–F)
  • Uses HEAD with GET fallback when origins reject HEAD
  • Stateless; no bindings required

API Reference

GET /grade

Prop

Type

Example Request

curl "https://your-worker.workers.dev/grade?url=https://www.cloudflare.com"

Success Response

url string

Final URL after redirects

score number

Average score from 0–100 across all checks

grade string

Letter grade: A, B, C, D, or F

checks array

Per-header results with header, status (pass | warn | fail | missing), detail, and recommendation

headers object

Raw response headers as lowercase key/value pairs

{
  "url": "https://www.cloudflare.com/",
  "score": 71,
  "grade": "C",
  "checks": [
    {
      "header": "Strict-Transport-Security",
      "status": "pass",
      "detail": "max-age=31536000; includeSubDomains; preload",
      "recommendation": "Looks good"
    }
  ],
  "headers": {
    "strict-transport-security": "max-age=31536000; includeSubDomains; preload"
  }
}

Error Codes

  • 400 - Missing or invalid url (INVALID_URL)
  • 502 - Fetch failed (FETCH_ERROR)

Use Cases

  • Audit security headers before launching a site
  • Compare header posture across environments
  • Teach Workers fetch + header analysis patterns
  • Generate actionable remediation tips for missing headers

Limitations

  • Scoring is heuristic, not a formal compliance audit
  • Does not execute or fully validate CSP policy correctness
  • Only inspects response headers visible to the edge fetch

Use in your project

Copy these files into an existing Worker. Prefer Deployment to try the full experiment first. Source: apps/experiments/security-headers-grader.

DependenciesNoneBindingsNonePlatformFetch API
import { FETCH_TIMEOUT_MS, USER_AGENT } from "../constants/defaults";import { headersToRecord } from "./url";export type FetchHeadersResult =  | { ok: true; url: string; headers: Record<string, string>; method: "HEAD" | "GET" }  | { ok: false; error: string };function shouldRetryWithGet(status: number): boolean {  return status === 405 || status === 501 || status === 400 || status === 403;}async function fetchWithMethod(  url: string,  method: "HEAD" | "GET",  signal: AbortSignal): Promise<Response> {  return fetch(url, {    method,    redirect: "follow",    signal,    headers: { "User-Agent": USER_AGENT },  });}/** * Fetches response headers using HEAD, falling back to GET when needed. */export async function fetchResponseHeaders(url: string): Promise<FetchHeadersResult> {  const controller = new AbortController();  const timeoutId = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);  try {    let method: "HEAD" | "GET" = "HEAD";    let response = await fetchWithMethod(url, method, controller.signal);    if (shouldRetryWithGet(response.status)) {      method = "GET";      response = await fetchWithMethod(url, method, controller.signal);    }    clearTimeout(timeoutId);    return {      ok: true,      url: response.url || url,      headers: headersToRecord(response.headers),      method,    };  } catch (e) {    clearTimeout(timeoutId);    const message = e instanceof Error ? e.message : "Unknown error";    return { ok: false, error: message };  }}

Deployment

Click the deploy button

Deploy to Cloudflare Workers

Deploy

Follow the deployment wizard. No bindings or secrets required.

Test your deployment

curl "https://your-worker.workers.dev/grade?url=https://example.com"

Local Development

cd apps/experiments/security-headers-grader
npm install
npm run dev
curl "http://localhost:8787/grade?url=https://www.cloudflare.com"

Cloudflare Features Used

Next Steps

On this page