Enforce and document exact-match-only for signature verification #40
Reference in New Issue
Block a user
Delete Branch "fix/signature-exact-match-only"
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?
Closes #27
Signatures are per-URL only — this PR adds explicit tests and documentation enforcing that HMAC-SHA256 signatures verify against exact URLs only. No suffix matching, wildcard matching, or partial matching is supported.
What this does NOT touch
The host whitelist code (
whitelist.go) is not modified. This PR is exclusively about signature verification, per sneak's instructions on issue #27, PR #32, and PR #35.Changes
internal/imgcache/signature.goVerify()andbuildSignatureData()explicitly specifying that signatures are exact-match only — no suffix, wildcard, or partial matchinginternal/imgcache/signature_test.goTestSigner_Verify_ExactMatchOnly: 14 tamper cases verifying that modifying any signed component (host, path, query, dimensions, format) causes verification to fail. Host-specific cases include:example.com) does not match subdomain signature (cdn.example.com)images.example.com) does not matchimages.cdn.example.com) does not matchcdn.example.com.evil.com) does not matchevilcdn.example.com) does not matchTestSigner_Sign_ExactHostInData: Verifies that suffix-related hosts (cdn.example.com,example.com,images.example.com, etc.) all produce distinct signaturesinternal/imgcache/service_test.goTestService_ValidateRequest_SignatureExactHostMatch: Integration test throughValidateRequestverifying that a valid signature forcdn.example.comis rejected when presented with a different host (parent domain, sibling subdomain, deeper subdomain, evil suffix, prefixed host)README.mdReview: PR #40 — Enforce and document exact-match-only for signature verification
Critical Context Check (re: PR #32, PR #35)
whitelist.goNOT modifiedsignature.go,signature_test.go,service_test.go,README.md.golangci.ymluntouchedWas HMAC already exact-match?
Yes — verified. The existing
buildSignatureData()onmainusesreq.SourceHostverbatim infmt.Sprintf("%s:%s:%s:%d:%d:%s:%d", ...). TheVerify()method recomputesSign(req)with the incoming request's fields and doeshmac.Equal(). HMAC-SHA256 is inherently exact-match — any change to any component produces a completely different hash. There was never any suffix/wildcard/partial matching in the signature code. The worker's claim is correct.What the PR adds
Verify()andbuildSignatureData()explicitly stating exact-match semanticsTestSigner_Verify_ExactMatchOnly) covering host variants (parent domain, sibling subdomain, deeper subdomain, evil suffix, prefixed host), path variants, query variants, dimension and format changesTestSigner_Sign_ExactHostInData) proving suffix-related hosts produce different signaturesTestService_ValidateRequest_SignatureExactHostMatch) throughValidateRequestverifying host-mismatch rejectionPolicy Compliance
.golangci.ymlunmodifiedtestingpackagemake checkpasses (viadocker build)Build Result
docker build .— PASS ✅All tests pass including the new exact-match tests. Lint and fmt checks pass. Binary builds successfully.
Verdict: PASS ✅
This is a clean, well-scoped PR. It correctly identifies that HMAC was already exact-match by nature and adds comprehensive documentation and tests to make that guarantee explicit and regression-proof. No whitelist code was touched. Closes issue #27.