fix(mcp): normalize CRLF before frontmatter fence detection
Round-4 review found a fifth bypass, and this one needs no adversarial
old_str/new_str crafting at all: frontmatterBlock's fence detection matches
the literal byte sequence "---\n". A note whose fence lines use CRLF
("---\r\n") fails strings.HasPrefix(doc, "---\n") on the precondition read
purely from line-ending encoding — hadFence is false, so the round-3/round-4
checks can never fire, frontmatterScalars falls back to an empty map, and
claim.ValidateEnvelope({}) is nil by design. An invalid claim_provenance
value lands with zero error.
Zero CRLF-fenced notes exist in the live corpus today, but nothing in the
code prevented one, and this class of encoding-dependent false negative
could resurface in any of the other fence-based checks. Normalize once
inside frontmatterBlock so every caller (fence-presence detection and
frontmatterScalars) agrees regardless of line ending.
The broader structural concern — three independent, subtly inconsistent
fence-parsing implementations across internal/mcp, internal/api, and
internal/frontmatter, of which this CRLF gap is a direct symptom — is out
of scope for this PR and filed separately as hyperguild#138.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -310,6 +310,13 @@ func checkClaimEnvelope(brainDir, path, oldStr, newStr string) error {
|
||||
// frontmatterBlock returns the raw text between doc's opening and closing
|
||||
// `---` fences, or ok=false if doc has no (properly closed) fence.
|
||||
func frontmatterBlock(doc string) (block string, ok bool) {
|
||||
// Round 4 found a note with CRLF fence lines ("---\r\n") silently
|
||||
// defeats HasPrefix(doc, "---\n") on the precondition read — not an
|
||||
// adversarial old_str/new_str, just an encoding difference — which
|
||||
// makes checkClaimEnvelope no-op entirely. Normalize once, here, so
|
||||
// every caller (hadFence/hasFence detection and frontmatterScalars)
|
||||
// agrees regardless of line ending.
|
||||
doc = strings.ReplaceAll(doc, "\r\n", "\n")
|
||||
if !strings.HasPrefix(doc, "---\n") {
|
||||
return "", false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user