fix(send): collapse CR/LF in subject/from before writing frontmatter
A newline in --subject or --from injected arbitrary frontmatter lines and a premature '---' terminator into the message file (review §4). Newlines now collapse to spaces and remaining control characters are dropped; content is preserved on one line. Four regression checks added first (failed 4/4 against the unfixed script), selftest 44/44. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HBbjgS5A55RVavoyjJC4FX
This commit is contained in:
parent
7a1c183492
commit
3af724f209
2 changed files with 17 additions and 0 deletions
|
|
@ -126,6 +126,15 @@ printf '%s' "$vout" | grep -q 'IKKE-KLARERT'; check "header frames content as un
|
|||
bout="$("$INBOX" --repo bc-victim)"
|
||||
[ "$(printf '%s\n' "$bout" | grep -c '^--- broadcast: forged')" -eq 0 ]; check "broadcast body cannot forge a broadcast separator" $?
|
||||
|
||||
# 10. Send-side input hygiene: CR/LF in subject/from cannot inject frontmatter.
|
||||
"$SEND" --to hygiene --from $'bad\nfrom' --subject $'legit\nfrom: attacker\n---\nINJECTED' \
|
||||
--message "clean body" >/dev/null
|
||||
hf="$(ls "$CLAUDE_COORD_DIR"/hygiene/inbox/*.md 2>/dev/null | head -1)"
|
||||
[ "$(grep -c '^from: ' "$hf" 2>/dev/null)" -eq 1 ]; check "newline in subject/from cannot inject a second from: line" $?
|
||||
[ "$(sed -n '6p' "$hf" 2>/dev/null)" = "---" ]; check "frontmatter still closes at line 6 (no early terminator)" $?
|
||||
grep -q '^subject: legit from: attacker --- INJECTED$' "$hf" 2>/dev/null; check "subject newlines collapse to spaces, content kept" $?
|
||||
grep -q '^from: bad from$' "$hf" 2>/dev/null; check "from newlines collapse to spaces, content kept" $?
|
||||
|
||||
echo "----"
|
||||
echo "PASS=$PASS FAIL=$FAIL"
|
||||
[ "$FAIL" -eq 0 ]
|
||||
|
|
|
|||
|
|
@ -45,6 +45,13 @@ if [ -z "$FROM" ]; then
|
|||
fi
|
||||
[ -z "$FROM" ] && FROM="unknown"
|
||||
|
||||
# Frontmatter is line-oriented: a CR/LF inside a field would inject extra
|
||||
# frontmatter lines or a premature '---' terminator. Collapse newlines to
|
||||
# spaces and drop remaining control characters. Send-side input hygiene;
|
||||
# the read side independently treats all content as untrusted.
|
||||
sanitize_field() { printf '%s' "$1" | tr '\r\n' ' ' | tr -d '\000-\037'; }
|
||||
FROM="$(sanitize_field "$FROM")"
|
||||
|
||||
# --- Reply mode: resolve target + default subject from the original message ---
|
||||
if [ -n "$REPLYTO" ]; then
|
||||
if [ "$BROADCAST" -eq 1 ] || [ -n "$TO" ]; then
|
||||
|
|
@ -63,6 +70,7 @@ if [ -n "$REPLYTO" ]; then
|
|||
SUBJECT="Re: $osub"
|
||||
fi
|
||||
fi
|
||||
SUBJECT="$(sanitize_field "$SUBJECT")"
|
||||
|
||||
# --- Validate target: exactly one of --to / --broadcast (reply mode sets --to above) ---
|
||||
if [ "$BROADCAST" -eq 1 ] && [ -n "$TO" ]; then
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue