fix(download): enforce integrity check using db metadata

Signed-off-by: skidoodle <contact@albert.lol>
This commit is contained in:
2026-01-18 21:54:08 +01:00
parent a69e5a52a3
commit e18be18029
+31 -1
View File
@@ -2,6 +2,7 @@ package app
import ( import (
"encoding/base64" "encoding/base64"
"encoding/json"
"fmt" "fmt"
"mime" "mime"
"net/http" "net/http"
@@ -9,6 +10,7 @@ import (
"path/filepath" "path/filepath"
"github.com/skidoodle/safebin/internal/crypto" "github.com/skidoodle/safebin/internal/crypto"
"go.etcd.io/bbolt"
) )
func (app *App) HandleGetFile(writer http.ResponseWriter, request *http.Request) { func (app *App) HandleGetFile(writer http.ResponseWriter, request *http.Request) {
@@ -28,14 +30,42 @@ func (app *App) HandleGetFile(writer http.ResponseWriter, request *http.Request)
} }
id := crypto.GetID(key, ext) id := crypto.GetID(key, ext)
path := filepath.Join(app.Conf.StorageDir, id)
var meta FileMeta
err = app.DB.View(func(tx *bbolt.Tx) error {
b := tx.Bucket([]byte(DBBucketName))
if b == nil {
return fmt.Errorf("bucket not found")
}
data := b.Get([]byte(id))
if data == nil {
return fmt.Errorf("file not found")
}
return json.Unmarshal(data, &meta)
})
if err != nil {
app.SendError(writer, request, http.StatusNotFound)
return
}
path := filepath.Join(app.Conf.StorageDir, id)
info, err := os.Stat(path) info, err := os.Stat(path)
if err != nil { if err != nil {
app.SendError(writer, request, http.StatusNotFound) app.SendError(writer, request, http.StatusNotFound)
return return
} }
if info.Size() != meta.Size {
app.Logger.Error("Integrity check failed: disk size mismatch",
"id", id,
"disk_bytes", info.Size(),
"expected_bytes", meta.Size,
)
app.SendError(writer, request, http.StatusInternalServerError)
return
}
file, err := os.Open(path) file, err := os.Open(path)
if err != nil { if err != nil {