Development record
ReadState (internal/core/implement/loop/state.go) does not check a lane's stored hand-back text in a run's state.json, and on the call that routes a hand-back the drain echoes that text onto abcd drain --json before drain.json is ever re-read, so a hand-written or repository-shipped state.json whose hand-back reason, home or question carries a control or bidi rune (U+202E, U+009B) puts it raw on the stream. The receipt path sanitizes these fields when the loop takes them, so only a forged file carries them. Found by the implementer of iss-2610121505153157.
ReadState (internal/core/implement/loop/state.go) does not check a lane's stored hand-back text in a run's state.json, and on the call that routes a hand-back the drain echoes that text onto abcd drain --json before drain.json is ever re-read, so a hand-written or repository-shipped state.json whose hand-back reason, home or question carries a control or bidi rune (U+202E, U+009B) puts it raw on the stream. The receipt path sanitizes these fields when the loop takes them, so only a forged file carries them. Found by the implementer of iss-2610121505153157.
Security scope (abcd-fixes-what-it-adds): the route does not exist without abcd. The reader, the text it builds and the --json stream that carries it are abcd's own, so abcd added it and fixes it, at the boundary the text enters by; the fix changes nothing about how the repository works.
Frontmatter
| id | iss-2610121516559163 |
|---|---|
| type | issue |
| lifecycle | resolved |
| severity | minor |
.abcd/work/issues/resolved/iss-2610121516559163-readstate-internal-core-implement-loop.md
open on GitHub ↗ · commit history ↗
mentions2
- iss-2610121505153157readDrain (internal/core/implement/loop/drain.go) accepts the free text a drain state stores in .abcd/.work.local/run/drain.json unchecked: each hand-back's reason, home, question, rule, draft and wrote fields and the judgements are copied into 'abcd drain --json' as stored (res.HandBacks = st.HandBacks), so a hand-written or repository-shipped drain.json can carry control or bidi runes (U+202E, U+009B) onto the JSON stream; the same display-spoofing class as iss-2610121206163414, which hardened the drain's stored pace. Found by the implementer of that fix.
- iss-2610121532247004A lane receipt's model and each resolution's note and grounds are stored on the lane unchecked and echoed raw on 'abcd implement record --json' and 'abcd implement status --json': verifyReceipt (internal/core/implement/loop/receipt.go) checks a receipt's run, lane, branch, commits, resolution issue, commit and impact, but takes rc.Model and each resolution's note and grounds as written, and readStateIn reads them back from state.json unchecked. A receipt an agent writes, or a hand-edited or repository-shipped state.json, can carry control or bidi runes (U+202E, U+009B) onto both streams. Found sweeping the loop package's on-disk readers after iss-2610121516559163.