CVE-2026-14490 Overview
CVE-2026-14490 is an arbitrary directory deletion vulnerability in the Demi – One Click Demo Import, WP Backup & Site Migration plugin for WordPress. The flaw affects all versions up to and including 0.0.7. An unauthenticated attacker can retrieve an exposed HMAC signing key stored as a dotfile in a publicly accessible uploads subdirectory. With the key, the attacker forges a signed state envelope, invokes the demi_restore_step AJAX handler, and triggers CleanDir::execute() against an arbitrary absolute path. The vulnerability maps to CWE-22 (path traversal) and enables recursive deletion of any directory the WordPress process can access.
Critical Impact
Unauthenticated attackers can recursively delete arbitrary server directories, destroying WordPress installations and adjacent files.
Affected Products
- Demi – One Click Demo Import, WP Backup & Site Migration plugin for WordPress
- All versions through 0.0.7
- WordPress sites exposing the plugin's uploads subdirectory to the public
Discovery Timeline
- 2026-07-28 - CVE-2026-14490 published to NVD
- 2026-07-28 - Last updated in NVD database
Technical Details for CVE-2026-14490
Vulnerability Analysis
The Demi backup and migration plugin implements a multi-step restore workflow that persists cryptographic state between AJAX requests. The plugin writes an HMAC signing key and per-step restore tokens to dotfiles inside a subdirectory of the WordPress uploads folder. That directory ships without an .htaccess deny rule or an index.php guard, so a remote client can request the dotfiles directly over HTTP.
The demi_restore_step AJAX handler registers under wp_ajax_nopriv_, exposing it to unauthenticated callers. The handler treats possession of the on-disk signing key as an authentication primitive equivalent to a valid WordPress capability check and nonce. Once an attacker fetches the key, they can generate a signed state envelope that the handler accepts as trusted input.
Inside the envelope, the target path travels to CleanDir::execute() without allow-list validation or path canonicalization. The plugin passes the caller-supplied absolute path straight into a recursive delete routine. Any directory readable and writable by the PHP worker process becomes a deletion target, including wp-content, wp-admin, or arbitrary paths outside the web root.
Root Cause
The root cause combines two design defects. First, secret material is stored under a web-served directory without access controls. Second, an unauthenticated endpoint accepts a self-issued signature as a substitute for framework-level authorization.
Attack Vector
An attacker issues an HTTP GET request to retrieve the exposed HMAC dotfile from the uploads subdirectory. The attacker then constructs a signed payload naming an arbitrary absolute path and POSTs it to admin-ajax.php with action=demi_restore_step. The handler verifies the signature against the leaked key, accepts the envelope, and invokes CleanDir::execute() on the target path.
The vulnerability requires no authentication, no user interaction, and no local access. Refer to the Wordfence Vulnerability Report and the plugin source in the WordPress Plugin Repository for the affected code paths.
Detection Methods for CVE-2026-14490
Indicators of Compromise
- HTTP GET requests targeting dotfiles inside wp-content/uploads/ subdirectories associated with the demi-backup-migration plugin.
- POST requests to /wp-admin/admin-ajax.php with the parameter action=demi_restore_step originating from unauthenticated sessions.
- Missing or truncated directories under wp-content, wp-includes, or adjacent filesystem locations without a corresponding administrative action.
- Web server error spikes referencing missing WordPress core or theme files after suspicious AJAX traffic.
Detection Strategies
- Alert on any external HTTP request that successfully retrieves a hidden file (leading dot) from within the WordPress uploads directory.
- Inspect admin-ajax.php traffic for the demi_restore_step action from clients without a valid wordpress_logged_in_* cookie.
- Correlate filesystem deletion events on the web server host with preceding requests to the plugin's AJAX endpoint.
Monitoring Recommendations
- Enable file integrity monitoring on wp-content, wp-includes, and the WordPress document root to detect recursive deletions.
- Log and retain full web server access logs to reconstruct the two-stage retrieval-and-forge sequence.
- Forward WordPress and web server telemetry to a centralized analytics platform for cross-request correlation.
How to Mitigate CVE-2026-14490
Immediate Actions Required
- Deactivate and remove the Demi – One Click Demo Import, WP Backup & Site Migration plugin until a patched release is confirmed installed.
- Rotate any secrets, database credentials, and API keys that may have been staged on the affected host.
- Restore missing directories from a known-good backup and verify WordPress core file integrity.
- Block direct HTTP access to hidden files inside the WordPress uploads directory at the web server or WAF layer.
Patch Information
Review the plugin changeset details in the WordPress Plugin Repository for remediation status. Upgrade beyond version 0.0.7 once a fixed release is published by the vendor. Track the Wordfence advisory for confirmation of a patched version.
Workarounds
- Place an .htaccess rule (or equivalent nginx location block) that denies HTTP access to dotfiles across the entire wp-content/uploads/ tree.
- Restrict access to admin-ajax.php actions matching demi_restore_* at the WAF layer until the plugin is removed or patched.
- Enforce filesystem permissions that prevent the PHP worker from deleting files outside the WordPress document root.
# Apache configuration example: block dotfile retrieval under uploads
<DirectoryMatch "^.*/wp-content/uploads/">
<FilesMatch "^\.">
Require all denied
</FilesMatch>
</DirectoryMatch>
# WAF rule concept: deny unauthenticated demi_restore_step
# if request.uri contains "admin-ajax.php"
# and request.body contains "action=demi_restore_step"
# and not request.cookies matches "wordpress_logged_in_"
# then block
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

