Skip to content

Commit

Permalink
Accept a closure to configure SvgSanitizer
Browse files Browse the repository at this point in the history
  • Loading branch information
timkelty committed Mar 18, 2024
1 parent 14e9753 commit 52f8659
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 6 deletions.
20 changes: 16 additions & 4 deletions src/config/GeneralConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@

namespace craft\config;

use Closure;
use Craft;
use craft\helpers\ConfigHelper;
use craft\helpers\DateTimeHelper;
use craft\helpers\Localization;
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;
Expand Down Expand Up @@ -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.
*
Expand All @@ -2555,7 +2557,7 @@ class GeneralConfig extends BaseConfig
*
* @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]].
Expand Down Expand Up @@ -5951,13 +5953,23 @@ public function sameSiteCookieValue(?string $value): self
* ->sanitizeSvgUploads(false)
* ```
*
* 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
* @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;
Expand Down
11 changes: 9 additions & 2 deletions src/services/Images.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace craft\services;

use Closure;
use Craft;
use craft\base\Image;
use craft\helpers\App;
Expand All @@ -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;
Expand Down Expand Up @@ -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);

Expand Down

0 comments on commit 52f8659

Please sign in to comment.