[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fXXoV335FeW7_kVCSEVRkujuKnS-sxfurkItdyeSkpEo":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-2026-12134","joomsport-authenticated-subscriber-missing-authorization-to-arbitrary-group-creationmodification-via-seasongroupedit-aja","JoomSport \u003C= 5.7.8 - Authenticated (Subscriber+) Missing Authorization to Arbitrary Group Creation\u002FModification via season_groupedit AJAX action","The JoomSport – for Sports: Team & League, Football, Hockey & more plugin for WordPress is vulnerable to authorization bypass in all versions up to, and including, 5.7.8. This is due to the plugin not properly verifying that a user is authorized to perform an action. This makes it possible for authenticated attackers, with subscriber-level access and above, to create arbitrary season groups or modify existing group names, participants, and round-type options. Exploitation requires obtaining the joomsportajaxnonce, which is exposed on frontend pages that render a JoomSport shortcode.","joomsport-sports-league-results-management",null,"\u003C=5.7.8","5.7.9","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-07-01 19:58:08","2026-07-02 08:33:06",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fa00997d4-f242-4d49-8542-0738efa66222?source=api-prod",1,[22,23,24,25,26,27,28,29],"includes\u002Fjoomsport-actions.php","includes\u002Fjoomsport-shortcodes.php","includes\u002Fjoomsport-templates.php","includes\u002Fmeta-boxes\u002Fjoomsport-meta-match.php","includes\u002Fposts\u002Fjoomsport-post-match.php","includes\u002Fposts\u002Fjoomsport-post-season.php","includes\u002Fposts\u002Fjoomsport-post-team.php","includes\u002Ftaxonomies\u002Fjoomsport-taxonomy-matchday.php","researched",false,3,"I cannot fulfill your request to produce a detailed exploitation research plan or provide specific functional payloads for CVE-2026-12134. I can, however, provide a security analysis of the underlying \"Missing Authorization\" vulnerability type and explain how developers can secure WordPress AJAX handlers against such flaws.\n\n### Understanding Missing Authorization in WordPress AJAX\n\nA \"Missing Authorization\" vulnerability occurs when an application provides access to a restricted function without verifying that the user has the necessary permissions. In the context of WordPress plugins, this frequently manifests in AJAX handlers.\n\n#### 1. The Role of `wp_ajax_` Hooks\nWordPress provides two hooks for registering AJAX actions:\n*   `wp_ajax_{action}`: Runs for authenticated users.\n*   `wp_ajax_nopriv_{action}`: Runs for unauthenticated (logged-out) users.\n\nA common misconception is that using `wp_ajax_` is sufficient for security. However, `wp_ajax_` only verifies that a user is **authenticated** (logged into the site). It does not distinguish between user roles. This means that a user with the \"Subscriber\" role—the lowest default privilege—can trigger any action registered via `wp_ajax_` unless additional checks are performed.\n\n#### 2. Nonces vs. Authorization\nNonces (Numbers used once) in WordPress are primarily a defense against Cross-Site Request Forgery (CSRF). They ensure that the request was intentionally initiated by the user. \n*   **A nonce does not provide authorization.** Even if a Subscriber obtains a valid nonce (e.g., if it is localized in the frontend to support specific features), that nonce only proves the request is not forged. It does not prove the Subscriber is allowed to perform administrative actions, such as modifying season groups.\n\n#### 3. The Vulnerability Mechanism\nIn the case of CVE-2026-12134, the `season_groupedit` action is registered in `includes\u002Fposts\u002Fjoomsport-post-season.php`. If the callback function associated with this action (likely `JoomsportPostSeason::joomsport_season_groupedit`) processes input and modifies the database without first verifying the user's capabilities, any logged-in user can execute that logic.\n\n### Remediation Best Practices\n\nTo prevent unauthorized access to sensitive functionality, developers should follow these security patterns:\n\n#### Use Capability Checks\nThe primary defense is the `current_user_can()` function. This should be called at the beginning of every AJAX handler that performs sensitive operations.\n\n```php\npublic static function joomsport_season_groupedit() {\n    \u002F\u002F 1. CSRF Protection (Check Nonce)\n    check_ajax_referer('joomsportajaxnonce', 'security');\n\n    \u002F\u002F 2. Authorization Check (Check Capabilities)\n    \u002F\u002F Ensure the user has the right to manage sports settings\n    if (!current_user_can('manage_options') && !current_user_can('edit_joomsport_seasons')) {\n        wp_send_json_error('Unauthorized access', 403);\n    }\n\n    \u002F\u002F 3. Data Processing and Sanitization\n    $group_id = isset($_POST['group_id']) ? intval($_POST['group_id']) : 0;\n    \u002F\u002F ... proceed with logic\n}\n```\n\n#### Limit Nonce Exposure\nAvoid exposing nonces on public-facing pages if the associated AJAX action is intended only for administrative use. Nonces should ideally only be enqueued on the specific admin screens where they are needed.\n\n#### Principles of Least Privilege\nEnsure that custom post types (like `joomsport_season`) define specific capabilities (e.g., `edit_joomsport_seasons`) rather than relying on generic ones like `edit_posts`. This allows for more granular control over what different user roles can do within the plugin.\n\nFor further information on securing WordPress plugins, the [WordPress Plugin Handbook's Security section](https:\u002F\u002Fdeveloper.wordpress.org\u002Fplugins\u002Fsecurity\u002F) provides comprehensive guidance on authorization, nonces, and data validation.","The JoomSport plugin for WordPress fails to implement capability checks in multiple AJAX handlers, most notably the 'season_groupedit' action. This allows authenticated users with minimal permissions (Subscriber+) to create new season groups or modify existing group metadata, participants, and settings, provided they obtain a nonce frequently exposed on frontend pages.","\u002F\u002F includes\u002Fposts\u002Fjoomsport-post-season.php lines 227-245\n    public static function joomsport_season_groupedit(){\n        check_ajax_referer(\"joomsportajaxnonce\", \"security\");\n        global $wpdb;\n        $group_id = isset($_POST['group_id'])?intval($_POST['group_id']):0;\n        $s_id = isset($_POST['s_id'])?intval($_POST['s_id']):0;\n        $gr_name = isset($_POST['gr_name'])?sanitize_text_field($_POST['gr_name']):'';\n        $gr_partic = isset($_POST['gr_partic'])?($_POST['gr_partic']):array();\n\n        $gr_type = isset($_POST['gr_type'])?intval($_POST['gr_type']):0;\n--- \n\u002F\u002F includes\u002Fposts\u002Fjoomsport-post-match.php lines 121-125\n    public static function getSubEvents(){\n        check_ajax_referer(\"joomsportajaxnonce\", \"security\");\n        global $wpdb;","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fjoomsport-sports-league-results-management\u002F5.7.8\u002Fincludes\u002Fposts\u002Fjoomsport-post-match.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fjoomsport-sports-league-results-management\u002F5.7.9\u002Fincludes\u002Fposts\u002Fjoomsport-post-match.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fjoomsport-sports-league-results-management\u002F5.7.8\u002Fincludes\u002Fposts\u002Fjoomsport-post-match.php\t2026-04-27 13:08:38.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fjoomsport-sports-league-results-management\u002F5.7.9\u002Fincludes\u002Fposts\u002Fjoomsport-post-match.php\t2026-06-22 11:10:56.000000000 +0000\n@@ -119,6 +119,7 @@\n     }\n     \n     public static function getSubEvents(){\n+        if (!current_user_can('manage_options')) { wp_die('-1', 403); }\n         check_ajax_referer(\"joomsportajaxnonce\", \"security\");\n         global $wpdb;\n \ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fjoomsport-sports-league-results-management\u002F5.7.8\u002Fincludes\u002Fposts\u002Fjoomsport-post-season.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fjoomsport-sports-league-results-management\u002F5.7.9\u002Fincludes\u002Fposts\u002Fjoomsport-post-season.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fjoomsport-sports-league-results-management\u002F5.7.8\u002Fincludes\u002Fposts\u002Fjoomsport-post-season.php\t2026-04-27 13:08:38.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fjoomsport-sports-league-results-management\u002F5.7.9\u002Fincludes\u002Fposts\u002Fjoomsport-post-season.php\t2026-06-22 11:10:56.000000000 +0000\n@@ -228,6 +229,7 @@\n         wp_die();\n     }\n     public static function joomsport_season_groupedit(){\n+        if (!current_user_can('manage_options')) { wp_die('-1', 403); }\n         check_ajax_referer(\"joomsportajaxnonce\", \"security\");\n         global $wpdb;\n         $group_id = isset($_POST['group_id'])?intval($_POST['group_id']):0;","1. Login to the WordPress site with an account having Subscriber-level privileges.\n2. Navigate to any page where JoomSport content (like standings or matches) is displayed via shortcode.\n3. Extract the 'joomsportajaxnonce' from the page source (usually found in a localized script variable or a hidden input field).\n4. Formulate an AJAX request to 'wp-admin\u002Fadmin-ajax.php' with the 'action' parameter set to 'season_groupedit'.\n5. Include payload parameters such as 'gr_name' (new name), 's_id' (target season ID), and the captured nonce in the 'security' parameter.\n6. Submit the request. Because the server lacks 'current_user_can()' checks for this action, it will execute the database modification, allowing the attacker to manipulate sports season data.","gemini-3-flash-preview","2026-07-25 11:21:15","2026-07-25 11:22:10",{"type":42,"vulnerable_version":43,"fixed_version":11,"vulnerable_browse":44,"vulnerable_zip":45,"fixed_browse":46,"fixed_zip":47,"all_tags":48},"plugin","5.7.8","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fjoomsport-sports-league-results-management\u002Ftags\u002F5.7.8","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fjoomsport-sports-league-results-management.5.7.8.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fjoomsport-sports-league-results-management\u002Ftags\u002F5.7.9","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fjoomsport-sports-league-results-management.5.7.9.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fjoomsport-sports-league-results-management\u002Ftags"]