diff --git a/src/config/GeneralConfig.php b/src/config/GeneralConfig.php index 2b6c5738d38..5f2ee836a5f 100644 --- a/src/config/GeneralConfig.php +++ b/src/config/GeneralConfig.php @@ -7,6 +7,7 @@ namespace craft\config; +use Closure; use Craft; use craft\helpers\ConfigHelper; use craft\helpers\DateTimeHelper; @@ -14,6 +15,7 @@ use craft\helpers\StringHelper; use craft\services\Config; use DateInterval; +use enshrined\svgSanitize\Sanitizer; use yii\base\InvalidArgumentException; use yii\base\InvalidConfigException; use yii\base\UnknownPropertyException; @@ -2540,7 +2542,7 @@ class GeneralConfig extends BaseConfig public ?string $sameSiteCookieValue = null; /** - * @var bool Whether Craft should sanitize uploaded SVG files and strip out potential malicious-looking content. + * @var bool|Closure Whether Craft should sanitize uploaded SVG files and strip out potential malicious-looking content. * * This should definitely be enabled if you are accepting SVG uploads from untrusted sources. * @@ -2553,9 +2555,19 @@ class GeneralConfig extends BaseConfig * ``` * ::: * + * Alternatively, this maybe set to a closure that accepts a [[\enshrined\svgSanitize\Sanitizer]] instance and returns + * a [[\enshrined\svgSanitize\Sanitizer]] instance further customization. + * + * ```php + * ->sanitizeSvgUploads(function(\enshrined\svgSanitize\Sanitizer $sanitizer): \enshrined\svgSanitize\Sanitizer { + * $sanitizer->removeRemoteReferences(true); + * return $sanitizer; + * }) + * ``` + * * @group Security */ - public bool $sanitizeSvgUploads = true; + public bool|Closure $sanitizeSvgUploads = true; /** * @var string A private, random, cryptographically-secure key that is used for hashing and encrypting data in [[\craft\services\Security]]. @@ -5952,12 +5964,12 @@ public function sameSiteCookieValue(?string $value): self * ``` * * @group Security - * @param bool $value + * @param bool|Closure(Sanitizer):Sanitizer $value * @return self * @see $sanitizeSvgUploads * @since 4.2.0 */ - public function sanitizeSvgUploads(bool $value = true): self + public function sanitizeSvgUploads(bool|Closure $value = true): self { $this->sanitizeSvgUploads = $value; return $this; diff --git a/src/services/Images.php b/src/services/Images.php index 8146df26dba..f1b78a27af8 100644 --- a/src/services/Images.php +++ b/src/services/Images.php @@ -7,6 +7,7 @@ namespace craft\services; +use Closure; use Craft; use craft\base\Image; use craft\helpers\App; @@ -19,7 +20,6 @@ use enshrined\svgSanitize\Sanitizer; use Imagine\Gd\Imagine as GdImagine; use Imagine\Image\Format; -use Imagine\Imagick\Imagick; use Imagine\Imagick\Imagine as ImagickImagine; use Throwable; use yii\base\Component; @@ -320,12 +320,19 @@ public function cleanImage(string $filePath): void // Special case for SVG files. if (FileHelper::isSvg($filePath)) { - if (!Craft::$app->getConfig()->getGeneral()->sanitizeSvgUploads) { + $sanitizeSvgUploads = Craft::$app->getConfig()->getGeneral()->sanitizeSvgUploads; + + if (!$sanitizeSvgUploads) { return; } $sanitizer = new Sanitizer(); $sanitizer->setAllowedAttrs(new SvgAllowedAttributes()); + + if ($sanitizeSvgUploads instanceof Closure) { + $sanitizer = ($sanitizeSvgUploads)($sanitizer); + } + $svgContents = file_get_contents($filePath); $svgContents = $sanitizer->sanitize($svgContents);