ENGINEERING NOTE · 2026
Our host changed our downloads. A SHA-256 check caught it.
We publish the SHA-256 of every version of our offline package, so a laboratory can check the file before it goes onto an isolated PC. The first time a user checked a browser download, it did not match. Nothing was wrong with our build. The file had been changed on the way.
Written by Taha Bayar, a biologist working on laboratory data handover.
What had changed
The downloaded file was 367 bytes longer than the published one. The difference was one line before the closing body tag: a script tag loading beacon.min.js from static.cloudflareinsights.com, Cloudflare's Web Analytics (real user measurement) beacon. We had never added it. On our free-plan zone, Cloudflare inserts it into HTML responses at the edge, and its dashboard showed the feature as enabled for our hostname although we had not switched it on.
Why our own check missed it
We had checked the live site with curl and seen no script. The edge adds it only to requests that look like a browser. With a browser user agent and Accept: text/html, every HTML page carried it, including the downloadable package; with plain curl, none did. Test what your users receive, with a real browser or browser-like headers:
curl -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/140.0" -H "Accept: text/html" https://example.com/ | grep cloudflareinsights
Why it mattered
- The download no longer matched its published hash, which is exactly what a hash check is for. A user who skipped the check would have installed a file that was not the one we tested.
- The file could connect to the internet. Opened from disk on a connected PC, the injected script loaded from Cloudflare. For software whose promise is that it contacts no service, that is a broken promise.
- Our pages were protected, the file was not. On the website, our Content Security Policy blocked the script from running. A file opened from disk has no server headers, so nothing blocked it.
What stopped it
Cache-Control: no-transformon every response. It tells intermediaries, Cloudflare included, not to modify the body. Since adding it, browser-like requests receive our files byte for byte. It lives in our repository, so a dashboard setting cannot undo it.- A Content Security Policy inside the file itself. The offline package carries its own policy that allows no outside script or connection. We tested it by injecting the same beacon into a copy: the request was blocked.
- The dashboard switch, as a second layer. In Cloudflare, the setting only appears after the site is added to Web Analytics; then Manage site → Disable.
- A release test that downloads like a user. After every deployment a headless browser downloads the package from the public page and compares its SHA-256 with the published value.
If you distribute files for validated systems
Publish the SHA-256, and check it the way your users will receive the file, not the way your build server sees it. You can check a file in your browser, without uploading it, with our SHA-256 checker. What changed and when is in our changelog.