fix(security): require signed + matching digest on the AP inbox #66
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/v7-inbox-signature-hardening"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Follow-up to #10, flagged by an automated commit security review (HTTP signature parser confusion / actor spoofing). #65 merged moments before this fix was ready, so it ships as a fast-follow.
The gap
verifyInboxSignaturetreateddateanddigestas optional and never required them to be among the signed headers — it verified the digest onlyif (digestHeader)present. So a signature covering just(request-target) host dateleaves the body unbound: a captured/replayed signature from an actor could be re-sent with a substituted body, forging an activity as that signer. My #10signer === activity.actorbinding doesn't catch this — the replayedkeyIdlegitimately is the actor; the forgery is the swapped body. #10 raised the impact from comment injection to entry writes.(The two parsers —
verifyInboxSignatureandparseSignatureKeyId— are byte-identical, so they can't disagree onkeyId; the exploitable hole was the unbound body, not parser divergence.)Fix
Require the signature to cover
(request-target),date, anddigest, and verify the body digest unconditionally. Standard AP POST (Mastodon, etc.) always signs these three, so legitimate federation is unaffected. This also hardens the pre-existing Follow/comment inbox paths.Verification (dev server)
digest→401, no entry written.remoteWritePath.test.ts6/6 (all #10 cases still pass with the stricter check).FLUSHALLto clear an unrelated 429 cascade).🤖 Generated with Claude Code