This site is not affiliated with or endorsed by Cloudflare, Inc. It simply showcases experiments built using Cloudflare services.
Cloudflare Experiments
Network & Monitoring

Security Headers Grader

Grade HTTP security headers (HSTS, CSP, XFO, and more) for any URL 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