Full Report
PHP is full of security footguns. Many of them have been fixed, such as 'abc' == 0. However, there are some that still remain. In the case of Craft CMS, a popular PHP based CMS, there are still some footguns lurking. PHP can be used both on the command line and as a web server. So, the global variables $_SERVER['argc'] and $_SERVER['argv']. If you run this as a web server then PHP will take argv from the query string, if you have enabled this! In the case of PHP, this functionality was on in the default Docker container. In the case of Craft CMS, there is some code that runs for parsing CLI functions. If the argv entry is empty, then it skips this though. Normally from a website, this would it would be empty. Like many programs, there is a lot of option processing when running the application. Here's the crazy bug though: since $_SERVER['argv'] can be controlled from web! This allows an attacker to control the configurations of the running website. For example, --configPath=/aaa will set the configuration path to a non-existent location, remotely. At this point, the vulnerability feels like than RCE but the path needs to be found. They tried some easy wins but no dice. The path that looked interesting was a request to get a file remotely. If a PHP file could be included then this would mean RCE. However, there was a file_exists check before this that prevented using HTTP, PHP or other many other types of files. Upon further inspection, the ftp:// URI supports file existence checks. Using a file here is blocked by the allow_url_include security feature. But, a template CAN be included! So, they created an FTP server with anonymous access and a file called index.twig with {{7*7}} in it. When craft loads the file, it gets evaluated! Craft CMS attempts to sandbox the Twig template renderer. So, simple calls to system are denied. They found that using {{ ['system', 'id'] | sort('call_user_func') }} bypassed the verification, which I don't really understand how it works. Understanding esoteric portions of languages and frameworks can be useful but it's hard to see the payoff until something like this happens sometimes. Great find!
Analysis Summary
# Vulnerability: Unauthenticated Remote Code Execution in Craft CMS via register_argc_argv
## CVE Details
- **CVE ID**: CVE-2024-56145
- **CVSS Score**: Not explicitly listed in source, but typically 9.8 (Critical) for unauthenticated RCE.
- **CWE**: CWE-470 (Use of Externally-Controlled Input to Select Classes or Code) / CWE-94 (Code Injection)
## Affected Systems
- **Products**: Craft CMS
- **Versions**:
- Craft 5.x versions prior to 5.5.2
- Craft 4.x versions prior to 4.13.2
- **Configurations**: PHP environments where `register_argc_argv` is enabled (default in many PHP Docker containers and command-line configurations).
## Vulnerability Description
The vulnerability stems from a PHP "footgun" where the global `$_SERVER['argv']` variable is populated from URL query strings when `register_argc_argv` is set to `On`.
Craft CMS uses `bootstrap/bootstrap.php` to handle both web and CLI requests. It checks for CLI arguments (like `--configPath` or `--vendorPath`) to set internal system paths. Because PHP populates these arguments from the query string in certain configurations, an unauthenticated remote attacker can pass command-line options via a web request. By overriding the configuration path to a remote or malicious location (e.g., via the `ftp://` protocol), an attacker can bypass traditional `file_exists` checks and trigger the inclusion of a malicious Twig template.
## Exploitation
- **Status**: PoC available/Exploited by researchers (publicly documented).
- **Complexity**: Medium (requires bypassing the Twig sandbox and finding a protocol that satisfies `file_exists`).
- **Attack Vector**: Network
## Impact
- **Confidentiality**: High (Full access to application data and server files).
- **Integrity**: High (Full control over application logic and data).
- **Availability**: High (Ability to disrupt service or delete files).
## Remediation
### Patches
- **Craft CMS 5**: Upgrade to version **5.5.2** or higher.
- **Craft CMS 4**: Upgrade to version **4.13.2** or higher.
### Workarounds
- Disable the dangerous PHP directive in your `php.ini` file:
`register_argc_argv = Off`
- Ensure PHP is not running in a mode that treats web query strings as CLI arguments.
## Detection
- **Indicators of Compromise**:
- Web server logs showing query strings containing CLI-style arguments (e.g., `?--configPath=`, `?--vendorPath=`, `?--basePath=`).
- Unusual outbound FTP traffic from the web server.
- **Detection methods**: Monitor for `+` symbols in query strings used as argument separators (e.g., `index.php?--option+value`).
## References
- Vendor Advisory: [https://github.com/craftcms/cms/security/advisories/GHSA-2p6p-9rc9-62j9]
- Assetnote Research: [https://www.assetnote.io/resources/research/how-an-obscure-php-footgun-led-to-rce-in-craft-cms]