mirror of
https://github.com/imgproxy/imgproxy.git
synced 2025-09-16 09:36:18 +02:00
Add IMGPROXY_ALLOWED_PROCESSING_OPTIONS config
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
## [Unreleased]
|
||||
### Added
|
||||
- Add [IMGPROXY_MAX_RESULT_DIMENSION](https://docs.imgproxy.net/latest/configuration/options#IMGPROXY_MAX_RESULT_DIMENSION) config and [max_result_dimension](https://docs.imgproxy.net/latest/usage/processing#max-result-dimension) processing option.
|
||||
- Add [IMGPROXY_ALLOWED_PROCESSING_OPTIONS](https://docs.imgproxy.net/latest/configuration/options#IMGPROXY_ALLOWED_PROCESSING_OPTIONS) config.
|
||||
- Add `imgproxy.source_image_origin` attribute to New Relic, DataDog, and OpenTelemetry traces.
|
||||
- Add `imgproxy.source_image_url` and `imgproxy.source_image_origin` attributes to `downloading_image` spans in New Relic, DataDog, and OpenTelemetry traces.
|
||||
- Add `imgproxy.processing_options` attribute to `processing_image` spans in New Relic, DataDog, and OpenTelemetry traces.
|
||||
|
@@ -48,6 +48,7 @@ var (
|
||||
PngUnlimited bool
|
||||
SvgUnlimited bool
|
||||
MaxResultDimension int
|
||||
AllowedProcessiongOptions []string
|
||||
AllowSecurityOptions bool
|
||||
|
||||
JpegProgressive bool
|
||||
@@ -254,6 +255,7 @@ func Reset() {
|
||||
PngUnlimited = false
|
||||
SvgUnlimited = false
|
||||
MaxResultDimension = 0
|
||||
AllowedProcessiongOptions = make([]string, 0)
|
||||
AllowSecurityOptions = false
|
||||
|
||||
JpegProgressive = false
|
||||
@@ -486,6 +488,7 @@ func Configure() error {
|
||||
configurators.Bool(&SvgUnlimited, "IMGPROXY_SVG_UNLIMITED")
|
||||
|
||||
configurators.Int(&MaxResultDimension, "IMGPROXY_MAX_RESULT_DIMENSION")
|
||||
configurators.StringSlice(&AllowedProcessiongOptions, "IMGPROXY_ALLOWED_PROCESSING_OPTIONS")
|
||||
|
||||
configurators.Bool(&AllowSecurityOptions, "IMGPROXY_ALLOW_SECURITY_OPTIONS")
|
||||
|
||||
|
@@ -35,6 +35,16 @@ func newUnknownOptionError(kind, opt string) error {
|
||||
)
|
||||
}
|
||||
|
||||
func newForbiddenOptionError(kind, opt string) error {
|
||||
return ierrors.Wrap(
|
||||
UnknownOptionError(fmt.Sprintf("Forbidden %s option %s", kind, opt)),
|
||||
1,
|
||||
ierrors.WithStatusCode(http.StatusNotFound),
|
||||
ierrors.WithPublicMessage("Invalid URL"),
|
||||
ierrors.WithShouldReport(false),
|
||||
)
|
||||
}
|
||||
|
||||
func (e UnknownOptionError) Error() string { return string(e) }
|
||||
|
||||
func newOptionArgumentError(format string, args ...interface{}) error {
|
||||
|
@@ -59,7 +59,7 @@ func parsePreset(presetStr string) error {
|
||||
func ValidatePresets() error {
|
||||
for name, opts := range presets {
|
||||
po := NewProcessingOptions()
|
||||
if err := applyURLOptions(po, opts, name); err != nil {
|
||||
if err := applyURLOptions(po, opts, true, name); err != nil {
|
||||
return fmt.Errorf("Error in preset `%s`: %s", name, err)
|
||||
}
|
||||
}
|
||||
|
@@ -691,7 +691,7 @@ func applyPresetOption(po *ProcessingOptions, args []string, usedPresets ...stri
|
||||
|
||||
po.UsedPresets = append(po.UsedPresets, preset)
|
||||
|
||||
if err := applyURLOptions(po, p, append(usedPresets, preset)...); err != nil {
|
||||
if err := applyURLOptions(po, p, true, append(usedPresets, preset)...); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
@@ -1081,8 +1081,14 @@ func applyURLOption(po *ProcessingOptions, name string, args []string, usedPrese
|
||||
return newUnknownOptionError("processing", name)
|
||||
}
|
||||
|
||||
func applyURLOptions(po *ProcessingOptions, options urlOptions, usedPresets ...string) error {
|
||||
func applyURLOptions(po *ProcessingOptions, options urlOptions, allowAll bool, usedPresets ...string) error {
|
||||
allowAll = allowAll || len(config.AllowedProcessiongOptions) == 0
|
||||
|
||||
for _, opt := range options {
|
||||
if !allowAll && !slices.Contains(config.AllowedProcessiongOptions, opt.Name) {
|
||||
return newForbiddenOptionError("processing", opt.Name)
|
||||
}
|
||||
|
||||
if err := applyURLOption(po, opt.Name, opt.Args, usedPresets...); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1154,7 +1160,7 @@ func parsePathOptions(parts []string, headers http.Header) (*ProcessingOptions,
|
||||
|
||||
options, urlParts := parseURLOptions(parts)
|
||||
|
||||
if err = applyURLOptions(po, options); err != nil {
|
||||
if err = applyURLOptions(po, options, false); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
|
@@ -6,6 +6,7 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
@@ -644,6 +645,40 @@ func (s *ProcessingOptionsTestSuite) TestParseBase64URLOnlyPresets() {
|
||||
s.Require().Equal(originURL, imageURL)
|
||||
}
|
||||
|
||||
func (s *ProcessingOptionsTestSuite) TestParseAllowedOptions() {
|
||||
config.AllowedProcessiongOptions = []string{"w", "h", "pr"}
|
||||
|
||||
presets["test1"] = urlOptions{
|
||||
urlOption{Name: "blur", Args: []string{"0.2"}},
|
||||
}
|
||||
|
||||
originURL := "http://images.dev/lorem/ipsum.jpg?param=value"
|
||||
|
||||
testCases := []struct {
|
||||
options string
|
||||
expectedError string
|
||||
}{
|
||||
{options: "w:100/h:200", expectedError: ""},
|
||||
{options: "w:100/h:200/blur:10", expectedError: "Forbidden processing option blur"},
|
||||
{options: "w:100/h:200/pr:test1", expectedError: ""},
|
||||
{options: "w:100/h:200/pr:test1/blur:10", expectedError: "Forbidden processing option blur"},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(strings.ReplaceAll(tc.options, "/", "_"), func() {
|
||||
path := fmt.Sprintf("/%s/%s.png", tc.options, base64.RawURLEncoding.EncodeToString([]byte(originURL)))
|
||||
_, _, err := ParsePath(path, make(http.Header))
|
||||
|
||||
if len(tc.expectedError) > 0 {
|
||||
s.Require().Error(err)
|
||||
s.Require().Equal(tc.expectedError, err.Error())
|
||||
} else {
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessingOptions(t *testing.T) {
|
||||
suite.Run(t, new(ProcessingOptionsTestSuite))
|
||||
}
|
||||
|
Reference in New Issue
Block a user