Jul 18, 2026·6 min read·16 visits
Low-privileged Craft CMS Control Panel users can bypass UI restrictions and make direct HTTP requests to Formie controller endpoints to modify administrative settings and access API keys due to missing server-side authorization checks.
A missing authorization vulnerability in the Formie plugin for Craft CMS prior to version 3.1.28 allows low-privileged Control Panel users to read and modify sensitive administrative settings, configuration options, and third-party integrations.
Formie is a popular form builder plugin for the Craft CMS ecosystem, developed by Verbb. It enables administrators to construct, manage, and process complex multi-page forms, collect payments via integrations like Stripe, and forward captured data to CRM or marketing platforms. The administrative control surface exposes various sensitive capabilities, including API keys, encryption secrets, database schemas, and outbound webhook configurations.\n\nThis vulnerability, tracked as GHSA-CVPC-HCCG-WMW4, is a classic example of Broken Access Control, specifically categorized under CWE-862 (Missing Authorization). Prior to version 3.1.28, the plugin failed to enforce server-side capability checks on several backend controller actions responsible for managing these administrative settings. This deficiency left the application exposed to privilege escalation from within the authenticated environment.\n\nThe attack surface is accessible to any user who has authenticated credentials for the Craft CMS Control Panel. Even if a user account is configured with the absolute minimum set of privileges, such as a restricted content author who lacks administrative rights, that user can directly access and execute actions across fifteen distinct settings-related controllers.
The root cause of GHSA-CVPC-HCCG-WMW4 lies in a fundamental architectural oversight regarding security boundaries in web applications. The Formie development team implemented authorization checks primarily at the User Interface layer. The main plugin class checked if the active session user was a super administrator before rendering the Settings link in the Control Panel's sidebar menu.\n\nWhile this UI-level constraint successfully hid the settings menu from unauthorized users, it did not secure the underlying routing endpoints or controller actions. Under the Craft CMS architecture, controllers handle incoming web requests by mapping routing paths directly to controller classes and action methods. Because these controllers extended the default craft web Controller class without overriding permission checks, they inherited standard, low-privilege access rules.\n\nConsequently, the application did not perform any server-side validation to verify that the requesting user possessed administrative privileges. An attacker could bypass the UI restrictions entirely by executing structured HTTP POST or GET requests directly targeting the backend action endpoints. This lack of centralized or middleware-enforced authorization checks allowed low-privileged sessions to execute critical administrative workflows.
Prior to version 3.1.28, the Formie main class restricted UI access to the settings menu using the following code path inside src/Formie.php:\n\nphp\n// src/Formie.php (Vulnerable UI Check)\nif (Craft::$app->getUser()->getIsAdmin()) {\n $nav['subnav']['settings'] = [\n 'label' => Craft::t('formie', 'Settings'),\n 'url' => 'formie/settings',\n ];\n}\n\n\nTo remediate this, the patch introduced proper function-level access control. First, a granular permission was registered inside src/Formie.php:\n\nphp\n// src/Formie.php (Patched Check)\nif (Craft::$app->getUser()->checkPermission('formie-accessSettings')) {\n $nav['subnav']['settings'] = [\n 'label' => Craft::t('formie', 'Settings'),\n 'url' => 'formie/settings',\n ];\n}\n\n\nSecond, the patch introduced a base controller SettingsAccessController.php to intercept incoming requests and systematically enforce permission checks before executing any settings actions:\n\nphp\n// src/controllers/SettingsAccessController.php (New Base Controller)\n<?php\nnamespace verbb\\formie\\controllers;\n\nuse craft\\web\\Controller;\n\nclass SettingsAccessController extends Controller\n{\n public function beforeAction($action): bool\n {\n // Explicitly require the settings permission before executing any action\n $this->requirePermission('formie-accessSettings');\n\n return parent::beforeAction($action);\n }\n}\n\n\nFifteen settings-related controllers were refactored to inherit from SettingsAccessController instead of craft\\web\\Controller, securing all associated routes. For controllers where global inheritance was not applicable, explicit action checks were implemented. For example, in IntegrationsController.php:\n\nphp\n// src/controllers/IntegrationsController.php (Patched Method Check)\nif (in_array($action->id, ['save-integration', 'reorder-integrations', 'delete-integration', 'check-connection', 'connect', 'disconnect'], true)) {\n $this->requirePermission('formie-accessSettings');\n}\n
To exploit this vulnerability, an attacker must first obtain valid credentials to the Craft CMS Control Panel. This initial access can be achieved through credential harvesting, social engineering, or secondary low-severity application flaws. Once logged into the Control Panel, the attacker does not need any administrative permissions to proceed.\n\nThe attacker can identify target controllers by mapping standard Formie administrative endpoints, such as formie/integrations/save-integration. Because Craft CMS routing maps these endpoints predictably, the attacker can craft an HTTP request to save, modify, or delete a third-party integration configuration. The lack of server-side validation means the controller will process the request exactly as it would for a super administrator.\n\nThe following diagram illustrates the vulnerable control flow compared to the patched, secure authorization flow:\n\nmermaid\ngraph LR\n A["Low-Privilege User"] --> B{"Direct Request to Controller Action?"}\n B -- "Yes (Pre-Patch)" --> C["Skip UI Nav Check"]\n C --> D["Execute Action in Controller"]\n D --> E["Unauthorized Config Change"]\n B -- "Yes (Post-Patch)" --> F["beforeAction Interception"]\n F --> G{"Has 'formie-accessSettings'?"}\n G -- "No" --> H["403 Forbidden Access Blocked"]\n G -- "Yes" --> I["Execute Action"]\n
The security implications of GHSA-CVPC-HCCG-WMW4 are substantial, affecting the Confidentiality, Integrity, and Availability of the host Craft CMS platform. By gaining unauthorized access to the Formie configuration panel, a low-privileged user can intercept, modify, or disable critical business processes. The base severity for this flaw is assessed at CVSS 8.8 (High) due to the combination of low attack complexity and extensive privileges granted upon success.\n\nFrom a confidentiality perspective, administrative access to Formie allows users to view sensitive third-party API credentials, such as Stripe private keys, Mailchimp integration tokens, or CRM connection secrets. This exposure allows an attacker to exfiltrate these credentials and pivot to secondary external systems, expanding the breach surface well beyond the boundaries of the CMS.\n\nFrom an integrity and availability perspective, an attacker can modify active form behaviors, hijack payment processing destinations, alter submission routing rules, or delete crucial database migration configurations. This capability can result in financial loss through direct redirect attacks, lead capture hijacking, and structural application disruption.
The primary remediation path is upgrading the Formie plugin to version 3.1.28 or higher immediately. The development team has systematically secured fifteen settings-related controllers by introducing the SettingsAccessController and defining the explicit formie-accessSettings permission check. Administrators must verify that the upgrade has been successfully applied and that no cached files or dependencies prevent the new controllers from running.\n\nFollowing the upgrade, security teams must audit user roles and permission sets in the Craft CMS Control Panel. Because the patch introduces a new granular permission, formie-accessSettings, administrators should verify that this permission is strictly restricted to trusted administrative groups. No low-privileged or standard user roles should have this permission enabled.\n\nIn environments where immediate patching is not feasible, organizations can implement temporary web application firewall rules. These rules should monitor and block POST requests targeting /admin/formie/settings/* or /admin/formie/integrations/* coming from IP addresses or sessions associated with non-administrative users. However, these mitigations are brittle and should not replace a complete patch application.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
Formie Verbb | < 3.1.28 | 3.1.28 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-862 (Missing Authorization) |
| Attack Vector | Network |
| CVSS v3.1 | 8.8 (High) |
| EPSS Score | N/A |
| Impact | Privilege Escalation and Unauthorized Configuration Modification |
| Exploit Status | No public exploit available |
| KEV Status | Not listed |
The software does not perform an authorization check when an actor attempts to access a resource or perform an action.
A path traversal vulnerability (CWE-22) in Contao CMS allows unauthenticated remote attackers to bypass directory boundary restrictions in ImagesController and access files within the project directory.
Contao Open Source CMS versions 4.0.0 through 5.3.49 and 5.4.0-RC1 through 5.7.11 contain a Cross-Site Request Forgery (CSRF) vulnerability in backend parameter handling. The `RequestTokenListener` component validates anti-CSRF tokens solely for HTTP POST requests, while GET-based declarative guards run only when an `act` parameter is present in the query string. Consequently, custom backend actions dispatched via alternative parameters such as `key=` can execute without CSRF token verification when triggered by an authenticated user.
Contao CMS versions 4.1.0 through 5.3.49 and 5.4.0-RC1 through 5.7.11 fail to validate form submission tokens and enforce rate limiting when processing activation email resend requests via HTTP POST, enabling resource exhaustion and account state enumeration.
An information disclosure vulnerability in Contao CMS allows unauthenticated site visitors to view protected page titles, URLs, and text excerpts through search queries when protected page indexing is disabled after previously being enabled.
In Vikunja prior to version 2.6.0, relation creation via the CalDAV endpoint fails to invoke the TaskRelation.CanCreate authorization check. This missing access control allows an authenticated user to establish unauthorized relationships and perform write operations against any task, provided its unique identifier (UID) is known.
A cross-project information disclosure vulnerability in Vikunja allows authenticated users with read access to one project to view private task details from unauthorized projects via subtask expansion parameters.