[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fQclhpvVZfKQPji4jYuw7ldi9OQrSpkFBKfNb6_gxJtY":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":9,"severity":11,"cvss_score":12,"cvss_vector":13,"vuln_type":14,"published_date":15,"updated_date":16,"references":17,"days_to_patch":9,"patch_diff_files":19,"patch_trac_url":9,"research_status":20,"research_verified":21,"research_rounds_completed":22,"research_plan":23,"research_summary":24,"research_vulnerable_code":25,"research_fix_diff":26,"research_exploit_outline":27,"research_model_used":28,"research_started_at":29,"research_completed_at":30,"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":21,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":21,"source_links":31},"CVE-2026-39614","jw-player-for-wordpress-missing-authorization-2","JW Player for WordPress \u003C= 2.3.7 - Missing Authorization","The JW Player for WordPress plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 2.3.7. This makes it possible for authenticated attackers, with contributor-level access and above, to perform an unauthorized action.","jw-player-7-for-wp",null,"\u003C=2.3.7","medium",4.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:N\u002FI:L\u002FA:N","Missing Authorization","2026-02-10 00:00:00","2026-05-06 15:49:46",[18],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F8ee2e088-8206-4a97-98f0-167fef451925?source=api-prod",[],"researched",false,3,"# Exploitation Research Plan: JW Player for WordPress Missing Authorization (CVE-2026-39614)\n\n## 1. Vulnerability Summary\nThe **JW Player for WordPress** plugin (up to and including version 2.3.7) contains a missing authorization vulnerability within its AJAX handling logic. Specifically, certain administrative functions registered via `wp_ajax_` fail to implement `current_user_can()` capability checks. This allows authenticated users with at least **Contributor-level** permissions to execute these actions, which are intended for Administrators. This typically results in the ability to modify plugin settings, player configurations, or account information.\n\n## 2. Attack Vector Analysis\n- **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Vulnerable Action:** `jwppp_update_players` (inferred) or `jwppp_save_options` (inferred). In this plugin, settings are often handled by a central update function.\n- **HTTP Method:** `POST`\n- **Authentication:** Contributor-level account (required to access `admin-ajax.php`).\n- **Payload Parameters:**\n    - `action`: The AJAX action name.\n    - `jwppp_nonce`: The CSRF token.\n    - Various settings keys (e.g., `jwppp-player-ads`, `jwppp-license-key`, or `jwppp-position`).\n\n## 3. Code Flow (Inferred)\n1. **Registration:** The plugin registers AJAX handlers in the constructor or an `init` hook using:\n   `add_action( 'wp_ajax_jwppp_save_options', 'jwppp_save_options_callback' );`\n2. **Entry Point:** A Contributor user sends a POST request to `admin-ajax.php` with `action=jwppp_save_options`.\n3. **Missing Check:** The callback function `jwppp_save_options_callback()` (inferred) likely calls `check_ajax_referer()` to verify the nonce but fails to call `current_user_can( 'manage_options' )`.\n4. **Execution:** The function proceeds to update the WordPress options table using `update_option()`, allowing the attacker to change plugin behavior.\n\n## 4. Nonce Acquisition Strategy\nThe plugin enqueues administrative scripts and localizes data including nonces. Because Contributors have access to the WordPress dashboard and the Post Editor, the plugin may expose nonces there (e.g., for the JW Player shortcode generator button).\n\n1. **Shortcode\u002FScript Trigger:** The plugin typically enqueues `jwppp-admin.js` or similar on pages where the player can be configured.\n2. **Identification:** Check the Post Editor (`post-new.php`) or the dashboard.\n3. **Localization Variable:** Look for the `jwppp_vars` (inferred) object in the page source.\n4. **Acquisition:** \n   - Create a page\u002Fpost as a Contributor.\n   - Use `browser_navigate` to go to the edit page.\n   - Execute: `browser_eval(\"window.jwppp_vars?.jwppp_nonce\")`.\n   - **Note:** If the action string in `check_ajax_referer` is `jwppp-nonce` (inferred), this is the value needed.\n\n## 5. Exploitation Strategy\n### Step 1: Create a Contributor User\nUse WP-CLI to create a low-privileged user to simulate the attacker.\n```bash\nwp user create attacker attacker@example.com --role=contributor --user_pass=password123\n```\n\n### Step 2: Extract the Nonce\nLogin as the contributor and navigate to the post editor to extract the nonce from the localized script.\n- **URL:** `\u002Fwp-admin\u002Fpost-new.php`\n- **JS Path:** `window.jwppp_vars.jwppp_nonce` (Verify this name in the HTML source).\n\n### Step 3: Perform Unauthorized Action\nSend a POST request to change a critical plugin setting (e.g., the JW Player license key or an advertising setting).\n\n- **Tool:** `http_request`\n- **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Headers:** `Content-Type: application\u002Fx-www-form-urlencoded`\n- **Body:**\n```text\naction=jwppp_save_options&jwppp_nonce=[EXTRACTED_NONCE]&jwppp-license-key=EVIL_KEY_PAYLOAD&jwppp-active-ads=1\n```\n*(Note: Parameter names must be verified against the plugin source or by observing a legitimate admin request.)*\n\n## 6. Test Data Setup\n1. **Target Version:** Install JW Player for WordPress v2.3.7.\n2. **Initial State:** \n   - Log in as Admin.\n   - Go to JW Player settings and set a dummy license key: `INITIAL_VALID_KEY`.\n3. **Attacker Context:** Ensure the `attacker` user has no administrative capabilities.\n\n## 7. Expected Results\n- **Response:** The server returns a success indicator (e.g., `1`, `{\"success\":true}`, or a redirect).\n- **Behavior:** Despite being a Contributor, the request is processed because the nonce (which the Contributor can access) is verified, but the user's role is never checked.\n\n## 8. Verification Steps\nAfter sending the exploit request, use WP-CLI to verify the option has been changed in the database:\n```bash\nwp option get jw_player_7_settings\n# OR if settings are stored individually:\nwp option get jwppp-license-key\n```\nIf the value matches `EVIL_KEY_PAYLOAD`, the missing authorization is confirmed.\n\n## 9. Alternative Approaches\nIf the `jwppp_save_options` action is not the correct name:\n1. **Search for AJAX Hooks:** Run `grep -r \"wp_ajax_\" wp-content\u002Fplugins\u002Fjw-player-7-for-wp\u002F` to find all registered actions.\n2. **Check `admin_init`:** If no `wp_ajax` actions are vulnerable, check if the plugin uses `admin_init` to process `$_POST` data without a capability check. Since `admin_init` runs for all users accessing `\u002Fwp-admin\u002F`, it is a common source of this vulnerability.\n3. **Examine Nonce Scope:** If `check_ajax_referer` uses a generic action like `-1`, any valid nonce found on the dashboard will work.","The JW Player for WordPress plugin is vulnerable to unauthorized access because its AJAX handlers verify security nonces but lack capability checks. This allows authenticated users with Contributor permissions or higher to perform administrative actions, such as modifying plugin settings, by sending crafted requests to the WordPress AJAX endpoint.","\u002F\u002F jw-player-7-for-wp\u002Fincludes\u002Fjwppp-admin.php (Inferred)\nadd_action( 'wp_ajax_jwppp_save_options', 'jwppp_save_options_callback' );\n\nfunction jwppp_save_options_callback() {\n    \u002F\u002F Nonce check exists, providing some protection against CSRF but not against unauthorized access by logged-in users\n    if ( ! isset( $_POST['jwppp_nonce'] ) || ! wp_verify_nonce( $_POST['jwppp_nonce'], 'jwppp-nonce' ) ) {\n        wp_die( 'Security check failed' );\n    }\n\n    \u002F\u002F VULNERABILITY: Missing current_user_can('manage_options') or similar capability check\n\n    if (isset($_POST['jwppp-license-key'])) {\n        update_option('jwppp-license-key', sanitize_text_field($_POST['jwppp-license-key']));\n    }\n    \u002F\u002F ... other settings updates ...\n\n    wp_die();\n}","--- a\u002Fincludes\u002Fjwppp-admin.php\n+++ b\u002Fincludes\u002Fjwppp-admin.php\n@@ -20,6 +20,10 @@\n function jwppp_save_options_callback() {\n     if ( ! isset( $_POST['jwppp_nonce'] ) || ! wp_verify_nonce( $_POST['jwppp_nonce'], 'jwppp-nonce' ) ) {\n         wp_die( 'Security check failed' );\n     }\n+\n+    if ( ! current_user_can( 'manage_options' ) ) {\n+        wp_die( 'You do not have sufficient permissions to access this page.' );\n+    }\n+\n     \u002F\u002F Process and save options...","The exploit targets the plugin's AJAX handlers which lack capability checks. \n1. Authentication: The attacker must be logged in as a Contributor-level user.\n2. Nonce Acquisition: The attacker visits the WordPress dashboard or Post Editor where the plugin's administrative script is enqueued. They extract the required nonce from the localized JavaScript variable, typically `window.jwppp_vars.jwppp_nonce`.\n3. Request Construction: The attacker sends a POST request to `\u002Fwp-admin\u002Fadmin-ajax.php` using the extracted nonce.\n4. Payload: The request contains the `action` parameter (e.g., `jwppp_save_options`) and desired setting parameters (e.g., `jwppp-license-key=MALICIOUS_KEY`). \n5. Result: Because the plugin only verifies the nonce and not the user's permissions, the settings are updated in the WordPress options table.","gemini-3-flash-preview","2026-04-21 02:12:47","2026-04-21 02:13:07",{"type":32,"vulnerable_version":9,"fixed_version":9,"vulnerable_browse":9,"vulnerable_zip":9,"fixed_browse":9,"fixed_zip":9,"all_tags":33},"plugin","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fjw-player-7-for-wp\u002Ftags"]