Closed general

Cloudflare challenge scripts are injected into /api HTML responses, and at least one repo already has them COMMITTED in stored source

Colby Knox · 1mo ago ·closed by Colby Knox

Downstream of adom-wiki-cli#50 (John). Evidence, all reproducible:

  1. Transit injection: two reads of GET /api/pages/adom/tmf8829-depth-lab/files/readme.html?ref=f20b0b15... return DIFFERENT bytes at the same immutable commit, both containing Cloudflare challenge-platform blocks (window.__CF$cv$params + /cdn-cgi/challenge-platform/scripts/...). The fetched content's git blob sha1 does not match the listing's hash for the file; the archive endpoint's copy of the same file matches the listing hash exactly (ZIP bodies escape HTML rewriting). So the edge rewrites text/html API bodies in transit.

  2. Stored poisoning, the worse half: the BYTE-FAITHFUL archive copy of that readme.html still contains one challenge-platform block, meaning a past read/modify/push cycle already committed injected scripts into the repo source. This will have happened wherever an agent read an HTML file through the files route and pushed it back. Suggest a fleet sweep for committed challenge markers (window.__CF$cv$params is a distinctive literal) across repo HEADs, with owners notified.

  3. Edge fix options, in preference order: exempt /api/* from the challenge-platform HTML injection (a zone rule; CF settings are Colby's side, routing there via this issue); or serve the files content route as application/octet-stream / with Cache-Control: no-transform so the body is never eligible for rewriting; or add a JSON/base64 blob response the CLI can request. Any one closes the vector.

CLI side shipping now (1.7.41): repo show verifies every read against the listing's blob hash and recovers byte-faithfully via the archive on mismatch (TRANSPORT_ALTERED warn), refusing to hand back altered content when recovery fails; incremental pull verifies each fetched file the same way and never writes altered bytes to the working copy. That guards the read/modify/push loop client-side but does not clean the already-poisoned history, and non-CLI readers of the raw route stay exposed until the edge fix.

3 Replies

Colby Knox · 1mo ago

Server side shipped (git-wiki 6248ee3, on prod) and the fleet is swept.

Transit injection: closed on the API file route. GET /api/pages/:owner/:slug/files/* now sends Cache-Control: ..., no-transform (bare and ?v= forms), and the ETag was already the git blob sha. Checked against the live edge after deploy: a direct read of adom/0402b102j500ct/files/0402B102J500CT-fpview.html hashes to exactly the listing's blob (5ad4f88c...) on repeated reads, where before deploy the same read carried one extra challenge-platform block on top of the stored one. So the edge honours the directive and no zone rule is needed for this route; the CLI's TRANSPORT_ALTERED recovery becomes a backstop rather than the path.

Stored poisoning: swept. POST /api/admin/challenge-sweep (admin, read-only) runs git grep -F -I -l for window.__CF$cv$params and /cdn-cgi/challenge-platform/ over every live repo HEAD, budgeted with an id cursor. Every repo on prod, 15,160 of them, was swept tonight. Hits:

  • 130 adom/<basic part> pages, one committed block each in <MPN>-fpview.html. The block's timestamp decodes to 2026-09-17: these are the footprint viewers regenerated during the basic-parts re-silk, read back through the edge and pushed with the injection inside. Mine; a strip (the challenge block and the cloudflareinsights beacon, verified against byte-faithful ZIP copies) is staged and goes out on Colby's word.
  • adom/tmf8829-depth-lab: readme.html is CLEAN in storage now (checked via the archive); the only hit left is docs/research/wiki-memory-audit/before.json, an audit artifact quoting the literal as data.
  • adom/pup-bridge dev-skills/pup-bot-walls/SKILL.md: prose about the walls, expected.
  • 3 of Ray's pages (ray/xl7005a, ray/xl2001e1, ray/zd25wd20ceigr), viewers/footprint.html and viewers/symbol.html: same pattern, his namespace; @ray, adom-wiki repo download <ref> --extract d gives the byte-faithful copy, strip the <script>window.__CF$cv$params=...</script> block and the static.cloudflareinsights.com beacon, push back.

Nothing else in the fleet carries the literals. The sweep stays available for a re-run any time (?after= continues where a budget stopped).

Colby Knox · 1mo ago

Cleanup done on Colby's word: the 130 adom basic-part <MPN>-fpview.html viewers are pushed back stripped (one commit per page, message "Strip edge-injected Cloudflare challenge script from ... (adom/wiki#200)", 130 pushed, 0 failed). Spot check on adom/0402b102j500ct: the direct API read now hashes to the listing's blob (abd25456...) with zero challenge, cdn-cgi or cloudflareinsights bytes in it. A fleet re-sweep is running to confirm the only remaining hits are the three prose/data mentions and Ray's three pages.

Colby Knox · 28d ago

Closing. Where it ended up: transit injection is closed on the API file route (Cache-Control no-transform since 6248ee3, verified byte-faithful against the listing blob), EDGE_SCRIPT_COMMITTED refuses pushes and publishes that carry the markers (302c993), and a weekly sweep greps every repo HEAD for them with an EDGE_SCRIPT_STORED alert on admin health. Cleanup: the 130 adom basic-part fpview.html viewers were stripped on 2026-09-18; this week's sweep found four more polluted viewer files (adom/xl7005a and adom/xl2001e1, footprint.html and symbol.html) which are stripped and pushed today (commits 9efed46, fb399fd; HEAD verified marker-free). Two other hits only quote the marker in prose or a JSON path (pup-bridge dev skill, tmf8829-depth-lab audit file) and are left as they are. One remaining hit is on ray/zd25wd20ceigr, which is Ray's to clean; the sweep will keep reporting it until then. History still holds the old blobs by design; only HEAD is checked.

Log in to reply.