[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fyyeR8N6oqpvlZc9ULrKqXs67Kn8XtCPGyFrLDqIacyE":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":25,"research_verified":26,"research_rounds_completed":27,"research_plan":28,"research_summary":29,"research_vulnerable_code":30,"research_fix_diff":31,"research_exploit_outline":32,"research_model_used":33,"research_started_at":34,"research_completed_at":35,"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":26,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":26,"source_links":36},"CVE-2026-8996","backup-and-staging-by-wp-time-capsule-missing-authorization-to-authenticated-subscriber-sensitive-information-exposure-v","Backup and Staging by WP Time Capsule \u003C= 1.22.26 - Missing Authorization to Authenticated (Subscriber+) Sensitive Information Exposure via download_recent_decrypted_file_wptc Function","The Backup and Staging by WP Time Capsule plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 1.22.26 via the download_recent_decrypted_file_wptc. This makes it possible for authenticated attackers, with subscriber-level access and above, to extract download the most recently admin-decrypted SQL database backup, which typically contains password hashes, user credentials, and other sensitive site configuration data stored in the 'recent_decrypted_file' option. Exploitation requires that an administrator has previously performed a decrypt action, causing the decrypted SQL backup file to exist in the plugin's upload directory; without this prior admin action, there is no file to serve.","wp-time-capsule",null,"\u003C=1.22.26","1.22.27","medium",6.5,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:H\u002FI:N\u002FA:N","Missing Authorization","2026-07-08 17:48:06","2026-07-09 06:52:51",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Ff7c39d66-f1e1-4d41-a9e4-984aec3f37dc?source=api-prod",1,[22,23,24],"readme.txt","wp-time-capsule.php","wptc-constants.php","researched",false,3,"# Exploitation Research Plan: CVE-2026-8996\n\n## 1. Vulnerability Summary\nThe **Backup and Staging by WP Time Capsule** plugin (up to version 1.22.26) is vulnerable to **Sensitive Information Exposure**. The plugin implements an AJAX handler `download_recent_decrypted_file_wptc` which is intended to allow administrators to download SQL database backups after they have been decrypted for restoration or cloning. However, the function fails to perform adequate authorization checks (e.g., `current_user_can('manage_options')`). Consequently, any authenticated user with Subscriber-level permissions or higher can trigger this function to download the most recently decrypted SQL backup, which contains sensitive information including WordPress user password hashes, site configuration, and database structure.\n\n## 2. Attack Vector Analysis\n*   **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Action:** `download_recent_decrypted_file_wptc`\n*   **Method:** `GET` or `POST` (WordPress AJAX handlers typically support both, but the name implies a download\u002FGET context).\n*   **Authentication:** Authenticated (Subscriber-level or higher).\n*   **Vulnerable Parameter:** The `action` parameter triggers the code; the file path is retrieved internally from the database option `recent_decrypted_file`.\n*   **Precondition:** An administrator must have previously used the \"Decrypt\" feature on an encrypted database backup. This action populates the `recent_decrypted_file` option and ensures the decrypted file exists in the plugin's temporary storage directory.\n\n## 3. Code Flow\n1.  **Entry Point:** The request is sent to `admin-ajax.php` with `action=download_recent_decrypted_file_wptc`.\n2.  **Hook Registration:** The plugin registers the action (likely in `Classes\u002FWptcBackup\u002FHooksHandler.php` or `Classes\u002FCommon\u002FHooksHandler.php` - *inferred*):\n    `add_action('wp_ajax_download_recent_decrypted_file_wptc', 'download_recent_decrypted_file_wptc');`\n3.  **Vulnerable Function Execution:** The function `download_recent_decrypted_file_wptc` is called.\n4.  **Option Retrieval:** The code calls `get_option('recent_decrypted_file')` to retrieve the absolute path of the most recently decrypted SQL file.\n5.  **Information Exposure (Sink):** The function uses `readfile()` or similar file output functions to send the contents of the SQL file to the user's browser without checking if the current user has the `manage_options` capability.\n\n## 4. Nonce Acquisition Strategy\nThe WP Time Capsule plugin typically localizes its AJAX settings and nonces into a JavaScript object. To find the correct nonce:\n\n1.  **Identify Script Localization:** The plugin usually enqueues scripts on its admin pages. We can find the nonce by creating a page that loads the plugin context or by accessing a default admin dashboard as a subscriber (where some WPTC scripts may still load).\n2.  **Create Trigger Content:** If the script only loads on specific pages, we can use WP-CLI to create a page with a WPTC-related shortcode if any exist (e.g., `[wptc_test]`).\n3.  **Browser Extraction:**\n    *   Navigate to the WordPress dashboard (`\u002Fwp-admin\u002Findex.php`) as a Subscriber.\n    *   Use `browser_eval` to search for the WPTC AJAX object.\n    *   **Common Variable Name:** `window.wptc_ajax_object` (inferred from common plugin patterns).\n    *   **Common Nonce Key:** `window.wptc_ajax_object.nonce`.\n4.  **Check for Nonce Enforcement:** If `download_recent_decrypted_file_wptc` was designed for direct file download, it might lack a nonce check entirely, as the primary vulnerability is the missing authorization.\n\n## 5. Exploitation Strategy\n1.  **Pre-Exploit Setup (Internal Site):** As an admin, run a backup and use the \"Decrypt DB\" feature to ensure the `recent_decrypted_file` option is set.\n2.  **Authentication:** Obtain session cookies for a user with `Subscriber` role.\n3.  **Discovery:** Retrieve the nonce if required (see Section 4).\n4.  **Execution:** Use the `http_request` tool to perform a GET request to the AJAX endpoint.\n    *   **URL:** `https:\u002F\u002F[target]\u002Fwp-admin\u002Fadmin-ajax.php?action=download_recent_decrypted_file_wptc`\n    *   **Headers:** Include `Cookie: [subscriber_cookies]`\n5.  **Payload Extraction:** If successful, the response body will contain a raw SQL dump of the WordPress database.\n\n## 6. Test Data Setup\nTo verify the vulnerability, the environment must be prepared:\n1.  **Install Plugin:** Install version 1.22.26 of Backup and Staging by WP Time Capsule.\n2.  **Create Users:**\n    *   Admin: `admin_user` \u002F `password`\n    *   Subscriber: `attacker_sub` \u002F `password`\n3.  **Configure Plugin:** As Admin, connect a cloud storage (or use local\u002Fstaging mode) and perform at least one backup with **Database Encryption** enabled.\n4.  **Trigger Decryption:** In the WPTC dashboard, find the database backup and select the \"Decrypt\" option. This will place a file in `wp-content\u002Fuploads\u002FtCapsule\u002Fbackups\u002F...\u002Ffilename.sql`.\n5.  **Confirm Option:** Use WP-CLI to verify the path is stored:\n    `wp option get recent_decrypted_file`\n\n## 7. Expected Results\n*   **Successful Exploitation:** The `http_request` returns a `200 OK` status, and the response body begins with SQL dump headers (e.g., `INSERT INTO wp_users ...` or `-- WordPress MySQL dump`).\n*   **Failed Exploitation (Patched):** The response is `403 Forbidden` or `0` (WordPress default for unauthorized AJAX).\n\n## 8. Verification Steps\nAfter the HTTP request, confirm the data is valid:\n1.  **Inspect Response:** Check the response body for the string `wp_users`.\n2.  **Check for Password Hashes:** Verify that the output contains the password hash of the admin user (e.g., strings starting with `$P$B`).\n3.  **WP-CLI Verification:** Confirm the file downloaded matches the one stored in the path found via `wp option get recent_decrypted_file`.\n\n## 9. Alternative Approaches\n*   **Path Traversal Check:** If the function accepts a filename parameter (e.g., `?file=...`), check if it's vulnerable to path traversal (e.g., `..\u002F..\u002F..\u002F..\u002Fwp-config.php`). Based on the CVE, the path is likely hardcoded to the option value, but this should be checked.\n*   **Direct Access:** Check if the decrypted file path (retrieved from the option via WP-CLI for testing) is directly accessible via a URL (e.g., `https:\u002F\u002F[target]\u002Fwp-content\u002Fuploads\u002FtCapsule\u002Fbackups\u002F...\u002Fdump.sql`). The plugin should ideally use an `.htaccess` or `index.html` to block this, but the AJAX handler provides a direct bypass.","The Backup and Staging by WP Time Capsule plugin for WordPress is vulnerable to Sensitive Information Exposure via the `download_recent_decrypted_file_wptc` function. Due to missing authorization and nonce checks, authenticated attackers with subscriber-level access or higher can download the site's most recently decrypted SQL database backup, provided an administrator has recently performed a decryption action.","\u002F\u002F wp-time-capsule.php L3767\nfunction download_recent_decrypted_file_wptc(){\n\tif ( !is_admin() ) {\n\t\treturn ;\n\t}\n\n\t$wptc_file_path = WPTC_Factory::get('config')->get_option('recent_decrypted_file');\n\n\twptc_log($wptc_file_path,'-----------$wptc_file_path----------------');","--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwp-time-capsule\u002F1.22.26\u002Fwp-time-capsule.php\t2026-05-07 05:18:24.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwp-time-capsule\u002F1.22.27\u002Fwp-time-capsule.php\t2026-06-10 05:33:14.000000000 +0000\n@@ -3687,7 +3687,9 @@\n \n \tWPTC_Factory::get('config')->set_option('recent_decrypted_file', $result['fullpath']);\n \n-\t$result['message'] = \"Decryption Completed. \u003Ca href=\" . network_admin_url() . \"?page=wp-time-capsule-settings&download=1#wp-time-capsule-tab-advanced>Download your file here\u003C\u002Fa>. After downloaded \u003Ca href='#' id='wptc-clear-all-decrypt-files'>click here\u003C\u002Fa> to delete the file for security reason.\";\n+\t$wptc_download_decrypt_nonce = wp_create_nonce( 'download_decrypt' );\n+\n+\t$result['message'] = \"Decryption Completed. \u003Ca href=\" . network_admin_url() . \"?page=wp-time-capsule-settings&download=1&wptc_download_decrypt_nonce=\" . $wptc_download_decrypt_nonce . \"#wp-time-capsule-tab-advanced>Download your file here\u003C\u002Fa>. After downloaded \u003Ca href='#' id='wptc-clear-all-decrypt-files'>click here\u003C\u002Fa> to delete the file for security reason.\";\n \n \twptc_die_with_json_encode($result);\n }\n@@ -3767,6 +3769,14 @@\n \t\treturn ;\n \t}\n \n+\tif (! isset( $_GET['wptc_download_decrypt_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['wptc_download_decrypt_nonce'] ) ), 'download_decrypt' ) ) {\n+\t\treturn;\n+\t}\n+\n+\tif(!is_user_logged_in() || !current_user_can('manage_options')){\n+\t\treturn;\n+\t}\n+\n \t$wptc_file_path = WPTC_Factory::get('config')->get_option('recent_decrypted_file');\n \n \twptc_log($wptc_file_path,'-----------$wptc_file_path----------------');","The exploit targets the AJAX action 'download_recent_decrypted_file_wptc'. An attacker needs authenticated access (Subscriber level or higher) and must send a request to \u002Fwp-admin\u002Fadmin-ajax.php with the 'action' parameter set to 'download_recent_decrypted_file_wptc'. The vulnerability exists because the function only checks is_admin(), which is always true for AJAX requests, and fails to check user capabilities (current_user_can) or nonces. If an administrator has recently used the plugin's decryption tool, the plugin will serve the decrypted SQL database backup file stored in the 'recent_decrypted_file' option directly to the attacker.","gemini-3-flash-preview","2026-07-16 14:23:17","2026-07-16 14:24:17",{"type":37,"vulnerable_version":38,"fixed_version":11,"vulnerable_browse":39,"vulnerable_zip":40,"fixed_browse":41,"fixed_zip":42,"all_tags":43},"plugin","1.22.26","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwp-time-capsule\u002Ftags\u002F1.22.26","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwp-time-capsule.1.22.26.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwp-time-capsule\u002Ftags\u002F1.22.27","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwp-time-capsule.1.22.27.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwp-time-capsule\u002Ftags"]