fix(img):Prevent thumbnail generation for large images
parent
c18afcddc4
commit
d00b3ea8f8
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
libErrors "github.com/filebrowser/filebrowser/v2/errors"
|
libErrors "github.com/filebrowser/filebrowser/v2/errors"
|
||||||
|
imgErrors "github.com/filebrowser/filebrowser/v2/img"
|
||||||
)
|
)
|
||||||
|
|
||||||
func renderJSON(w http.ResponseWriter, _ *http.Request, data interface{}) (int, error) {
|
func renderJSON(w http.ResponseWriter, _ *http.Request, data interface{}) (int, error) {
|
||||||
|
|
@ -42,6 +43,8 @@ func errToStatus(err error) int {
|
||||||
return http.StatusBadRequest
|
return http.StatusBadRequest
|
||||||
case errors.Is(err, libErrors.ErrRootUserDeletion):
|
case errors.Is(err, libErrors.ErrRootUserDeletion):
|
||||||
return http.StatusForbidden
|
return http.StatusForbidden
|
||||||
|
case errors.Is(err, imgErrors.ErrImageTooLarge):
|
||||||
|
return http.StatusRequestEntityTooLarge
|
||||||
default:
|
default:
|
||||||
return http.StatusInternalServerError
|
return http.StatusInternalServerError
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,15 @@ import (
|
||||||
// ErrUnsupportedFormat means the given image format is not supported.
|
// ErrUnsupportedFormat means the given image format is not supported.
|
||||||
var ErrUnsupportedFormat = errors.New("unsupported image format")
|
var ErrUnsupportedFormat = errors.New("unsupported image format")
|
||||||
|
|
||||||
|
// ErrImageTooLarge means the image is too large to create a thumbnail.
|
||||||
|
var ErrImageTooLarge = errors.New("image too large for thumbnail generation")
|
||||||
|
|
||||||
|
// Maximum dimensions for thumbnail generation to prevent server crashes
|
||||||
|
const (
|
||||||
|
MaxImageWidth = 10000
|
||||||
|
MaxImageHeight = 10000
|
||||||
|
)
|
||||||
|
|
||||||
// Service
|
// Service
|
||||||
type Service struct {
|
type Service struct {
|
||||||
sem semaphore.Semaphore
|
sem semaphore.Semaphore
|
||||||
|
|
@ -187,11 +196,17 @@ func (s *Service) detectFormat(in io.Reader) (Format, io.Reader, error) {
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
r := io.TeeReader(in, buf)
|
r := io.TeeReader(in, buf)
|
||||||
|
|
||||||
_, imgFormat, err := image.DecodeConfig(r)
|
imgConfig, imgFormat, err := image.DecodeConfig(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, nil, fmt.Errorf("%s: %w", err.Error(), ErrUnsupportedFormat)
|
return 0, nil, fmt.Errorf("%s: %w", err.Error(), ErrUnsupportedFormat)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if image dimensions exceed maximum allowed size
|
||||||
|
if imgConfig.Width > MaxImageWidth || imgConfig.Height > MaxImageHeight {
|
||||||
|
return 0, nil, fmt.Errorf("image dimensions %dx%d exceed maximum %dx%d: %w",
|
||||||
|
imgConfig.Width, imgConfig.Height, MaxImageWidth, MaxImageHeight, ErrImageTooLarge)
|
||||||
|
}
|
||||||
|
|
||||||
format, err := ParseFormat(imgFormat)
|
format, err := ParseFormat(imgFormat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, nil, ErrUnsupportedFormat
|
return 0, nil, ErrUnsupportedFormat
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue