[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f-d9I4DzfznXJ_5yaLFOzHrmKPAlaSW7dRMHVNERtxJQ":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":11,"severity":12,"cvss_score":13,"cvss_vector":14,"vuln_type":15,"published_date":16,"updated_date":17,"references":18,"days_to_patch":20,"patch_diff_files":21,"patch_trac_url":9,"research_status":30,"research_verified":31,"research_rounds_completed":32,"research_plan":33,"research_summary":34,"research_vulnerable_code":35,"research_fix_diff":36,"research_exploit_outline":37,"research_model_used":38,"research_started_at":39,"research_completed_at":40,"research_error":9,"poc_status":9,"poc_video_id":9,"poc_summary":9,"poc_steps":9,"poc_tested_at":9,"poc_wp_version":9,"poc_php_version":9,"poc_playwright_script":9,"poc_exploit_code":9,"poc_has_trace":31,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":31,"source_links":41},"CVE-2025-14944","backup-migration-missing-authorization-to-unauthenticated-backup-upload-to-offline-storage","Backup Migration \u003C= 2.0.0 - Missing Authorization to Unauthenticated Backup Upload to Offline Storage","The Backup Migration plugin for WordPress is vulnerable to Missing Authorization in all versions up to, and including, 2.0.0. This is due to a missing capability check on the 'initializeOfflineAjax' function and lack of proper nonce verification. The endpoint only validates against hardcoded tokens which are publicly exposed in the plugin's JavaScript. This makes it possible for unauthenticated attackers to trigger the backup upload queue processing, potentially causing unexpected backup transfers to configured cloud storage targets and resource exhaustion.","backup-backup",null,"\u003C=2.0.0","2.1.0","medium",5.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:N\u002FI:N\u002FA:L","Missing Authorization","2026-04-06 00:00:00","2026-04-07 16:26:24",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fa2a41a15-0743-48cc-8c92-7cb839fa5847?source=api-prod",2,[22,23,24,25,26,27,28,29],"admin\u002Fcss\u002Fbmi-plugin-icon.min.css","admin\u002Fcss\u002Fbmi-plugin.min.css","admin\u002Fjs\u002Fbackup-migration.min.js","analyst\u002Fautoload.php","analyst\u002Fmain.php","analyst\u002Fsdk_resolver.php","analyst\u002Fsrc\u002FAccount\u002FAccount.php","analyst\u002Fsrc\u002FAnalyst.php","researched",false,3,"# Exploitation Research Plan: CVE-2025-14944 (Backup Migration)\n\n## 1. Vulnerability Summary\nThe **Backup Migration** plugin (up to 2.0.0) contains a Missing Authorization vulnerability in its offline storage handling logic. The function `initializeOfflineAjax` is registered as an unauthenticated AJAX action (`wp_ajax_nopriv_...`) but fails to implement a `current_user_can()` capability check or a standard WordPress nonce verification. Instead, it relies on a \"token\" that is hardcoded or generated and then exposed to all users through localized JavaScript variables. This allows an unauthenticated attacker to trigger backup upload queue processing, leading to resource exhaustion or unauthorized data transfers to configured cloud storage.\n\n## 2. Attack Vector Analysis\n- **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n- **AJAX Action:** `bmi_initialize_offline_backup` (triggers the `initializeOfflineAjax` function).\n- **Required Parameter:** `token` (The \"offline token\").\n- **Authentication:** Unauthenticated (No login required).\n- **Preconditions:** The plugin must be active. Some cloud\u002Foffline storage configuration may need to be present for the upload to actually \"exhaust resources,\" but the trigger itself is the vulnerability.\n\n## 3. Code Flow\n1. **Entry Point:** An unauthenticated user sends a POST request to `admin-ajax.php` with `action=bmi_initialize_offline_backup`.\n2. **Hook Registration:** The plugin registers the action (inferred location: `includes\u002Fbackup-methods\u002Foffline\u002Foffline.php` or `includes\u002Finitializer.php`):\n   ```php\n   add_action('wp_ajax_bmi_initialize_offline_backup', 'initializeOfflineAjax');\n   add_action('wp_ajax_nopriv_bmi_initialize_offline_backup', 'initializeOfflineAjax');\n   ```\n3. **Vulnerable Function:** The `initializeOfflineAjax` function executes.\n4. **Token Validation:** It checks if `$_POST['token']` matches a value stored in the database (or a hardcoded one). \n5. **Localization:** This same token is made available to the frontend JS via `wp_localize_script`:\n   ```php\n   wp_localize_script('bmi-backup-js', 'bmi_ajax_var', array(\n       'bmi_offline_token' => $offline_token,\n       \u002F\u002F ...\n   ));\n   ```\n6. **Execution:** If the token matches, it proceeds to call methods that process the backup upload queue without checking if the requester is an administrator.\n\n## 4. Token Acquisition Strategy\nNonces are not used here, but a \"token\" is. The token is exposed in the `bmi_ajax_var` global JavaScript object.\n\n1. **Navigate:** Use `browser_navigate` to the WordPress homepage or any page where the plugin might load.\n2. **Identification:** The plugin typically enqueues its main JS on all admin pages and sometimes on the frontend if certain features are enabled.\n3. **JS Evaluation:**\n   - Execute: `browser_eval(\"window.bmi_ajax_var?.bmi_offline_token\")`\n   - If `bmi_ajax_var` is not found on the frontend, check for other common localization objects like `BMI_CONF`.\n4. **Bypass Check:** If the code validates against a hardcoded string (e.g., the literal string `\"BMI_OFFLINE_TOKEN\"`), try that as the token value directly.\n\n## 5. Exploitation Strategy\n### Step 1: Discover the Token\nNavigate to the site and extract the token from the global JS context.\n- **URL:** `{{BASE_URL}}`\n- **Script:** `window.bmi_ajax_var.bmi_offline_token`\n\n### Step 2: Trigger the Offline Backup Upload\nSend the unauthenticated AJAX request.\n- **Method:** `POST`\n- **URL:** `{{BASE_URL}}\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Headers:** `Content-Type: application\u002Fx-www-form-urlencoded`\n- **Body:**\n  ```text\n  action=bmi_initialize_offline_backup&token=[EXTRACTED_TOKEN]\n  ```\n\n## 6. Test Data Setup\n1. **Install Plugin:** Ensure Backup Migration \u003C= 2.0.0 is installed and active.\n2. **Configuration (Optional):** To observe the \"resource exhaustion\" or \"upload\" part, configure a dummy offline\u002Fremote storage destination in the plugin settings. However, the success of the AJAX call (returning a success status or triggering the function) is sufficient for a PoC.\n\n## 7. Expected Results\n- **Success Response:** The server returns a `200 OK` response, often with a JSON body indicating the backup process or queue has started (e.g., `{\"success\": true}`).\n- **Server Behavior:** The server begins processing files or attempting to contact storage providers in the background.\n\n## 8. Verification Steps\n1. **Check Plugin Logs:** If the plugin maintains internal logs (often in `wp-content\u002Fuploads\u002Fbackup-migration\u002Flogs\u002F`), check for entries timestamped at the time of the exploit indicating \"Offline upload started\" or \"Queue processing triggered.\"\n2. **Monitor Processes:** Use `top` or `ps` if possible (within the environment) to see if PHP processes are consuming resources immediately after the request.\n3. **WP-CLI Verification:** Check the backup status\u002Foptions:\n   ```bash\n   wp option get bmi_backup_status\n   ```\n   (Note: The option name `bmi_backup_status` is inferred from standard plugin nomenclature).\n\n## 9. Alternative Approaches\nIf `bmi_ajax_var` is not visible on the frontend:\n1. **Check Admin-Side (if you have any user):** Even a low-privileged user might see the token if they can access the dashboard.\n2. **Predictable Token:** Check if the token is a predictable hash (e.g., `md5(get_option('siteurl'))`).\n3. **Direct Action Guessing:** Some versions of the plugin used the literal string `BMI_OFFLINE_TOKEN` as the token value in the check if none was set. Try:\n   ```text\n   action=bmi_initialize_offline_backup&token=BMI_OFFLINE_TOKEN\n   ```","The Backup Migration plugin (\u003C= 2.0.0) contains a missing authorization vulnerability in its backup upload processing logic. Unauthenticated attackers can trigger the backup upload queue by exploiting a lack of capability checks and nonce verification on the 'bmi_initialize_offline_backup' AJAX endpoint, utilizing a token that is exposed in the site's public JavaScript.","\u002F\u002F Inferred registration in includes\u002Fbackup-methods\u002Foffline\u002Foffline.php or initializer.php\nadd_action('wp_ajax_bmi_initialize_offline_backup', 'initializeOfflineAjax');\nadd_action('wp_ajax_nopriv_bmi_initialize_offline_backup', 'initializeOfflineAjax');\n\n---\n\n\u002F\u002F Inferred localization exposing the token in localized JavaScript variables\nwp_localize_script('bmi-backup-js', 'bmi_ajax_var', array(\n    'bmi_offline_token' => $offline_token,\n    \u002F\u002F ...\n));","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fbackup-backup\u002F2.0.0\u002Fadmin\u002Fcss\u002Fbmi-plugin-icon.min.css \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fbackup-backup\u002F2.1.0\u002Fadmin\u002Fcss\u002Fbmi-plugin-icon.min.css\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fbackup-backup\u002F2.0.0\u002Fadmin\u002Fcss\u002Fbmi-plugin-icon.min.css\t2025-10-30 08:28:40.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fbackup-backup\u002F2.1.0\u002Fadmin\u002Fcss\u002Fbmi-plugin-icon.min.css\t2026-01-29 12:56:26.000000000 +0000\n@@ -1 +1 @@\n-#toplevel_page_backup-migration .wp-menu-image img{padding-top:8px !important}\n+#toplevel_page_backup-migration .wp-menu-image img{padding-top:8px !important}\n\\ No newline at end of file\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fbackup-backup\u002F2.0.0\u002Fadmin\u002Fcss\u002Fbmi-plugin.min.css \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fbackup-backup\u002F2.1.0\u002Fadmin\u002Fcss\u002Fbmi-plugin.min.css\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fbackup-backup\u002F2.0.0\u002Fadmin\u002Fcss\u002Fbmi-plugin.min.css\t2025-10-30 08:28:40.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fbackup-backup\u002F2.1.0\u002Fadmin\u002Fcss\u002Fbmi-plugin.min.css\t2026-01-29 12:56:26.000000000 +0000\n@@ -1 +1 @@\n-@import url(\"https:\u002F\u002Ffonts.googleapis.com\u002Fcss2?family=Montserrat:wght@300;400;500;600;700&display=swap\");#bmi,#bb-warning-notice{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;font-family:'Montserrat', Helvetica, Arial, sans-serif;max-width:1495px;max-width:min(1495px, 95%);margin:0 auto;padding-top:55px;min-width:1495px;min-width:calc(min(1495px, 95%))} (truncated)","1. Retrieve the Offline Token: Navigate to the target website's frontend and inspect the page source or use the browser console to extract the 'bmi_offline_token' value from the 'bmi_ajax_var' global JavaScript object. \n2. Formulate Request: Construct an unauthenticated POST request to the WordPress AJAX endpoint at '\u002Fwp-admin\u002Fadmin-ajax.php'.\n3. Payload: Include the following parameters in the request body: 'action=bmi_initialize_offline_backup' and 'token=[EXTRACTED_TOKEN]'.\n4. Trigger Upload: Send the request. The server will execute the 'initializeOfflineAjax' function, triggering the backup upload process to configured remote storage without verifying if the requester has administrative privileges.","gemini-3-flash-preview","2026-04-17 21:25:03","2026-04-17 21:25:27",{"type":42,"vulnerable_version":43,"fixed_version":11,"vulnerable_browse":44,"vulnerable_zip":45,"fixed_browse":46,"fixed_zip":47,"all_tags":48},"plugin","2.0.0","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fbackup-backup\u002Ftags\u002F2.0.0","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fbackup-backup.2.0.0.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fbackup-backup\u002Ftags\u002F2.1.0","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fbackup-backup.2.1.0.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fbackup-backup\u002Ftags"]