From 35dbca86f1fcfa94faf5954c16af494c0ea23599 Mon Sep 17 00:00:00 2001 From: Ole-Martin Bratteng <1681525+omBratteng@users.noreply.github.com> Date: Thu, 17 Mar 2022 17:29:15 +0100 Subject: [PATCH] Fix leakage of info when no azure blob is found (#664) * Create `isAzureError` function * Throw 404 is info file is not found * Use `isAzureError` in GetOffset function * Make `GetUpload` match others without named returns * Follow code style for `isAzureError` not returning but setting `err` to value * Return not found when the blob is not found This will also be triggered when the blob is being uploaded but not yet committed * Return not found if blob is not found when getting offset * Don't return error in GetUpload if GetOffset returns `handler.ErrNotFound` --- pkg/azurestore/azureservice.go | 21 ++++++++++++++++++--- pkg/azurestore/azurestore.go | 4 ++-- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/pkg/azurestore/azureservice.go b/pkg/azurestore/azureservice.go index 1bfb8bd..9f27a30 100644 --- a/pkg/azurestore/azureservice.go +++ b/pkg/azurestore/azureservice.go @@ -26,6 +26,7 @@ import ( "strings" "github.com/Azure/azure-storage-blob-go/azblob" + "github.com/tus/tusd/pkg/handler" ) const ( @@ -175,9 +176,13 @@ func (blockBlob *BlockBlob) Download(ctx context.Context) (data []byte, err erro // If the file does not exist, it will not return an error, but a 404 status and body if downloadResponse != nil && downloadResponse.StatusCode() == 404 { - return nil, fmt.Errorf("File %s does not exist", blockBlob.Blob.ToBlockBlobURL()) + return nil, handler.ErrNotFound } if err != nil { + // This might occur when the blob is being uploaded, but a block list has not been committed yet + if isAzureError(err, "BlobNotFound") { + err = handler.ErrNotFound + } return nil, err } @@ -200,8 +205,8 @@ func (blockBlob *BlockBlob) GetOffset(ctx context.Context) (int64, error) { getBlock, err := blockBlob.Blob.GetBlockList(ctx, azblob.BlockListAll, azblob.LeaseAccessConditions{}) if err != nil { - if err.(azblob.StorageError).ServiceCode() == azblob.ServiceCodeBlobNotFound { - return 0, nil + if isAzureError(err, "BlobNotFound") { + err = handler.ErrNotFound } return 0, err @@ -261,6 +266,9 @@ func (infoBlob *InfoBlob) Download(ctx context.Context) ([]byte, error) { return nil, fmt.Errorf("File %s does not exist", infoBlob.Blob.ToBlockBlobURL()) } if err != nil { + if isAzureError(err, "BlobNotFound") { + err = handler.ErrNotFound + } return nil, err } @@ -308,3 +316,10 @@ func blockIDBase64ToInt(blockID string) int { blockIDBase64ToBinary(blockID) return int(binary.LittleEndian.Uint32(blockIDBase64ToBinary(blockID))) } + +func isAzureError(err error, code string) bool { + if err, ok := err.(azblob.StorageError); ok && string(err.ServiceCode()) == code { + return true + } + return false +} diff --git a/pkg/azurestore/azurestore.go b/pkg/azurestore/azurestore.go index 8447e74..a63d959 100644 --- a/pkg/azurestore/azurestore.go +++ b/pkg/azurestore/azurestore.go @@ -83,7 +83,7 @@ func (store AzureStore) NewUpload(ctx context.Context, info handler.FileInfo) (h return azUpload, nil } -func (store AzureStore) GetUpload(ctx context.Context, id string) (handle handler.Upload, err error) { +func (store AzureStore) GetUpload(ctx context.Context, id string) (handler.Upload, error) { info := handler.FileInfo{} infoFile := store.keyWithPrefix(store.infoPath(id)) infoBlob, err := store.Service.NewBlob(ctx, infoFile) @@ -112,7 +112,7 @@ func (store AzureStore) GetUpload(ctx context.Context, id string) (handle handle } offset, err := blockBlob.GetOffset(ctx) - if err != nil { + if err != nil && err != handler.ErrNotFound { return nil, err }