CVE-2026-15012
This vulnerability comes down to a simple but devastating architectural choice: storing authentication credentials in a publicly-served directory. The plugin in question—affecting WordPress sites—writes a `.restore_key` file and `.restore_step_token` to `wp-content/uploads/` to authenticate an unauthenticated AJAX handler that handles a multi-step restore workflow. The dot-prefix convention suggests the developer believed these would be hidden from web access, but WordPress's uploads directory is served publicly by design. That convention provides zero security. The trigger condition—an active restore must be initiated—appears to have been intended to limit exposure. The developer likely assumed the window between initiating a restore and completing it would be short. But there's no server-side timeout enforcement: nothing invalidates the key if the user abandons the workflow or simply closes their browser. An attacker monitoring the uploads directory (or running automated directory scans) can harvest these keys at leisure. Once the key is obtained, the impact is severe. The restore functionality accepts signed state envelopes, and with the harvested key, an attacker can forge these to trigger arbitrary file copies. This means wp-config.php (containing database credentials), .htaccess, nginx configurations, and ultimately the underlying server become accessible. The CVE description's 'arbitrary file copy' understates this—it's a total site compromise mechanism with a one-click trigger. The root cause is credential storage as an afterthought. File-based authentication was likely the simplest solution for maintaining state across HTTP requests for an unauthenticated user, but it created a single point of failure where file exposure equals authentication bypass. WordPress's nonce system exists precisely for this scenario—AJAX handlers can validate user-specific tokens generated server-side and transmitted via the initiating page. The developer didn't hit an architectural wall; they bypassed the documented solution. What to check: Audit any WordPress plugins handling restore, backup, or migration workflows. Verify whether they store authentication materials in `wp-content/uploads/` or any publicly-served directory. Check for dot-prefixed files in uploads that shouldn't be there. Even if this specific plugin is patched, the underlying pattern—using filesystem state as the authentication anchor for unauthenticated AJAX handlers—remains a design smell worth scanning for.
Reviewed through automated stages and approved by a human before publication.