Files
istos 3bc7e6ec7e site: let the analytics beacon through img-src
Fathom sends its pageview as an image request. script-src named the
origin and img-src did not, so the script loaded and the one thing it
loads to do was blocked — visible only in the browser console, with a
200 on every response and no pageview at the other end.

The console said it plainly:

  Loading the image 'https://cdn.usefathom.com/?h=...&sid=ZPKDEHCV...'
  violates the following Content-Security-Policy directive: img-src
  'self'

A test now asserts the origin appears under all three directives it
actually uses, because nothing on this side of the wire can tell that it
does not.
2026-07-31 16:15:50 +02:00

62 lines
3.4 KiB
Plaintext

# Response headers for bench.12vectors.com.
#
# Read by Cloudflare Workers static assets at deploy time — the file is
# consumed, never served — and copied here from site/root/ by
# site/build.py, because the host looks for it at the root of the build
# and nowhere else.
#
# Rules do NOT override each other: a header two matching rules both set
# arrives concatenated. Measured on the live site, not assumed —
# /* and /static/* both setting Cache-Control produced
#
# cache-control: public, max-age=0, must-revalidate, public,
# max-age=31536000, immutable
#
# on the stylesheet, and the first max-age wins in every browser, so the
# year-long cache never happened. So exactly one rule may set a given
# header: Cache-Control is set on /static/* alone, and HTML is left to
# the host's own default, which is the revalidating one. Check #4 after a
# deploy is what keeps that honest.
# Everything, so that no page can ever forget one of these.
#
# nosniff a text/plain file must not become a script
# Referrer-Policy a full url is never sent to another origin
# HSTS one year, this host and anything below it. No
# `preload`: that is a submission to browser
# vendors and a commitment this card did not make
# X-Frame-Options nothing here is meant to be framed
# CSP the runtime form of the site's own promise.
# `default-src 'none'` means an asset must be
# named below to load at all, and no
# 'unsafe-inline' anywhere means an injected
# <script> does not run. One origin besides
# 'self' is named: cdn.usefathom.com, which
# serves the analytics script and receives its
# pageviews. It appears in THREE directives, and
# img-src is the one that is easy to miss:
# Fathom sends its pageview as an image request,
# so script-src alone loads the script and blocks
# everything it was loaded to do — silently, on
# the browser's side, where no deploy check
# looks. Fathom sets no cookie and collects
# nothing about a person, which is why it needs
# no banner — but it is a third party, and the
# policy says so out loud rather than quietly
# allowing everything
/*
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Frame-Options: DENY
Content-Security-Policy: default-src 'none'; style-src 'self'; font-src 'self'; img-src 'self' https://cdn.usefathom.com; script-src https://cdn.usefathom.com; connect-src https://cdn.usefathom.com; base-uri 'none'; form-action 'none'; frame-ancestors 'none'
# The stylesheet and the icon are linked with a ?v=<hash> of their own
# contents (site/build.py, stamp()), and the fonts never change under a
# given filename. All of it is safe to keep for a year and never check:
# a deploy that changes the stylesheet changes the url that asks for it.
# The only rule in this file that sets Cache-Control, for the reason at
# the top — a second one would concatenate rather than lose.
/static/*
Cache-Control: public, max-age=31536000, immutable