verify --deep hashes encrypted bytes but compares to the plaintext blob ID, so it fails on healthy snapshots #131

Closed
opened 2026-09-21 09:44:04 +02:00 by clawbot · 1 comment
Collaborator

Found while adding fault-injection tests for #72.

A blob's hash — its remote filename — is the double SHA256 of the plaintext (internal/blobgen/writer.go, Sum256). Deep verification's final integrity step (internal/vaultik/verify.go, verifyBlobFinalIntegrity) instead hashes the encrypted downloaded bytes with a single SHA256 and compares that to the blob hash. The two can never be equal, so verify --deep fails on every valid blob with blob hash mismatch.

The per-chunk hash checks in the same path are correct; only the final blob-hash comparison is wrong.

Effect: deep verification is unusable — it reports healthy backups as corrupt. The blob-existence stage that runs earlier is unaffected, so a genuinely missing blob is still caught.

Reproduction: internal/vaultik/fault_injection_test.go, TestFaultInjection_DeepVerifyAcceptsHealthySnapshot (skipped, points to this issue).

Model: opus-4-8

Found while adding fault-injection tests for https://git.eeqj.de/sneak/vaultik/issues/72. A blob's hash — its remote filename — is the double SHA256 of the plaintext (`internal/blobgen/writer.go`, `Sum256`). Deep verification's final integrity step (`internal/vaultik/verify.go`, `verifyBlobFinalIntegrity`) instead hashes the encrypted downloaded bytes with a single SHA256 and compares that to the blob hash. The two can never be equal, so `verify --deep` fails on every valid blob with `blob hash mismatch`. The per-chunk hash checks in the same path are correct; only the final blob-hash comparison is wrong. Effect: deep verification is unusable — it reports healthy backups as corrupt. The blob-existence stage that runs earlier is unaffected, so a genuinely missing blob is still caught. Reproduction: `internal/vaultik/fault_injection_test.go`, `TestFaultInjection_DeepVerifyAcceptsHealthySnapshot` (skipped, points to this issue). Model: opus-4-8
clawbot added this to the 1.0.0 milestone 2026-09-21 09:47:34 +02:00
Author
Collaborator

Fixed in #138 (base next). Deep verification now hashes the decompressed plaintext and compares its double SHA256 to the blob name, instead of single-hashing the encrypted bytes. Added a test that backs up a real snapshot, deep-verifies it (fails before the fix), then flips a byte in one stored blob and confirms deep verification then fails.

Model: opus-4-8

Fixed in https://git.eeqj.de/sneak/vaultik/pulls/138 (base `next`). Deep verification now hashes the decompressed plaintext and compares its double SHA256 to the blob name, instead of single-hashing the encrypted bytes. Added a test that backs up a real snapshot, deep-verifies it (fails before the fix), then flips a byte in one stored blob and confirms deep verification then fails. Model: opus-4-8
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/vaultik#131