GitHub Advisoryadvisory · Packagist

GHSA-v47q-jxvr-p68x Craft CMS Vulnerable to Authenticated RCE via "craft.app.fs.write()" in Twig Templates

CRITICAL Published 2026-03-03 Modified 2026-03-04 Official page ↗
Aliases
CVE-2026-28697
Ecosystem
Packagist
Packages
craftcms/cms
Severity
Critical
CVSS vector
CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H
Weaknesses
CWE-1336
Reviewed
2026-03-03

Affected packages

• Packagist craftcms/cms: >= 5.0.0-RC1, < 5.9.0-beta.1 → fixed in 5.9.0-beta.1 • Packagist craftcms/cms: >= 4.0.0-RC1, < 4.17.0-beta.1 → fixed in 4.17.0-beta.1

Description

Summary An authenticated administrator can achieve Remote Code Execution (RCE) by injecting a Server-Side Template Injection (SSTI) payload into Twig template fields (e.g., Email Templates). By calling the `craft.app.fs.write()` method, an attacker can write a malicious PHP script to a web-accessible directory and subsequently access it via the browser to execute arbitrary system commands. --- Proof of Concept Attack Prerequisites • Authenticated administrator account with `allowAdminChanges` enabled, or access to the System Messages utility Steps to Reproduce 1. Navigate to Utilities → System Messages (`/admin/utilities/system-messages`) 2. Edit any email template (e.g., "Test Email") and inject the following in the body (or the Subject): • To exploit it by writing to a file system: • Note: Replace the filesystem handle (e.g., `hardDisk`) with a valid handle configured in the target installation. ```twig {{ craft.app.fs.getFilesystemByHandle('hardDisk').write('shell.php', '') }} ``` • To exploit it by writing to a volume: • Note: Replace the volume handle (e.g., `images`) with a valid handle configured in the target installation. ```twig {{ craft.app.volumes.getVolumeByHandle('images').fs.write('shell.php', '') }} ``` 3. Save & go to Settings → Email (`/admin/settings/email`) 4. Click "Test" at the bottom of the page to trigger template rendering 5. The webshell is now written to the filesystem/volume. Access it via curl or directly from the browser: Note: The path might be different on your end depending on the filesystem or volume configuration. ```bash # For Filesystem curl "http://target.com/uploads/shell.php?c=id" # For Volume curl "http://target.com/uploads/images/shell.php?c=id" # Example Output: uid=33(www-data) gid=33(www-data) groups=33(www-data) ``` --- Additional Impact The same `craft.app` exposure without any security measures enables additional attack vectors: Database Credential Disclosure Database credentials are stored in `.env` outside the webroot and are not accessible to admins through the UI. This bypasses that protection. ```twig {{ craft.app.db.username }} {{ craft.app.db.password }} {{ craft.app.db.dsn }} ``` Security Key Disclosure Craft explicitly redacts the security key from phpinfo and error logs, indicating it should be protected. However, `craft.app.config.general.securityKey` bypasses this protection. ```twig {{ craft.app.config.general.securityKey }} ``` Recommended Fix • Add Twig sandbox rules to block `write`, `writeFileFromStream`, `deleteFile`, and similar destructive methods • Consider allowlist approach for `craft.app` properties accessible in templates rather than exposing the entire application Resources https://github.com/craftcms/cms/commit/9dc2a4a3ec8e9cd5e8c0d1129f36371437519197 https://github.com/craftcms/cms/pull/18219 https://github.com/craftcms/cms/pull/18216

Related

Alias · CVE (1)

  • CVE-2026-28697 Craft is a content management system (CMS). vulnerability

Weakness · CWE (1)

  • CWE-1336 Improper Neutralization of Special Elements Used in a Template Engine weakness

References