Cloudflare Setup Guide – Security Headers for comfytechcheck.com
GitHub Pages does not support custom HTTP response headers. Since comfytechcheck.com is hosted on GitHub Pages but proxied through Cloudflare, security headers must be added at the Cloudflare edge.
Two Methods
| Method | Pros | Cons |
|---|---|---|
| A. Transform Rules (recommended) | Works on any plan (Free tier included); visible in dashboard; easy to audit | Must add each header as separate rules or one rule with multiple headers |
B. _headers file (Cloudflare Pages only) |
Declarative, version-controlled with repo | Only works if site is on Cloudflare Pages, not GitHub Pages behind Cloudflare proxy |
Since this site uses GitHub Pages + Cloudflare proxy (not Cloudflare Pages), use Method A.
Method A: Cloudflare Transform Rules (Recommended)
Step 1 – Log into Cloudflare Dashboard
- Go to https://dash.cloudflare.com
- Select the domain comfytechcheck.com
Step 2 – Create an HTTP Response Header Modification Rule
- Navigate to Rules → Transform Rules
- Click the Modify Response Headers tab
- Click Create Rule
- Give the rule a name:
Security Headers -- comfytechcheck.com
Step 3 – Set the Rule Criteria
- When:
Hostname equals comfytechcheck.com - And:
(leave all other fields empty to match all requests)
Step 4 – Add Each Header
Click Add new header for each of the following:
| Header | Value |
|---|---|
Strict-Transport-Security |
max-age=31536000; includeSubDomains; preload |
X-Content-Type-Options |
nosniff |
X-Frame-Options |
DENY |
Referrer-Policy |
strict-origin-when-cross-origin |
Content-Security-Policy |
default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self' |
Permissions-Policy |
camera=(), microphone=(), geolocation=() |
Important: Set the Action dropdown to Set static value for each header. Do not use “Remove” or “Dynamic”.
Step 5 – Save and Deploy
- Click Save
- The rule becomes active within seconds
Header Details
1. Strict-Transport-Security (HSTS)
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
- Forces all communication over HTTPS for 1 year
includeSubDomainscovers all subdomainspreloadallows inclusion in browser HSTS preload lists
2. X-Content-Type-Options
X-Content-Type-Options: nosniff
- Prevents MIME-type sniffing by browsers
3. X-Frame-Options
X-Frame-Options: DENY
- Prevents clickjacking by blocking the site from being loaded in frames
4. Referrer-Policy
Referrer-Policy: strict-origin-when-cross-origin
- Sends full URL as referrer for same-origin requests
- Sends only origin for cross-origin requests
- Sends no referrer when downgrading from HTTPS to HTTP
5. Content-Security-Policy (CSP)
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'
- Restricts resources to same origin
- Allows inline styles (needed for Jekyll)
- Allows
data:URIs for images - Blocks framing (
frame-ancestors 'none') - Restricts form submissions to same origin
- Note: If you add third-party scripts (analytics, affiliate widgets), update the
script-srcdirective accordingly
6. Permissions-Policy
Permissions-Policy: camera=(), microphone=(), geolocation=()
- Disables camera, microphone, and geolocation access
- Can be expanded or relaxed as needed
Verification
After applying the Transform Rule, verify headers are being sent:
Browser DevTools
- Visit https://comfytechcheck.com
- Open DevTools → Network tab
- Click the first request (the HTML document)
- Check the Response Headers section
Command Line (curl)
curl -sI https://comfytechcheck.com | grep -i -E "(strict-transport-security|x-content-type-options|x-frame-options|referrer-policy|content-security-policy|permissions-policy)"
Online Tools
- https://securityheaders.com – Scan the domain for a full report
- https://hstspreload.org – Check HSTS preload eligibility
Cache Busting & Static Asset Optimization
Method A: Enable Auto-Minify in Cloudflare Dashboard
Cloudflare can automatically minify CSS, JavaScript, and HTML at the edge, reducing file sizes without changing your source files.
- Log into https://dash.cloudflare.com
- Select the domain comfytechcheck.com
- Navigate to Speed → Optimization
- Scroll to the Auto Minify section
- Enable the checkboxes for:
- ☑ JavaScript
- ☑ CSS
- ☑ HTML
- Click Apply
Note: Auto-minify works on cached assets. If you update a file, you may need to Purge Cache (Speed → Cache Purge) before visitors see the minified version of the updated file.
Method B: Version Query Strings for Long-Term Caching
For static assets (CSS, JS, images, fonts) that change infrequently, append a version query string to the URL. This lets Cloudflare and browsers cache the file aggressively (e.g., max-age: 31536000), but still fetch the new version when it changes.
Example:
<!-- Before (no versioning -- cache-busting relies on unpredictable filename) -->
<link rel="stylesheet" href="/assets/css/main.css">
<script src="/assets/js/app.js"></script>
<!-- After (version query string -- update the version number on each deploy) -->
<link rel="stylesheet" href="/assets/css/main.css?v=1.0.1">
<script src="/assets/js/app.js?v=1.0.1">
How it works:
- The
?v=1.0.1query parameter is treated by Cloudflare and browsers as a different URL from?v=1.0.0. - Set a long Edge Cache TTL (e.g., 2+ years) under Speed → Cache → Edge Cache TTL so repeat visitors never re-download unchanged assets.
- When you deploy a new version, bump the version string on every changed asset. The browser sees a new URL and fetches the fresh file.
Recommendations for this site:
- Enable Auto Minify (Method A above) for on-the-fly compression.
- Use version query strings (
v=1.0.1) on all<link>and<script>tags in_layouts/default.htmlor wherever static assets are referenced. - Additionally, consider setting a Cache Everything page rule for
/assets/*with Edge Cache TTL of 1 month or longer (Speed → Cache → Cache Rules in the Cloudflare dashboard). - If you use Jekyll’s
asset_urlfilter or a build-time hash plugin, those are alternatives – but a simple version string is the easiest starting point.
Important: The query string must change whenever the file content changes. If you forget to bump the version, visitors may continue to receive a stale cached copy. Use a deployment script or CI step that automatically increments the version number.
HTML Page Caching – Edge Cache TTL via Cloudflare Page Rule
GitHub Pages does not allow configuring Cache-Control headers on HTML responses. By default, GitHub Pages sends Cache-Control: no-cache for HTML pages, which means browsers and CDNs will revalidate every time, increasing latency and origin load.
To solve this, create a Cloudflare Page Rule that forces a 2-hour Edge Cache TTL for HTML pages.
Step 1 – Log into Cloudflare Dashboard
- Go to https://dash.cloudflare.com
- Select the domain comfytechcheck.com
Step 2 – Create the Page Rule
- Navigate to Rules → Page Rules
- Click Create Page Rule
Step 3 – Define the URL Pattern and Settings
- URL pattern:
comfytechcheck.com/* - Pick settings:
- Cache Level: ➔ Cache Everything
- Edge Cache TTL: ➔ 2 hours
(Optionally add Browser Cache TTL: 2 hours to match.)
Step 4 – Save and Deploy
- Click Save and Deploy
- The rule becomes active within seconds
How it works
| Setting | Effect |
|---|---|
| Cache Level: Cache Everything | Overrides Cloudflare’s default behavior (which only caches static assets) to also cache HTML responses. |
| Edge Cache TTL: 2 hours | Tells Cloudflare to serve the cached HTML for up to 2 hours before checking the origin (GitHub Pages) for a fresh copy. Visitors see faster load times and reduced origin load. |
What this rule caches
Because the pattern is comfytechcheck.com/*, all responses (HTML pages, CSS, JS, images) will be cached at the edge for 2 hours. This is fine – Cloudflare automatically respects any Cache-Control headers that GitHub Pages does set on non-HTML assets (e.g., JS/CSS with far-future expires). The only practical change is that HTML pages, which previously were not cached, now get a 2-hour edge TTL.
Verification
# Check the cf-cache-status header -- should return "HIT" on repeat visits
curl -sI https://comfytechcheck.com/ | grep -i "cf-cache-status"
# Check the cache-control header Cloudflare returns to browsers
curl -sI https://comfytechcheck.com/ | grep -i "cache-control"
Alternative: Cloudflare Cache Rules (Newer Approach)
Cloudflare now recommends Cache Rules (under Rules → Cache Rules) over Page Rules for caching. They support more granular matching (e.g., by content type). To target only HTML pages:
- Navigate to Rules → Cache Rules
- Click Create cache rule
- Rule name:
HTML Cache -- 2h TTL - When incoming requests match:
Hostname equals comfytechcheck.comContent Type equals text/html
- Then:
- Edge TTL: Override → 2 hours
- Click Save
This is more precise – it only affects HTML responses and leaves asset caching untouched.
Notes
- GitHub Pages + Cloudflare proxy is a common setup. The
_headersfile in this repo is included for reference and would apply automatically if the site were migrated to Cloudflare Pages. - HSTS preload: After confirming HSTS works, submit the domain to https://hstspreload.org for hardcoded HSTS in browsers.
- CSP tuning: If affiliate scripts or analytics are added, test the CSP in report-only mode first (
Content-Security-Policy-Report-Only) to avoid breaking functionality. - CORS (
Access-Control-Allow-Origin): The site currently returnsAccess-Control-Allow-Origin: *on most responses (Cloudflare’s default for proxied origins). This is fine for a public blog – it allows any website to fetch your content via JavaScript (e.g., for embedded widgets or API access). If tighter CORS is ever needed (e.g., restricting to a specific origin likehttps://app.example.com), create a Cloudflare Transform Rule under Rules → Transform Rules → Modify Response Headers to overrideAccess-Control-Allow-Originwith the desired value. The default (*) is acceptable and recommended for the current use case. - Google Fonts & WOFF2 conversion: The site loads Inter and JetBrains Mono from Google Fonts (
fonts.googleapis.com). Google Fonts automatically detects the visitor’s browser and serves WOFF2 (a highly compressed web font format) to all modern browsers. The raw TTF/OTF download size for these font families totals roughly 1.85MB, but this number is misleading – the actual transferred size is WOFF2, typically around 200–300KB combined for the weights used. Google’s CDN also handles character subsetting per page, so only the glyphs actually needed are downloaded. Do not attempt to self-host or pre-convert these fonts to WOFF2; Google’s server-side format negotiation is more performant and cache-friendly than any local workaround.