VYPR
High severityNVD Advisory· Published Mar 16, 2026· Updated Apr 16, 2026

CVE-2026-32261

CVE-2026-32261

Description

Webhooks for Craft CMS plugin adds the ability to manage “webhooks” in Craft CMS, which will send GET or POST requests when certain events occur. From version 3.0.0 to before version 3.2.0, the Webhooks plugin renders user-supplied template content through Twig’s renderString() function without sandbox protection. This allows an authenticated user with access to the Craft control panel and permissions to access the Webhooks plugin to inject Twig template code that calls arbitrary PHP functions. This is possible even if allowAdminChanges is set to false. This issue has been patched in version 3.2.0.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
craftcms/webhooksPackagist
>= 3.0.0, < 3.2.03.2.0

Affected products

1

Patches

1
88344991a68b

Use the Twig sandbox

https://github.com/craftcms/webhooksbrandonkellyFeb 13, 2026via ghsa
4 files changed · +808 547
  • CHANGELOG.md+8 0 modified
    @@ -1,5 +1,13 @@
     # Release Notes for Webhooks for Craft CMS
     
    +## Unreleased
    +
    +> [!WARNING]
    +> Payload, header, webhook URL, and debounce key templates are now rendered in a sandboxed Twig environment, when `enableTwigSandbox` is enabled.
    + 
    +- Webhooks now requires Craft 4.17+ or 5.9+.
    +- Fixed a [high-severity](https://github.com/craftcms/cms/security/policy#severity--remediation) RCE vulnerability. (GHSA-8wg7-wm29-2rvg)
    +
     ## 3.1.1 - 2025-07-29
     
     - Fixed a PHP error that could occur if a webhook header was null. ([#97](https://github.com/craftcms/webhooks/issues/97))
    
  • composer.json+1 1 modified
    @@ -27,7 +27,7 @@
       "prefer-stable": true,
       "require": {
         "php": "^8.0.2",
    -    "craftcms/cms": "^4.0.0-RC2|^5.0.0-beta.1"
    +    "craftcms/cms": "^4.17.0|^5.9.0"
       },
       "require-dev": {
         "craftcms/ecs": "dev-main",
    
  • composer.lock+795 542 modified
  • src/Plugin.php+4 4 modified
    @@ -155,7 +155,7 @@ function(Event $e) use ($webhook) {
                         if (in_array($webhook->method, ['post', 'put'], true)) {
                             // Build out the body data
                             if ($webhook->payloadTemplate) {
    -                            $json = $view->renderString($webhook->payloadTemplate, [
    +                            $json = $view->renderSandboxedString($webhook->payloadTemplate, [
                                     'event' => $e,
                                 ]);
                                 $data = Json::decodeIfJson($json);
    @@ -188,7 +188,7 @@ function(Event $e) use ($webhook) {
                             $header['value'] = App::parseEnv($header['value']);
     
                             if (is_string($header['value'])) {
    -                            $header['value'] = $view->renderString($header['value'], [
    +                            $header['value'] = $view->renderSandboxedString($header['value'], [
                                     'event' => $e,
                                 ]);
                             }
    @@ -219,13 +219,13 @@ function(Event $e) use ($webhook) {
     
                         // Queue the send request up
                         $url = App::parseEnv($webhook->url);
    -                    $url = $view->renderString($url, [
    +                    $url = $view->renderSandboxedString($url, [
                             'event' => $e,
                         ]);
     
                         if ($webhook->debounceKeyFormat) {
                             $debounceKey = App::parseEnv($webhook->debounceKeyFormat);
    -                        $debounceKey = $webhook->id . ':' . $view->renderString($debounceKey, [
    +                        $debounceKey = $webhook->id . ':' . $view->renderSandboxedString($debounceKey, [
                                     'event' => $e,
                                 ]);
                         }
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

7