Add IMGPROXY_MAX_ANIMATION_FRAME_RESOLUTION config

This commit is contained in:
DarthSim
2022-11-29 18:25:38 +06:00
parent c105e66e39
commit 1ededbb11f
6 changed files with 30 additions and 12 deletions

View File

@@ -1,6 +1,9 @@
# Changelog # Changelog
## [Unreleased] ## [Unreleased]
### Add
- Add `IMGPROXY_MAX_ANIMATION_FRAME_RESOLUTION` config.
### Change ### Change
- Change `IMGPROXY_FORMAT_QUALITY` default value to `avif=65`. - Change `IMGPROXY_FORMAT_QUALITY` default value to `avif=65`.
- Change `IMGPROXY_AVIF_SPEED` default value to `8`. - Change `IMGPROXY_AVIF_SPEED` default value to `8`.

View File

@@ -35,11 +35,12 @@ var (
PathPrefix string PathPrefix string
MaxSrcResolution int MaxSrcResolution int
MaxSrcFileSize int MaxSrcFileSize int
MaxAnimationFrames int MaxAnimationFrames int
MaxSvgCheckBytes int MaxAnimationFrameResolution int
MaxRedirects int MaxSvgCheckBytes int
MaxRedirects int
JpegProgressive bool JpegProgressive bool
PngInterlaced bool PngInterlaced bool
@@ -217,6 +218,7 @@ func Reset() {
MaxSrcResolution = 16800000 MaxSrcResolution = 16800000
MaxSrcFileSize = 0 MaxSrcFileSize = 0
MaxAnimationFrames = 1 MaxAnimationFrames = 1
MaxAnimationFrameResolution = 0
MaxSvgCheckBytes = 32 * 1024 MaxSvgCheckBytes = 32 * 1024
MaxRedirects = 10 MaxRedirects = 10
@@ -386,6 +388,7 @@ func Configure() error {
configurators.Int(&MaxSvgCheckBytes, "IMGPROXY_MAX_SVG_CHECK_BYTES") configurators.Int(&MaxSvgCheckBytes, "IMGPROXY_MAX_SVG_CHECK_BYTES")
configurators.Int(&MaxAnimationFrames, "IMGPROXY_MAX_ANIMATION_FRAMES") configurators.Int(&MaxAnimationFrames, "IMGPROXY_MAX_ANIMATION_FRAMES")
configurators.MegaInt(&MaxAnimationFrameResolution, "IMGPROXY_MAX_ANIMATION_FRAME_RESOLUTION")
configurators.Int(&MaxRedirects, "IMGPROXY_MAX_REDIRECTS") configurators.Int(&MaxRedirects, "IMGPROXY_MAX_REDIRECTS")

View File

@@ -60,13 +60,15 @@ echo $(xxd -g 2 -l 64 -p /dev/random | tr -d '\n')
imgproxy protects you from so-called image bombs. Here's how you can specify the maximum image resolution which you consider reasonable: imgproxy protects you from so-called image bombs. Here's how you can specify the maximum image resolution which you consider reasonable:
* `IMGPROXY_MAX_SRC_RESOLUTION`: the maximum resolution of the source image, in megapixels. Images with larger actual size will be rejected. Default: `16.8` * `IMGPROXY_MAX_SRC_RESOLUTION`: the maximum resolution of the source image, in megapixels. Images with larger actual size will be rejected. Default: `16.8`
**Warning:** When the source image is animated, imgproxy summarizes all its frames' resolutions while checking the source image resolution unless `IMGPROXY_MAX_ANIMATION_FRAME_RESOLUTION` is greater than zero.
* `IMGPROXY_MAX_SRC_FILE_SIZE`: the maximum size of the source image, in bytes. Images with larger file size will be rejected. When set to `0`, file size check is disabled. Default: `0` * `IMGPROXY_MAX_SRC_FILE_SIZE`: the maximum size of the source image, in bytes. Images with larger file size will be rejected. When set to `0`, file size check is disabled. Default: `0`
imgproxy can process animated images (GIF, WebP), but since this operation is pretty memory heavy, only one frame is processed by default. You can increase the maximum animation frames that can be processed number of with the following variable: imgproxy can process animated images (GIF, WebP), but since this operation is pretty memory heavy, only one frame is processed by default. You can increase the maximum animation frames that can be processed number of with the following variable:
* `IMGPROXY_MAX_ANIMATION_FRAMES`: the maximum number of animated image frames that may be processed. Default: `1` * `IMGPROXY_MAX_ANIMATION_FRAMES`: the maximum number of animated image frames that may be processed. Default: `1`
* `IMGPROXY_MAX_ANIMATION_FRAME_RESOLUTION`: the maximum resolution of the animated source image frame, in megapixels. Images with larger actual frame size will be rejected. When set to `0`, imgproxy will test the whole animated image resolution against `IMGPROXY_MAX_SRC_RESOLUTION` summarising all the frames' resolutions. Default: `0`
**📝Note:** imgproxy summarizes all frame resolutions while checking the source image resolution.
To check if the source image is SVG, imgproxy reads some amount of bytes; by default it reads a maximum of 32KB. However, you can change this value using the following variable: To check if the source image is SVG, imgproxy reads some amount of bytes; by default it reads a maximum of 32KB. However, you can change this value using the following variable:

View File

@@ -67,7 +67,7 @@ func readAndCheckImage(r io.Reader, contentLength int) (*ImageData, error) {
return nil, checkTimeoutErr(err) return nil, checkTimeoutErr(err)
} }
if err = security.CheckDimensions(meta.Width(), meta.Height()); err != nil { if err = security.CheckDimensions(meta.Width(), meta.Height(), 1); err != nil {
buf.Reset() buf.Reset()
cancel() cancel()
return nil, err return nil, err

View File

@@ -119,7 +119,7 @@ func transformAnimated(ctx context.Context, img *vips.Image, po *options.Process
framesCount := imath.Min(img.Height()/frameHeight, config.MaxAnimationFrames) framesCount := imath.Min(img.Height()/frameHeight, config.MaxAnimationFrames)
// Double check dimensions because animated image has many frames // Double check dimensions because animated image has many frames
if err = security.CheckDimensions(imgWidth, frameHeight*framesCount); err != nil { if err = security.CheckDimensions(imgWidth, frameHeight, framesCount); err != nil {
return err return err
} }

View File

@@ -3,13 +3,23 @@ package security
import ( import (
"github.com/imgproxy/imgproxy/v3/config" "github.com/imgproxy/imgproxy/v3/config"
"github.com/imgproxy/imgproxy/v3/ierrors" "github.com/imgproxy/imgproxy/v3/ierrors"
"github.com/imgproxy/imgproxy/v3/imath"
) )
var ErrSourceResolutionTooBig = ierrors.New(422, "Source image resolution is too big", "Invalid source image") var ErrSourceResolutionTooBig = ierrors.New(422, "Source image resolution is too big", "Invalid source image")
var ErrSourceFrameResolutionTooBig = ierrors.New(422, "Source image frame resolution is too big", "Invalid source image")
func CheckDimensions(width, height int) error { func CheckDimensions(width, height, frames int) error {
if width*height > config.MaxSrcResolution { frames = imath.Max(frames, 1)
return ErrSourceResolutionTooBig
if frames > 1 && config.MaxAnimationFrameResolution > 0 {
if width*height > config.MaxAnimationFrameResolution {
return ErrSourceFrameResolutionTooBig
}
} else {
if width*height*frames > config.MaxSrcResolution {
return ErrSourceResolutionTooBig
}
} }
return nil return nil