All vulnerabilities
GHSA-w643-x88w-6wcm

craftcms/cms: Twig "create()" blocklist case-sensitivity bypass

craftcms/cms
CVSS
n/aLow
ExploitationNo known exploitationNot in CISA KEV, which does not prove it is unexploitedCISA KEV
Exploit odds (EPSS)No scoreNo FIRST EPSS score in this snapshot yet
Fixed in4.18.8Also 5.11.0GitHub
Published5 Oct 2026Updated 5 Oct 2026GitHub

What fixes it

  • 4.18.8craftcms/cms, composerGitHubcomposer require "craftcms/cms:^4.18.8"
  • 5.11.0craftcms/cms, composerGitHubcomposer require "craftcms/cms:^5.11.0"

A fixed version on one release line is not the upgrade target for every line. Check your exact version and any vendor backports.

Description

The blocklist guarding Craft’s Twig create() function — introduced in 5.10.6 as the fix for 1369 — tests attacker-controlled class names with case-sensitive string prefix/suffix checks, while PHP class resolution is case-insensitive.

Passing the class name in lowercase (create("splfileobject", …)) bypasses both checks and instantiates SplFileObject, restoring arbitrary local file read and write from any template-execution context. File write escalates to remote code execution by writing a PHP file into the webroot and requesting it over HTTP.

Two independent defects combine in Extension::createFunction() (src/web/twig/Extension.php:1543-1574, 5.10.13.2):

  1. str_starts_with(ltrim($class, '\\'), 'Spl') (:1564) and str_ends_with(rtrim($class, '\\'), 'Iterator') (:1568) are case-sensitive; Craft::createObject() resolves "splfileobject" to SplFileObject regardless.
  2. When the Spl prefix check was added in 5.10.6, SplFileObject was simultaneously *removed* from the surviving case-insensitive is_a() blocklist (:1550-1562), so no case-insensitive check covers it at all.

This is a regression of the original 1369 fix: the proper case name is blocked, the lowercase name is not.

Impact

An attacker with template-execution rights (e.g., a Control Panel administrator in the default configuration) can:

  • Read any file the web user can read, including .env → theft of CRAFT_SECURITY_KEY and database credentials (Craft’s canonical privilege-escalation chain).
  • Write any file the web user can write; demonstrated end-to-end: PHP shell written into the webroot → HTTP-triggered code execution as the web user.
  • Defeat the blocklist as a security boundary for any other consumer of create().

Report ID: 1681

Text from GitHub Advisory Database

Affected versions 2

  • craftcms/cms, composer>= 4.0.0, < 4.18.8GitHub
  • craftcms/cms, composer>= 5.0.0, < 5.11.0GitHub