Validate blob hashes, offsets and lengths from the destination (closes #155)
check / check (pull_request) Successful in 1m23s
check / check (pull_request) Successful in 1m23s
A blob hash read back from the downloaded snapshot database or the store
listing was trusted unchecked. A hostile remote could set a hash such as
"aa/../../etc" and make a decrypted blob be written outside the cache
directory, or feed a short or negative value that panicked a command.
blobDiskCache.path now refuses any key containing a path separator, and
ReadAt rejects a negative offset or length, bounding with
length > size-offset so a sum cannot overflow past the check. A new
isBlobHash helper (a plain function, not a method, since the packer stores
temp-placeholder-{uuid} as a hash) gates FetchBlob, shallow and deep
verify; the blobs/ and metadata/ listings skip a non-conforming name with
a warning; and short-hash prefixes in log and error text go through a
shortHash helper that cannot panic. verify's chunk reader rejects a
negative blob_chunks length and streams the chunk rather than allocating a
database-supplied size.
restore.go and internal/database are left untouched to avoid colliding
with the in-flight issue #156 work; the cache-path and FetchBlob guards
already stop the unsafe write and fetch.
Model: opus-4-8
This commit is contained in:
@@ -25,6 +25,29 @@ release" is exactly the contradiction
|
||||
|
||||
# Completed Steps
|
||||
|
||||
- 2026-09-22: Validated blob hashes, offsets and lengths read back from
|
||||
the destination before using them
|
||||
([issue #155](https://git.eeqj.de/sneak/vaultik/issues/155)). A blob
|
||||
hash taken from the downloaded database or the store listing was
|
||||
trusted unchecked, so a hostile remote could drive a decrypted blob to
|
||||
be written outside the cache directory (a hash like `aa/../../etc`) or
|
||||
crash a command with a short or negative value. `blobDiskCache.path`
|
||||
now refuses any key containing a path separator, and `ReadAt` rejects a
|
||||
negative offset or length and bounds with `length > size-offset` so a
|
||||
sum cannot overflow past the check. A new `isBlobHash` helper (a plain
|
||||
function, not a method — the packer stores `temp-placeholder-{uuid}` as
|
||||
a hash) gates `FetchBlob`, shallow and deep verify; the `blobs/` and
|
||||
`metadata/` listings skip a non-conforming name with a warning; and
|
||||
short-hash prefixes in log and error text go through a `shortHash`
|
||||
helper that cannot panic. `verify`'s chunk reader also rejects a
|
||||
negative `blob_chunks` length and streams the chunk instead of
|
||||
allocating a database-supplied size. `restore.go` and
|
||||
`internal/database` were left untouched to avoid colliding with the
|
||||
in-flight [issue #156](https://git.eeqj.de/sneak/vaultik/issues/156)
|
||||
work; the cache-path and `FetchBlob` guards already stop the unsafe
|
||||
write and fetch, so restore's own `buildBlobIndexes` early check is
|
||||
deferred as fail-fast defense in depth.
|
||||
|
||||
- 2026-09-21: Stopped an interrupted blob upload from making a later
|
||||
backup deduplicate against data that was never stored
|
||||
([issue #148](https://git.eeqj.de/sneak/vaultik/issues/148)). The
|
||||
|
||||
Reference in New Issue
Block a user