fix: critical security vulnerabilities
- Fix type assertion panics in auth.go (9 handlers)
* GetProfile, UpdateProfile, UpdateTheme, UpdateUsername
* UpdateEmail, UpdatePassword, DeleteAccount
* UpdateScanSettings, GetScanSettings, Register admin check
* Replace c.Get("user_id").(string) with MustGetAuthenticatedUser()
- Fix type assertion panic in library.go
* GetUserVisibleLibraries now uses MustGetAuthenticatedUser()
- Add path traversal protection to AddLibraryFolder
* Detect and block ".." in paths
* Clean paths with filepath.Clean()
* Verify path is a directory before adding
- Remove debug logging from Login handler
* Removed all fmt.Printf statements
* No more plaintext password logging
- Create safe context helper functions
* internal/handlers/context.go added
* GetAuthenticatedUser() for safe retrieval
* MustGetAuthenticatedUser() for post-auth middleware
Security: Critical
Tests: All 62 integration tests pass
Breaking: None - backward compatible
This commit is contained in:
@@ -5,6 +5,8 @@ import (
|
||||
"bookmann/internal/services"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
@@ -107,13 +109,9 @@ func (h *LibraryHandler) ListLibraries(c echo.Context) error {
|
||||
|
||||
// GetUserVisibleLibraries retrieves libraries visible to the current user
|
||||
func (h *LibraryHandler) GetUserVisibleLibraries(c echo.Context) error {
|
||||
userID := c.Get("user_id").(string)
|
||||
userUUID, err := uuid.Parse(userID)
|
||||
if err != nil {
|
||||
return c.JSON(http.StatusBadRequest, map[string]string{"error": "invalid user id"})
|
||||
}
|
||||
user := MustGetAuthenticatedUser(c)
|
||||
|
||||
libraries, err := h.libraryService.GetUserVisibleLibraries(c.Request().Context(), pgtype.UUID{Bytes: userUUID, Valid: true})
|
||||
libraries, err := h.libraryService.GetUserVisibleLibraries(c.Request().Context(), user.ID)
|
||||
if err != nil {
|
||||
return c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
|
||||
}
|
||||
@@ -179,8 +177,16 @@ func (h *LibraryHandler) AddLibraryFolder(c echo.Context) error {
|
||||
return c.JSON(http.StatusBadRequest, map[string]string{"error": err.Error()})
|
||||
}
|
||||
|
||||
// Path traversal protection - detect and block .. in path
|
||||
if strings.Contains(req.FolderPath, "..") {
|
||||
return c.JSON(http.StatusBadRequest, map[string]string{"error": "path traversal not allowed"})
|
||||
}
|
||||
|
||||
// Clean the path to remove any redundant separators or . references
|
||||
cleanPath := filepath.Clean(req.FolderPath)
|
||||
|
||||
// Validate that folder path exists and is accessible
|
||||
_, err = os.Stat(req.FolderPath)
|
||||
fileInfo, err := os.Stat(cleanPath)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return c.JSON(http.StatusBadRequest, map[string]string{"error": "folder path does not exist"})
|
||||
@@ -188,10 +194,15 @@ func (h *LibraryHandler) AddLibraryFolder(c echo.Context) error {
|
||||
return c.JSON(http.StatusBadRequest, map[string]string{"error": "folder is not accessible"})
|
||||
}
|
||||
|
||||
// Ensure it's actually a directory, not a file
|
||||
if !fileInfo.IsDir() {
|
||||
return c.JSON(http.StatusBadRequest, map[string]string{"error": "path must be a directory"})
|
||||
}
|
||||
|
||||
folder, err := h.libraryService.AddLibraryFolder(
|
||||
c.Request().Context(),
|
||||
libraryID,
|
||||
req.FolderPath,
|
||||
cleanPath,
|
||||
)
|
||||
if err != nil {
|
||||
return c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
|
||||
|
||||
Reference in New Issue
Block a user