Validate blob hashes, offsets and lengths from the destination (closes #155)
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 have a decrypted blob written outside the cache directory, or feed a short or negative value that panicked a command. blobDiskCache.path now refuses any key with a path separator, and ReadAt rejects a negative offset or length, bounding so a sum cannot overflow past the check. A new isBlobHash helper gates FetchBlob, shallow and deep verify, and restore: buildBlobIndexes rejects every hash from the snapshot database before any fetch. The blobs/ and metadata/ listings skip a non-conforming name, and short-hash prefixes in log and error text go through a panic-safe shortHash helper. Model: opus-4-8
This commit was merged in pull request #195.
This commit is contained in:
@@ -247,9 +247,22 @@ func (v *Vaultik) listAllRemoteBlobs() (map[string]int64, error) {
|
||||
}
|
||||
|
||||
parts := strings.Split(object.Key, "/")
|
||||
if len(parts) == blobKeyParts && parts[0] == "blobs" {
|
||||
allBlobs[parts[3]] = object.Size
|
||||
if len(parts) != blobKeyParts || parts[0] != "blobs" {
|
||||
continue
|
||||
}
|
||||
|
||||
// The object name is read from the destination store and is not
|
||||
// trusted. A name that is not a blob hash (e.g. a short or
|
||||
// non-hex string) would panic the later hash[:2]/hash[2:4] path
|
||||
// build, so skip it with a warning rather than delete it.
|
||||
if !isBlobHash(parts[3]) {
|
||||
log.Warn("Skipping non-conforming object under blobs/",
|
||||
"key", object.Key)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
allBlobs[parts[3]] = object.Size
|
||||
}
|
||||
|
||||
log.Info("Found blobs in storage", "count", len(allBlobs))
|
||||
|
||||
Reference in New Issue
Block a user