Files
felhom.eu/documentation/audits/SPIKE-cc-creds-2026-10-17/probes/sweep.py
T
adminandClaude Opus 5.5 b9c4f73bfa
gates / gates (push) Failing after 6m36s
SPIKE cc-creds: secret broker + CC transcript guards measured with canaries (R-1118..R-1122, 168 -> 173)
Mask PASS, PreToolUse refuse PASS, PostToolUse replace PARTIAL (crash and
large-output disk leaks, both with a measured fix), SOPS+age store PARTIAL
(private repo could not be created), transcript sweep PASS. Fake secrets
only; ~/.config/credentials not read; no CC settings changed. Files use
"creds": .gitignore *secret* ignores the brief's names. STATUS D10: the
store choice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
2026-10-17 11:57:24 +02:00

38 lines
1.6 KiB
Python

#!/usr/bin/env python3
"""SPIKE probe — transcript sweep. Searches ROOT/**/*.jsonl (and tool-results/*.txt) for each value
and its encodings (mask.forms, plus the JSON-escaped form as it sits inside a JSONL string).
Prints NAMES and FILE COUNTS only — never a value, never a matching line.
sweep.py ROOT NAME=FILE [NAME=FILE ...] [--list] (--list also prints matching file paths)"""
import glob, os, re, sys, time, json
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import mask
root, args = sys.argv[1], [a for a in sys.argv[2:] if not a.startswith("--")]
show = "--list" in sys.argv
secrets = []
for a in args:
n, p = a.split("=", 1)
secrets.append((n, open(p).read().rstrip("\n")))
pats = {}
for n, v in secrets:
fs = set(mask.forms(v)) | {json.dumps(json.dumps(v)[1:-1])[1:-1].encode()} # double-escaped (JSON in JSON)
pats[n] = re.compile(b"|".join(re.escape(f) for f in sorted(fs, key=len, reverse=True)))
files = sorted(set(glob.glob(os.path.join(root, "**", "*.jsonl"), recursive=True)) |
set(glob.glob(os.path.join(root, "**", "tool-results", "*"), recursive=True)))
t0 = time.time(); total = 0; hits = {n: [] for n, _ in secrets}
for f in files:
try:
data = open(f, "rb").read()
except OSError:
continue
total += len(data)
for n, rx in pats.items():
if rx.search(data):
hits[n].append(f)
dt = time.time() - t0
print("searched %d files, %.1f MB, %.2f s" % (len(files), total / 1e6, dt))
for n, _ in secrets:
print("%-10s files=%d" % (n, len(hits[n])))
if show:
for f in hits[n]:
print(" " + f)