chore: implement Phase 1 and 2 security remediations
Some checks failed
Automated Container Build / build-and-push (push) Has been cancelled
Some checks failed
Automated Container Build / build-and-push (push) Has been cancelled
This commit is contained in:
parent
82731e93b1
commit
701766b611
14 changed files with 213 additions and 55 deletions
|
|
@ -3,6 +3,7 @@ package handlers
|
|||
import (
|
||||
"archive/zip"
|
||||
"bufio"
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
|
@ -293,12 +294,22 @@ func (h *FSHandler) GetExtendedFileInfo(c *fiber.Ctx) error {
|
|||
// For files, attempt to get media metadata
|
||||
cat := categorizeFile(filepath.Ext(info.Name()))
|
||||
if cat == "images" || cat == "videos" || cat == "audio" {
|
||||
cmd := exec.Command("exiftool", "-json", "--", resolvedPath)
|
||||
output, err := cmd.Output()
|
||||
if err == nil {
|
||||
var meta []map[string]interface{}
|
||||
if err := json.Unmarshal(output, &meta); err == nil && len(meta) > 0 {
|
||||
fi.Metadata = meta[0]
|
||||
ext := strings.ToLower(filepath.Ext(info.Name()))
|
||||
validExts := map[string]bool{
|
||||
".jpg": true, ".jpeg": true, ".png": true, ".gif": true, ".webp": true,
|
||||
".mp4": true, ".mov": true, ".webm": true, ".mkv": true,
|
||||
".mp3": true, ".wav": true, ".flac": true, ".m4a": true,
|
||||
}
|
||||
if validExts[ext] {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
cmd := exec.CommandContext(ctx, "exiftool", "-json", "--", resolvedPath)
|
||||
output, err := cmd.Output()
|
||||
if err == nil {
|
||||
var meta []map[string]interface{}
|
||||
if err := json.Unmarshal(output, &meta); err == nil && len(meta) > 0 {
|
||||
fi.Metadata = meta[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -548,9 +559,9 @@ func (h *FSHandler) Delete(c *fiber.Ctx) error {
|
|||
}
|
||||
|
||||
// Remove both potential locations to be safe
|
||||
os.RemoveAll(resolvedPath)
|
||||
safeRemovePath(h.Config.StorageDir, resolvedPath)
|
||||
if relativePath != "." {
|
||||
os.RemoveAll(trashPath)
|
||||
safeRemovePath(h.Config.TrashDir, trashPath)
|
||||
}
|
||||
|
||||
cleanPath := filepath.ToSlash(relativePath)
|
||||
|
|
@ -584,7 +595,7 @@ func (h *FSHandler) Delete(c *fiber.Ctx) error {
|
|||
if err := copyFile(resolvedPath, trashPath); err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "failed to move to trash"})
|
||||
}
|
||||
os.RemoveAll(resolvedPath)
|
||||
safeRemovePath(h.Config.StorageDir, resolvedPath)
|
||||
}
|
||||
|
||||
// Update DB
|
||||
|
|
@ -691,7 +702,7 @@ func (h *FSHandler) RestoreFromTrash(c *fiber.Ctx) error {
|
|||
if err := copyFile(trashPath, destFull); err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "failed to restore file"})
|
||||
}
|
||||
os.RemoveAll(trashPath)
|
||||
safeRemovePath(h.Config.TrashDir, trashPath)
|
||||
}
|
||||
|
||||
h.DB.Exec("UPDATE files SET path = ?, name = ?, is_trashed = 0, trashed_at = NULL WHERE path = ?", originalPath, filepath.Base(originalPath), body.Path)
|
||||
|
|
@ -715,10 +726,15 @@ func (h *FSHandler) RestoreFromTrash(c *fiber.Ctx) error {
|
|||
// EmptyTrash permanently deletes all trashed items.
|
||||
// DELETE /api/trash
|
||||
func (h *FSHandler) EmptyTrash(c *fiber.Ctx) error {
|
||||
if err := os.RemoveAll(h.Config.TrashDir); err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "failed to empty trash"})
|
||||
if err := safeRemovePath(h.Config.TrashDir, h.Config.TrashDir); err != nil {
|
||||
// safeRemovePath blocks deleting the root directory, so we just clear its contents instead
|
||||
entries, err := os.ReadDir(h.Config.TrashDir)
|
||||
if err == nil {
|
||||
for _, e := range entries {
|
||||
os.RemoveAll(filepath.Join(h.Config.TrashDir, e.Name()))
|
||||
}
|
||||
}
|
||||
}
|
||||
os.MkdirAll(h.Config.TrashDir, 0755)
|
||||
|
||||
h.DB.Exec("DELETE FROM files WHERE is_trashed = 1")
|
||||
h.DB.AddAuditLog("emptied_trash", "User emptied trash", c.IP())
|
||||
|
|
|
|||
Reference in a new issue