Every CVE Search/ Get API key

CVE-2026-55885

Grav: Admin Backup Zip File Exposes Account Credentials and Configuration Secrets

6.8 MediumFix available

Grav is a file-based Web platform. Prior to 1.7.53, an authenticated administrator with backup permissions can download a ZIP archive containing the full Grav installation root, including user/accounts/admin.yaml with the administrator password hash and user/config with site configuration, through the backup download endpoint protected only by the session-static admin-nonce URL parameter. This issue is reported as fixed in version 1.7.53.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
High
User interaction
None

What an attacker can affect

Confidentiality
High
Integrity
None
Availability
None

Exploit likelihood

0.21%Unchanged since Jul 11, 2026
90%50%10%1%

What each source reports

CVE List Score used 6.8

Grav: Admin Backup Zip File Exposes Account Credentials and Configuration Secrets

Grav is a file-based Web platform. Prior to 1.7.53, an authenticated administrator with backup permissions can download a ZIP archive containing the full Grav installation root, including user/accounts/admin.yaml with the administrator password hash and user/config with site configuration, through the backup download endpoint protected only by the session-static admin-nonce URL parameter. This issue is reported as fixed in version 1.7.53.

Record
CVE-2026-55885
CVSS 3.1
6.8 MediumCVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:N/A:N
Weakness
CWE-312, CWE-522
Updated
2026-11-02
EUVDEUVD-2026-42944 6.8

Grav is a file-based Web platform. Prior to 1.7.53, an authenticated administrator with backup permissions can download a ZIP archive containing the full Grav installation root, including user/accounts/admin.yaml with the administrator password hash and user/config with site configuration, through the backup download endpoint protected only by the session-static admin-nonce URL parameter. This issue is reported as fixed in version 1.7.53.

Record
EUVD-2026-42944
CVSS 3.1
6.8 MediumCVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:N/A:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-2f86-9cp8-6hcf 6.8

Grav: Admin Backup Zip File Exposes Account Credentials and Configuration Secrets

Summary

An authenticated administrator with backup permissions can download a ZIP archive containing the full Grav installation root, including user/accounts/admin.yaml with the admin's bcrypt password hash and email, plus user/config/ with all site configuration. The download endpoint requires only the session-static admin-nonce in the URL, no additional form-level CSRF token, and reveals the server's full filesystem path in a Base64-encoded query parameter. Combined with the absence of login rate limiting on http://{Grav_URL}/admin, an attacker who obtains a single admin-nonce value (via Referrer leakage, browser history, or XSS) can exfiltrate password hashes for offline cracking and achieve account takeover.

Details

The vulnerability chain spans three components in the deployed Grav source tree at /var/www/html/grav/:

1. Backup archive scope — Backups::backup()
/var/www/html/grav/system/src/Grav/Common/Backup/Backups.php:201-272

The backup() static method creates a ZIP of the directory specified by the backup profile's root property. The default profile (ID 0, named default_site_backup) backs up the entire Grav root directory. On line 225, when the root is not a stream URI, it falls back to the full installation path:

// Backups.php:225
$backup_root = rtrim(GRAV_ROOT . $backup->root, DS) ?: DS;

Since the default profile ships with no root override, $backup->root is empty, making $backup_root equal to GRAV_ROOT — i.e. /var/www/html/grav/. The archive therefore captures the entire installation including:

  • /var/www/html/grav/user/accounts/ — admin password hash, email, full name, granular permissions
  • /var/www/html/grav/user/config/ — system settings, potentially email SMTP credentials

The exclude_files and exclude_paths options on lines 232-235 are empty by default and offer no protection against including account files.

2. Backup download handler — AdminController::taskBackup()
/var/www/html/grav/user/plugins/admin/classes/plugin/AdminController.php:517-573

After creating the backup ZIP, the controller Base64-encodes the full filesystem path and embeds it directly in a download URL displayed to the admin:

// AdminController.php:558-560
$download = urlencode(base64_encode($backup));
$url = rtrim(...) . '/task' . $param_sep . 'backup/download' . $param_sep
       . $download . '/admin-nonce' . $param_sep . Utils::getNonce('admin-form');

The download handler (lines 532-541) decodes the path, locates the file via the backup:// stream, and serves it with Utils::download($file, true). It performs only two checks: the filename must end in .zip and the file must actually exist. It does not verify the file belongs to the requesting user, does not enforce a form-level nonce, and does not tie the download to a specific session.

3. Nonce validation — permissive
The backup route is protected only by the admin-nonce parameter appended to the URL path. This nonce is session-static and shared across every admin page. No form-nonce is required — unlike page saves or configuration changes which demand both admin-nonce and form-nonce. This makes the backup download exploitable via a single crafted GET request from any attacker who knows the nonce value.

PoC

Prerequisites: Admin session with valid admin-nonce.

Step 1 — Authenticate and extract the session-static nonces:

# Get login page, extract login-nonce, authenticate
NONCE=$(curl -s -c /tmp/jar "http://127.0.0.1/grav/admin" \
  | grep -oP 'name="login-nonce" value="\K[^"]+')
curl -s -b /tmp/jar -c /tmp/jar -X POST "http://127.0.0.1/grav/admin" \
  --data-urlencode "data[username]=admin" \
  --data-urlencode "data[password]=Passw0rd123!" \
  --data-urlencode "task=login" \
  --data-urlencode "login-nonce=${NONCE}"

# Extract the admin-nonce (same value on every admin page)
ADMIN_NONCE=$(curl -s -b /tmp/jar…
Record
GHSA-2f86-9cp8-6hcf
CVSS 3.1
6.8 MediumCVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:N/A:N
Weakness
CWE-312, CWE-522
Updated
2026-11-02
NVD 6.8

Grav is a file-based Web platform. Prior to 1.7.53, an authenticated administrator with backup permissions can download a ZIP archive containing the full Grav installation root, including user/accounts/admin.yaml with the administrator password hash and user/config with site configuration, through the backup download endpoint protected only by the session-static admin-nonce URL parameter. This issue is reported as fixed in version 1.7.53.

Record
CVE-2026-55885
CVSS 3.1
6.8 MediumCVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:N/A:N
Weakness
CWE-312, CWE-522
Updated
2026-11-02
OSV 6.8

Grav: Admin Backup Zip File Exposes Account Credentials and Configuration Secrets

Grav is a file-based Web platform. Prior to 1.7.53, an authenticated administrator with backup permissions can download a ZIP archive containing the full Grav installation root, including user/accounts/admin.yaml with the administrator password hash and user/config with site configuration, through the backup download endpoint protected only by the session-static admin-nonce URL parameter. This issue is reported as fixed in version 1.7.53.

Record
CVE-2026-55885
CVSS 3.1
6.8 MediumCVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:N/A:N
Weakness
CWE-312, CWE-522
Updated
2026-11-02
OSVGHSA-2f86-9cp8-6hcf 6.8

Grav: Admin Backup Zip File Exposes Account Credentials and Configuration Secrets

Summary

An authenticated administrator with backup permissions can download a ZIP archive containing the full Grav installation root, including user/accounts/admin.yaml with the admin's bcrypt password hash and email, plus user/config/ with all site configuration. The download endpoint requires only the session-static admin-nonce in the URL, no additional form-level CSRF token, and reveals the server's full filesystem path in a Base64-encoded query parameter. Combined with the absence of login rate limiting on http://{Grav_URL}/admin, an attacker who obtains a single admin-nonce value (via Referrer leakage, browser history, or XSS) can exfiltrate password hashes for offline cracking and achieve account takeover.

Details

The vulnerability chain spans three components in the deployed Grav source tree at /var/www/html/grav/:

1. Backup archive scope — Backups::backup()
/var/www/html/grav/system/src/Grav/Common/Backup/Backups.php:201-272

The backup() static method creates a ZIP of the directory specified by the backup profile's root property. The default profile (ID 0, named default_site_backup) backs up the entire Grav root directory. On line 225, when the root is not a stream URI, it falls back to the full installation path:

// Backups.php:225
$backup_root = rtrim(GRAV_ROOT . $backup->root, DS) ?: DS;

Since the default profile ships with no root override, $backup->root is empty, making $backup_root equal to GRAV_ROOT — i.e. /var/www/html/grav/. The archive therefore captures the entire installation including:

  • /var/www/html/grav/user/accounts/ — admin password hash, email, full name, granular permissions
  • /var/www/html/grav/user/config/ — system settings, potentially email SMTP credentials

The exclude_files and exclude_paths options on lines 232-235 are empty by default and offer no protection against including account files.

2. Backup download handler — AdminController::taskBackup()
/var/www/html/grav/user/plugins/admin/classes/plugin/AdminController.php:517-573

After creating the backup ZIP, the controller Base64-encodes the full filesystem path and embeds it directly in a download URL displayed to the admin:

// AdminController.php:558-560
$download = urlencode(base64_encode($backup));
$url = rtrim(...) . '/task' . $param_sep . 'backup/download' . $param_sep
       . $download . '/admin-nonce' . $param_sep . Utils::getNonce('admin-form');

The download handler (lines 532-541) decodes the path, locates the file via the backup:// stream, and serves it with Utils::download($file, true). It performs only two checks: the filename must end in .zip and the file must actually exist. It does not verify the file belongs to the requesting user, does not enforce a form-level nonce, and does not tie the download to a specific session.

3. Nonce validation — permissive
The backup route is protected only by the admin-nonce parameter appended to the URL path. This nonce is session-static and shared across every admin page. No form-nonce is required — unlike page saves or configuration changes which demand both admin-nonce and form-nonce. This makes the backup download exploitable via a single crafted GET request from any attacker who knows the nonce value.

PoC

Prerequisites: Admin session with valid admin-nonce.

Step 1 — Authenticate and extract the session-static nonces:

# Get login page, extract login-nonce, authenticate
NONCE=$(curl -s -c /tmp/jar "http://127.0.0.1/grav/admin" \
  | grep -oP 'name="login-nonce" value="\K[^"]+')
curl -s -b /tmp/jar -c /tmp/jar -X POST "http://127.0.0.1/grav/admin" \
  --data-urlencode "data[username]=admin" \
  --data-urlencode "data[password]=Passw0rd123!" \
  --data-urlencode "task=login" \
  --data-urlencode "login-nonce=${NONCE}"

# Extract the admin-nonce (same value on every admin page)
ADMIN_NONCE=$(curl -s -b /tmp/jar…
Record
GHSA-2f86-9cp8-6hcf
CVSS 3.1
6.8 MediumCVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:N/A:N
Weakness
CWE-312, CWE-522
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
getgrav/grav
Packagist
before 1.7.53
1.7.53
getgrav/grav
Packagist
before 1.7.53, plus listed versions
0.8.00.9.00.9.10.9.100.9.11
Show 45 moreShow less
0.9.120.9.130.9.140.9.150.9.160.9.170.9.180.9.190.9.20.9.200.9.210.9.220.9.230.9.240.9.250.9.260.9.270.9.280.9.290.9.30.9.300.9.310.9.320.9.330.9.340.9.350.9.360.9.370.9.380.9.390.9.40.9.400.9.410.9.420.9.430.9.440.9.450.9.50.9.60.9.70.9.80.9.91.0.01.0.0-rc.11.0.0-rc.2
1.7.53

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-55885 is a medium vulnerability (CVSS 6.8) in Getgrav Grav, published June 18, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.21%, the 12th percentile. Fixed in getgrav/grav 1.7.53.

References

This page doesn't list everything

Left out here: 237 versions and the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open