[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fjjTmAAbF8cxqMHc2LnG__Kd3RVxzOVRNVvX0KiXkFh8":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-14864","virusdie-missing-authorization-to-authenticated-subscriber-api-key-disclosure","Virusdie \u003C= 1.1.7 - Missing Authorization to Authenticated (Subscriber+) API Key Disclosure","The Virusdie - One-click website security plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 1.1.7. This is due to missing capability checks on the `vd_get_apikey` function which is hooked to `wp_ajax_virusdie_apikey`. This makes it possible for authenticated attackers, with Subscriber-level access and above, to retrieve the site's Virusdie API key, which could be used to access the site owner's Virusdie account and potentially compromise site security.","virusdie",null,"\u003C=1.1.7","1.1.8","medium",4.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:L\u002FI:N\u002FA:N","Missing Authorization","2026-02-18 00:00:00","2026-02-19 04:36:19",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F8ef2e0b1-52ef-4f70-9e95-d010a586d060?source=api-prod",1,[22,23,24,25,26,27,28,29],"assets\u002Fcss\u002Fvirusdie.css","changelog.txt","inc\u002Fclass-virusdie.php","inc\u002Ftools\u002Fclass-virusdie-behavior.php","readme.txt","views\u002Fauth-pass.php","views\u002Ffree.php","views\u002Fpremium.php","researched",false,3,"This research plan outlines the steps required to exploit a Sensitive Information Exposure vulnerability in the Virusdie plugin (\u003C= 1.1.7). The vulnerability allows authenticated users with Subscriber-level permissions to retrieve the Virusdie API key due to missing authorization checks in an AJAX handler.\n\n### 1. Vulnerability Summary\n*   **ID:** CVE-2025-14864\n*   **Vulnerability:** Missing Authorization \u002F Sensitive Information Exposure\n*   **Affected Function:** `VDWS_VirusdieBehavior::vd_get_apikey`\n*   **AJAX Action:** `virusdie_apikey`\n*   **Root Cause:** The function `vd_get_apikey` (hooked via `wp_ajax_virusdie_apikey`) lacks sufficient capability checks and nonce verification in the vulnerable version (1.1.7). While the provided source code shows a `canDoAjax` check, the vulnerability description confirms that in affected versions, this check is either missing, bypassed, or insufficient, allowing Subscriber-level users to retrieve the API key.\n\n### 2. Attack Vector Analysis\n*   **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Method:** POST or GET\n*   **Action:** `virusdie_apikey`\n*   **Authentication:** Authenticated (Subscriber or higher)\n*   **Payload:** No specific payload parameters are required beyond the `action` parameter.\n\n### 3. Code Flow\n1.  **Entry Point:** The plugin registers the AJAX action in `inc\u002Fclass-virusdie.php`:\n    `add_action( 'wp_ajax_virusdie_apikey', 'VDWS_VirusdieBehavior::vd_get_apikey' );`\n2.  **Handler Trigger:** When a request is made to `admin-ajax.php?action=virusdie_apikey`, WordPress invokes `VDWS_VirusdieBehavior::vd_get_apikey`.\n3.  **Vulnerable Check:** In version 1.1.7, `vd_get_apikey` is executed without a functioning `current_user_can('manage_options')` check or a nonce check.\n4.  **Information Disclosure:** The function calls `VDWS_Virusdie::get_api_key()`, which retrieves the sensitive Virusdie API key and outputs it via `wp_die()`.\n\n### 4. Nonce Acquisition Strategy\nBased on the provided source for `inc\u002Ftools\u002Fclass-virusdie-behavior.php`, the `vd_get_apikey` function and its helper `canDoAjax` **do not perform any nonce verification** (i.e., no `check_ajax_referer` or `wp_verify_nonce` is present). \n\n*   **Conclusion:** No nonce is required for this exploit. An authenticated session cookie is the only requirement.\n\n### 5. Exploitation Strategy\nThe agent will perform the following steps using the `http_request` tool:\n\n1.  **Authentication:** Log in as a Subscriber user to obtain valid session cookies.\n2.  **Information Retrieval:** Send a request to the AJAX endpoint requesting the API key.\n3.  **Request Details:**\n    *   **URL:** `http:\u002F\u002F[target]\u002Fwp-admin\u002Fadmin-ajax.php`\n    *   **Method:** POST\n    *   **Headers:** `Content-Type: application\u002Fx-www-form-urlencoded`\n    *   **Body:** `action=virusdie_apikey`\n\n### 6. Test Data Setup\nTo verify the disclosure, a dummy API key must be present in the database.\n1.  **Create Subscriber:**\n    `wp user create attacker attacker@example.com --role=subscriber --user_pass=password123`\n2.  **Set Dummy API Key:**\n    Use the plugin's internal class method via WP-CLI to ensure the key is stored correctly in the context of the plugin:\n    `wp eval \"require_once 'wp-content\u002Fplugins\u002Fvirusdie\u002Finc\u002Fclass-virusdie.php'; VDWS_Virusdie::set_api_key('VIRUSDIE-API-KEY-SECRET-12345');\"`\n    *(Note: The exact option name is internal, using the class method is most reliable).*\n\n### 7. Expected Results\n*   **Success:** The HTTP response body contains the string `VIRUSDIE-API-KEY-SECRET-12345`.\n*   **HTTP Status:** 200 OK.\n*   **Failure:** The response body contains `{\"success\":false,\"data\":{\"error\":\"Permission denied\"}}` or a 403 status code (indicating the patch is active).\n\n### 8. Verification Steps\nAfter receiving the response from the HTTP request:\n1.  **Match Key:** Compare the string returned in the HTTP response body with the value set during the \"Test Data Setup\" (`VIRUSDIE-API-KEY-SECRET-12345`).\n2.  **Confirm Role:** Use WP-CLI to confirm the user used for the request does not have administrative privileges:\n    `wp user get attacker --field=roles` (Should return `subscriber`).\n\n### 9. Alternative Approaches\nIf the POST request fails or returns `0`, try a GET request:\n*   **GET URL:** `http:\u002F\u002F[target]\u002Fwp-admin\u002Fadmin-ajax.php?action=virusdie_apikey`\n*   **Logic:** Some AJAX handlers do not discriminate between `$_GET` and `$_POST` (though `wp_ajax` usually expects POST).\n\nIf the `VDWS_Virusdie::set_api_key` method is unavailable via CLI, manually set the option that likely stores the key:\n*   `wp option update vd_apikey \"VIRUSDIE-API-KEY-SECRET-12345\"` (inferred from common plugin patterns).","The Virusdie plugin for WordPress is vulnerable to sensitive information exposure in versions up to 1.1.7. This is caused by missing or insufficient authorization checks in the `vd_get_apikey` function, which is accessible via the `wp_ajax_virusdie_apikey` AJAX action, allowing authenticated users with Subscriber-level access to retrieve the site's Virusdie API key.","\u002F\u002F inc\u002Fclass-virusdie.php\n\nadd_action( 'wp_ajax_virusdie_apikey', 'VDWS_VirusdieBehavior::vd_get_apikey' );\n\n---\n\n\u002F\u002F inc\u002Ftools\u002Fclass-virusdie-behavior.php\n\npublic static function canDoAjax()\n{\n    if (!current_user_can('manage_options')) {\n        wp_send_json_error(array('error' => 'Permission denied'), 403);\n        return FALSE;\n    }\n    return TRUE;\n}\n\n\u002F\u002F ... lines 265-270\n\npublic static function vd_get_apikey()\n{\n    if (!self::canDoAjax()) {\n        return;\n    }\n    wp_die(VDWS_Virusdie::get_api_key());\n}","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvirusdie\u002F1.1.7\u002Finc\u002Fclass-virusdie.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvirusdie\u002F1.1.8\u002Finc\u002Fclass-virusdie.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvirusdie\u002F1.1.7\u002Finc\u002Fclass-virusdie.php\t2025-12-30 13:54:42.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvirusdie\u002F1.1.8\u002Finc\u002Fclass-virusdie.php\t2026-01-30 22:05:56.000000000 +0000\n@@ -67,12 +67,12 @@\n \n \t\tadd_filter( 'plugin_action_links_' . plugin_basename( VDWS_VIRUSDIE_PLUGIN_FILE ), array( $this, 'page_plugin_action' ) );\n \n-\t\tadd_action( 'wp_ajax_virusdie_switcher', 'VDWS_VirusdieBehavior::vd_switcher' );\n+\t\t\u002F\u002F add_action( 'wp_ajax_virusdie_switcher', 'VDWS_VirusdieBehavior::vd_switcher' );\n \t\t\u002F\u002F add_action( 'wp_ajax_nopriv_virusdie_switcher', 'VDWS_VirusdieBehavior::vd_switcher' ); \u002F\u002F Will be used in future versions\n-\t\tadd_action( 'wp_ajax_virusdie_start_scan', 'VDWS_VirusdieBehavior::vd_scan_start' );\n-\t\tadd_action( 'wp_ajax_virusdie_get_progress', 'VDWS_VirusdieBehavior::vd_get_progress' );\n-\t\tadd_action( 'wp_ajax_virusdie_apikey', 'VDWS_VirusdieBehavior::vd_get_apikey' );\n-\t\tadd_action( 'wp_ajax_virusdie_resend', 'VDWS_VirusdieBehavior::vd_resend' );\n+\t\t\u002F\u002F add_action( 'wp_ajax_virusdie_start_scan', 'VDWS_VirusdieBehavior::vd_scan_start' );\n+\t\t\u002F\u002F add_action( 'wp_ajax_virusdie_get_progress', 'VDWS_VirusdieBehavior::vd_get_progress' );\n+\t\t\u002F\u002F add_action( 'wp_ajax_virusdie_apikey', 'VDWS_VirusdieBehavior::vd_get_apikey' );\n+\t\t\u002F\u002F add_action( 'wp_ajax_virusdie_resend', 'VDWS_VirusdieBehavior::vd_resend' );\n \t}\n \n \t\u002F**\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvirusdie\u002F1.1.7\u002Finc\u002Ftools\u002Fclass-virusdie-behavior.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvirusdie\u002F1.1.8\u002Finc\u002Ftools\u002Fclass-virusdie-behavior.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvirusdie\u002F1.1.7\u002Finc\u002Ftools\u002Fclass-virusdie-behavior.php\t2025-12-30 13:54:42.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fvirusdie\u002F1.1.8\u002Finc\u002Ftools\u002Fclass-virusdie-behavior.php\t2026-01-30 22:05:56.000000000 +0000\n@@ -188,6 +188,7 @@\n \t\treturn false;\n \t}\n \n+\t\u002F*\n \tpublic static function canDoAjax()\n \t{\n \t\tif (!current_user_can('manage_options')) {\n@@ -271,5 +272,6 @@\n \t\t}\n \t\twp_die(VDWS_VirusdieApiClient::signup($_POST['vd_email'], $err));\n \t}\n+\t*\u002F\n \n }","To exploit this vulnerability, an attacker needs an authenticated session with at least Subscriber-level privileges. No nonce or complex payload is required. The attacker simply sends a request to the WordPress AJAX endpoint (\u002Fwp-admin\u002Fadmin-ajax.php) with the 'action' parameter set to 'virusdie_apikey'. The server will respond with the site's Virusdie API key in the response body.","gemini-3-flash-preview","2026-04-19 05:32:30","2026-04-19 05:33:11",{"type":42,"vulnerable_version":43,"fixed_version":11,"vulnerable_browse":44,"vulnerable_zip":45,"fixed_browse":46,"fixed_zip":47,"all_tags":48},"plugin","1.1.7","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fvirusdie\u002Ftags\u002F1.1.7","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fvirusdie.1.1.7.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fvirusdie\u002Ftags\u002F1.1.8","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fvirusdie.1.1.8.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fvirusdie\u002Ftags"]