GHSA-287W-MXQ6-X2CP

Vulnerability from github – Published: 2026-07-06 21:29 – Updated: 2026-07-06 21:29
VLAI
Summary
Craft CMS: Sensitive File Disclosure / Server-Side File Read
Details

The dataUrl() Twig function is included in Craft’s Twig sandbox allowlist, allowing any control panel user granted the utility:system-messages permission to embed a file-reading payload into system email templates. When those emails are sent, the server reads the target file and returns its contents as a base64-encoded data URL embedded in the email body. The .env file, which typically contains the database password, CRAFT_SECURITY_KEY, and third-party API keys, passes all of Craft’s existing dataUrl() protection checks and is fully exfiltrated. Obtaining CRAFT_SECURITY_KEY enables an attacker to forge session tokens and escalate to full admin account takeover.

Details

Affected versions: Craft CMS 4.x, 5.x (confirmed against 5.9.19)

The vulnerability arises from the combination of three code facts: 1. dataUrl is in the Twig sandbox allowlist src/config/twig-sandbox.php, line 115: php'allowedFunctions' => [ ... 'dataUrl', // ← allows file reading inside sandboxed templates ... ],

  1. Html::dataUrl() does not block dotfiles src/helpers/Html.php, lines 1065–1090. The function applies four checks before reading a file:

Must be within the project root .env is at the root Must not be in a system directory (config/, vendor/, storage/, templates/) .env is not Must not be a .php file .env has no extension File must exist .env always exists in a Craft install

There is no check for dotfiles or specifically for .env. All four checks pass silently and file_get_contents() is called, with the result returned as data:text/plain;base64,....

  1. System message body is rendered via renderSandboxedString() src/mail/Mailer.php, lines 181–183: php$subject = $view->renderSandboxedString($systemMessage->subject, $variables); $textBody = $view->renderSandboxedString($systemMessage->body, $variables); $htmlBody = $view->renderSandboxedString($systemMessage->body, $variables, escapeHtml: true);

Any body content saved to a system message is executed inside the Twig sandbox when the email renders. Because dataUrl is in allowedFunctions, the sandbox policy permits its execution without restriction.

Access control: The utility:system-messages permission is a non-admin CP permission grantable to any user group via Settings > Users > Groups. It is not restricted to admins.

Impact

Vulnerability type: Sensitive File Disclosure / Server-Side File Read Who is impacted: Any Craft CMS 4.x or 5.x installation where at least one non-admin control panel user has been granted the utility:system-messages permission, and email sending is configured.

Resources:

  • https://github.com/craftcms/cms/pull/18559
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "craftcms/cms"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "4.0.0-RC1"
            },
            {
              "fixed": "4.18.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "craftcms/cms"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "5.0.0-RC1"
            },
            {
              "fixed": "5.10.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-55792"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-200"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-07-06T21:29:49Z",
    "nvd_published_at": "2026-07-02T00:16:44Z",
    "severity": "MODERATE"
  },
  "details": "The `dataUrl()` Twig function is included in Craft\u2019s Twig sandbox allowlist, allowing any control panel user granted the `utility:system-messages` permission to embed a file-reading payload into system email templates. When those emails are sent, the server reads the target file and returns its contents as a base64-encoded data URL embedded in the email body. The .env file, which typically contains the database password, CRAFT_SECURITY_KEY, and third-party API keys, passes all of Craft\u2019s existing `dataUrl()` protection checks and is fully exfiltrated. Obtaining CRAFT_SECURITY_KEY enables an attacker to forge session tokens and escalate to full admin account takeover.\n\n## Details\nAffected versions: Craft CMS 4.x, 5.x (confirmed against 5.9.19)\n\nThe vulnerability arises from the combination of three code facts:\n1. dataUrl is in the Twig sandbox allowlist\nsrc/config/twig-sandbox.php, line 115:\nphp\u0027allowedFunctions\u0027 =\u003e [\n    ...\n    \u0027dataUrl\u0027,   // \u2190 allows file reading inside sandboxed templates\n    ...\n],\n\n2. Html::dataUrl() does not block dotfiles\nsrc/helpers/Html.php, lines 1065\u20131090. The function applies four checks before reading a file:\n\nMust be within the project root .env is at the root\nMust not be in a system directory (config/, vendor/, storage/, templates/) .env is not\nMust not be a .php file  .env has no extension\nFile must exist .env always exists in a Craft install\n\nThere is no check for dotfiles or specifically for .env. All four checks pass silently and file_get_contents() is called, with the result returned as data:text/plain;base64,....\n\n3. System message body is rendered via renderSandboxedString()\nsrc/mail/Mailer.php, lines 181\u2013183:\nphp$subject = $view-\u003erenderSandboxedString($systemMessage-\u003esubject, $variables);\n$textBody = $view-\u003erenderSandboxedString($systemMessage-\u003ebody, $variables);\n$htmlBody = $view-\u003erenderSandboxedString($systemMessage-\u003ebody, $variables, escapeHtml: true);\n\nAny body content saved to a system message is executed inside the Twig sandbox when the email renders. Because dataUrl is in allowedFunctions, the sandbox policy permits its execution without restriction.\n\nAccess control: The utility:system-messages permission is a non-admin CP permission grantable to any user group via Settings \u003e Users \u003e Groups. It is not restricted to admins.\n\n## Impact\nVulnerability type: Sensitive File Disclosure / Server-Side File Read\nWho is impacted: Any Craft CMS 4.x or 5.x installation where at least one non-admin control panel user has been granted the utility:system-messages permission, and email sending is configured.\n\nResources:\n\n- https://github.com/craftcms/cms/pull/18559",
  "id": "GHSA-287w-mxq6-x2cp",
  "modified": "2026-07-06T21:29:49Z",
  "published": "2026-07-06T21:29:49Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/craftcms/cms/security/advisories/GHSA-287w-mxq6-x2cp"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-55792"
    },
    {
      "type": "WEB",
      "url": "https://github.com/craftcms/cms/pull/18559"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/craftcms/cms"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Craft CMS: Sensitive File Disclosure / Server-Side File Read"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…