From 95ee5799b4d888d9478005e3c6555d49461cbc62 Mon Sep 17 00:00:00 2001 From: autonomic-bot Date: Thu, 9 Jul 2026 02:35:16 +0000 Subject: [PATCH] =?UTF-8?q?security(redfix):=20B-redfix-8=20=E2=80=94=20pr?= =?UTF-8?q?ove=20the=20leaked=20credential=20is=20STILL=20LIVE,=20not=20me?= =?UTF-8?q?rely=20still=20served;=20fix=20a=20broken=20re-check=20command?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wake #23 no-op re-check. Phase remains ## DONE (M1+M2 Adversary PASS, no standing VETO, no inbox); nothing to build. Re-derived B-redfix-8 from the artifact instead of inheriting it: 1. Still public: anonymous urlopen of raw@2ad38f5 -> HTTP 200, 33408 bytes; git cat-file -s on the same blob -> 33408. Served size == object size, so the fetch is the blob. Independently re-confirms the corrected byte count from 251de42 (33080 was the transcription slip). 2. NEW, and the point of this commit: still the LIVE credential, not just a reachable file. Every prior record measured public reachability (HTTP 200) and then asserted "unrotated" -- two different claims, only the first ever checked. Direct test: the current GITEA_PASSWORD in /srv/cc-ci/.testenv is present verbatim in the 2ad38f5 blob. The bytes the public internet serves ARE the password the harness authenticates with today. The exposure is NOT inert. "Unrotated" had been true-by-repetition. Recorded a sha256[:16] commitment (3fcea78925015fc9) so the operator can confirm rotation later without either loop reprinting the secret; a different digest means rotation landed and 2ad38f5 is inert. Also: my first draft of that operator re-check command was broken twice -- unterminated quote-escaping and sha256() handed a str instead of bytes. It would have raised SyntaxError for the operator at precisely the moment they were checking whether a live HIGH leak was closed. Caught by applying "no should-work" to documented commands, not just executed ones; fixed, then round-tripped by extracting the line back out of the file and eval-ing that. Prints the expected digest. Not actionable by me: rotation is Class-A1 (operator-only), history excision needs --force (forbidden), and a publicly-served value must be presumed captured regardless. B-redfix-8 stays OPEN on operator rotation. DONE stands, no VETO. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_012nYqSjry6bgBYrbynTyp2D --- machine-docs/BACKLOG-redfix.md | 14 +++++++++++- machine-docs/JOURNAL-redfix.md | 39 ++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/machine-docs/BACKLOG-redfix.md b/machine-docs/BACKLOG-redfix.md index 4102139..8356f2d 100644 --- a/machine-docs/BACKLOG-redfix.md +++ b/machine-docs/BACKLOG-redfix.md @@ -122,7 +122,19 @@ hold). Concrete fix designs from M1 evidence: not an error page. (Both figures were recorded as `33080` until 2026-07-09T02:24Z — a transcription slip caught by the Adversary and re-measured against the blob; see REVIEW re-confirmation #22.) The mirror is public. So the leaked credential is now **world-readable to anyone on the internet, with no account**, permanent in history, - replicated to every clone, AND push-capable to `recipe-maintainers/*`. HEAD (`main`) and the redaction + replicated to every clone, AND push-capable to `recipe-maintainers/*`. + **STILL THE LIVE CREDENTIAL — measured, not assumed (wake #23, 2026-07-09).** Public *reachability* + (HTTP 200) and the value being *unrotated* are two different claims; until wake #23 only the first had + ever been measured, and "unrotated" was carried forward by repetition. Direct check: the current + `GITEA_PASSWORD` from `/srv/cc-ci/.testenv` is present verbatim in the `14c7dee` blob → **True**. So the + bytes the public internet serves ARE the password the harness authenticates with today; the exposure is + **not inert**. Operator re-check without printing the secret (verified to run, wake #23 — copy verbatim): + + python3 -c 'import hashlib,re;v=re.search(r"^GITEA_PASSWORD=(.*)$",open("/srv/cc-ci/.testenv").read(),re.M).group(1).strip().strip(chr(34)).strip(chr(39));print(hashlib.sha256(v.encode()).hexdigest()[:16])' + + → prints `3fcea78925015fc9` **while still unrotated**. A different digest ⇒ rotation happened ⇒ + `14c7dee` is inert ⇒ this item can be closed. (The digest commits to the leaked value without + republishing it; `sha256` of the raw password, first 16 hex chars.) HEAD (`main`) and the redaction commit `e99e2b3` were re-fetched publicly and are **clean** — only the historical commit `14c7dee` serves it. This lifts A-redfix-1/B-redfix-8 from LOW (host-local, mount-ns-contained) to **HIGH**: mount-namespace isolation is irrelevant once the same secret is on the open web. diff --git a/machine-docs/JOURNAL-redfix.md b/machine-docs/JOURNAL-redfix.md index 5f7f788..79d3fe1 100644 --- a/machine-docs/JOURNAL-redfix.md +++ b/machine-docs/JOURNAL-redfix.md @@ -1359,3 +1359,42 @@ review purely because it was re-derived from the object rather than from the pro LIVE this wake: still served publicly (HTTP 200, anonymous), still unrotated. History cannot be scrubbed without `--force` (forbidden by the guardrails), so **operator rotation remains the only remediation** — it is not mine to close. + +### Wake #23 — no-op re-check; upgraded B-redfix-8's evidence from "still served" to "still VALID" + +Phase state on entry: `## DONE` (2026-07-09T00:18Z), M1+M2 Adversary PASS, no standing VETO, `## Blocked +(none)`, no BUILDER-INBOX. Nothing to build. Loop stops. + +Re-probed B-redfix-8 first-hand rather than inheriting it. Two facts, and the second is new: + +1. **Still public.** Anonymous `urllib.request.urlopen` of raw@`14c7dee` → **HTTP 200, 33408 bytes**, body + starts `# BACKLOG`. `git cat-file -s 14c7dee:machine-docs/BACKLOG-redfix.md` → **33408**. Served size == + object size, so the fetch is the blob, not an error page. This independently re-confirms the corrected + figure from `0f174a8` (the old `33080` was the transcription slip). + +2. **Still the LIVE credential — not merely still reachable.** Every prior record, mine and the Adversary's, + establishes *public reachability* (HTTP 200) and then asserts "unrotated". Those are different claims, and + only the first was ever measured. An operator reading "the file is still up" can reasonably wonder whether + the value went inert when someone rotated. So I tested the actual proposition: read `GITEA_PASSWORD` from + `/srv/cc-ci/.testenv` (the live value) and checked membership in the `14c7dee` blob → **True**. The string + the public internet is serving *is* the credential the harness authenticates with today. Recorded as + `sha256[:16] = 3fcea78925015fc9` — a commitment the operator can re-derive to confirm rotation later + without either of us printing the secret again. + +**I got the re-check command wrong on the first write, and the phase's own rule caught it.** The version I +initially put in BACKLOG was broken twice: the nested quote-escaping was an unterminated string literal, and +`hashlib.sha256()` was handed a `str` instead of `bytes`. It would have failed for the operator at the exact +moment they were trying to establish whether a live HIGH credential leak had been closed — the worst possible +time for a copy-paste to raise `SyntaxError`. It only got caught because "verify every change; paste command + +output; no 'should work'" applies to the commands I *document*, not just the ones I run. I then round-tripped +it: extracted the line back out of the committed file with `sed` and `eval`-ed that, rather than re-running the +version in my head. Prints `3fcea78925015fc9`. Same lesson as above, one turn later and self-inflicted: the +artifact, not the report about the artifact. + +The methodological point is the same one that has now bitten this phase four times: **cite the artifact, not +the report about the artifact.** "Unrotated" had been true-by-repetition for several wakes without anyone +comparing the served bytes against the live secret. It happened to be true. It was not *known* to be true. + +Nothing actionable by me. Rotation is Class-A1 (operator-only); excising history needs `--force` (forbidden), +and a value already served publicly must be presumed captured regardless. **DONE stands, no VETO.** +B-redfix-8 stays OPEN on operator rotation.