[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f_gksrmRf8002m8HYZX8Jwii1k4MoPDwtAvZcrOzrGvo":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":29,"research_verified":30,"research_rounds_completed":31,"research_plan":32,"research_summary":33,"research_vulnerable_code":34,"research_fix_diff":35,"research_exploit_outline":36,"research_model_used":37,"research_started_at":38,"research_completed_at":39,"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":30,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":30,"source_links":40},"CVE-2026-32492","my-tickets-accessible-event-ticketing-missing-authorization","My Tickets – Accessible Event Ticketing \u003C= 2.1.1 - Missing Authorization","The My Tickets – Accessible Event Ticketing plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 2.1.1. This makes it possible for unauthenticated attackers to perform an unauthorized action.","my-tickets",null,"\u003C=2.1.1","2.1.2","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-03-20 00:00:00","2026-03-27 13:51:38",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fb8f82dad-cba6-484e-8e30-6370ec2ba2d8?source=api-prod",8,[22,23,24,25,26,27,28],"css\u002Fmt-cart.css","mt-ajax.php","mt-notifications.php","mt-receipt.php","mt-verify.php","my-tickets.php","readme.txt","researched",false,3,"# Research Plan: CVE-2026-32492 Missing Authorization in My Tickets\n\n## 1. Vulnerability Summary\nThe **My Tickets** plugin for WordPress (versions \u003C= 2.1.1) is vulnerable to **Missing Authorization** in its AJAX handlers. Specifically, the `mt_ajax_handler` function (and potentially others in `mt-ajax.php`) is registered for both authenticated (`wp_ajax_`) and unauthenticated (`wp_ajax_nopriv_`) users without adequate capability checks for certain internal functions. \n\nThe most likely vector involves the `save_address` functionality or the `mt_ajax_load_model` function, which allows unauthenticated users to perform actions or access data models that should be restricted. In version 2.1.1, the `save_address` function updates user metadata based on the current user object, which for unauthenticated users defaults to ID 0, potentially leading to database pollution or unauthorized metadata manipulation.\n\n## 2. Attack Vector Analysis\n- **Endpoint**: `\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Action**: `mt_ajax_handler` (for `save_address`) or `mt_ajax_load_model`.\n- **Authentication**: Unauthenticated (via `wp_ajax_nopriv_mt_ajax_handler`).\n- **Preconditions**: \n    - The plugin must be active.\n    - A valid nonce for the specific AJAX action must be obtained from a front-end page (e.g., an event","The My Tickets plugin for WordPress is vulnerable to Missing Authorization because several AJAX handlers, such as mt_ajax_handler and mt_ajax_load_model, are registered for unauthenticated users without internal capability checks. This allows unauthenticated attackers to perform unauthorized actions like updating user metadata or accessing restricted data models, provided they can obtain a valid security nonce from the site's front-end.","\u002F\u002F mt-ajax.php lines 224-225 (v2.1.1)\nadd_action( 'wp_ajax_mt_ajax_handler', 'mt_ajax_handler' );\nadd_action( 'wp_ajax_nopriv_mt_ajax_handler', 'mt_ajax_handler' );\n\n---\n\n\u002F\u002F mt-ajax.php lines 212-222 (v2.1.1)\nif ( 'save_address' === $_REQUEST['function'] ) {\n    $post         = array_map( 'sanitize_text_field', $_REQUEST['data'] );\n    $current_user = wp_get_current_user();\n    $saved        = update_user_meta( $current_user->ID, '_mt_shipping_address', $post );\n    $response     = array();\n    if ( $saved ) {\n        $response['response'] = apply_filters( 'mt_save_address_success', __( 'Address updated.', 'my-tickets' ) );\n    } else {\n        $response['response'] = apply_filters( 'mt_save_address_failure', __( 'Address not updated.', 'my-tickets' ) );\n    }\n    wp_send_json( $response );\n}\n\n---\n\n\u002F\u002F mt-ajax.php lines 230-244 (v2.1.1)\nfunction mt_ajax_load_model() {\n\t\u002F\u002F verify nonce.\n\tif ( ! check_ajax_referer( 'mt-load-model', 'security', false ) ) {\n\t\twp_send_json(\n\t\t\tarray(\n\t\t\t\t'response' => __( 'Invalid security response.', 'my-tickets' ),\n\t\t\t\t'form'     => '',\n\t\t\t)\n\t\t);\n\t}\n\t$model    = ( in_array( $_REQUEST['model'], array( 'continuous', 'discrete', 'event' ), true ) ) ? sanitize_key( $_REQUEST['model'] ) : false;\n    \u002F\u002F ... logic continues ...\n}\nadd_action( 'wp_ajax_mt_ajax_load_model', 'mt_ajax_load_model' );\nadd_action( 'wp_ajax_nopriv_mt_ajax_load_model', 'mt_ajax_load_model' );","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fmy-tickets\u002F2.1.1\u002Fcss\u002Fmt-cart.css \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fmy-tickets\u002F2.1.2\u002Fcss\u002Fmt-cart.css\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fmy-tickets\u002F2.1.1\u002Fcss\u002Fmt-cart.css\t2025-11-30 19:38:36.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fmy-tickets\u002F2.1.2\u002Fcss\u002Fmt-cart.css\t2026-02-24 21:48:10.000000000 +0000\n@@ -178,6 +178,10 @@\n \ttext-align: end;\n }\n \n+.mt-order legend {\n+\tfloat: none;\n+}\n+\n .mt_cart th .mt-datetime {\n     font-weight: 400;\n }\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fmy-tickets\u002F2.1.1\u002Fmt-ajax.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fmy-tickets\u002F2.1.2\u002Fmt-ajax.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fmy-tickets\u002F2.1.1\u002Fmt-ajax.php\t2025-11-30 19:38:36.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fmy-tickets\u002F2.1.2\u002Fmt-ajax.php\t2026-02-24 21:48:10.000000000 +0000\n@@ -81,6 +81,15 @@\n \t\t$data = map_deep( $data, 'sanitize_text_field' );\n \t\t\u002F\u002F reformat request data to multidimensional array.\n \t\t$cart = mt_get_cart();\n+\t\t$lock = 'mt_add_to_cart_lock_' . sanitize_text_field( $_REQUEST['mt-cart-nonce'] );\n+\t\tif ( get_transient( $lock ) ) {\n+\t\t\t$return = array(\n+\t\t\t\t'response' => esc_html__( 'Another transaction is currently processing. Please try again shortly.', 'my-tickets' ),\n+\t\t\t\t'success'  => 0,\n+\t\t\t);\n+\t\t\twp_send_json( $return );\n+\t\t}\n+\t\tset_transient( $lock, 1, 5 );\n \n \t\tforeach ( $data as $k => $d ) {\n \t\t\tif ( 'mt_tickets' === $k ) {\n@@ -163,6 +172,7 @@\n \t\t\t'event_id' => $submit['mt_event_id'],\n \t\t\t'data'     => $count,\n \t\t);\n+\t\tdelete_transient( $lock );\n \t\twp_send_json( $return );\n \t}\n \tif ( 'save_address' === $_REQUEST['function'] ) {\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fmy-tickets\u002F2.1.1\u002Fmt-notifications.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fmy-tickets\u002F2.1.2\u002Fmt-notifications.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fmy-tickets\u002F2.1.1\u002Fmt-notifications.php\t2025-11-30 19:38:36.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fmy-tickets\u002F2.1.2\u002Fmt-notifications.php\t2026-02-24 21:48:10.000000000 +0000\n@@ -769,7 +769,7 @@\n \tif ( function_exists( 'mc_draw_template' ) ) {\n \t\treturn mc_draw_template( $data, $template );\n \t} else {\n-\t\t$template = stripcslashes( $template );\n+\t\t$template = wp_unslash( $template );\n \t\t\u002F\u002F If there are no brace characters, there is nothing to replace.\n \t\tif ( strpos( $template, '{' ) === false ) {\n \t\t\treturn trim( $template );\n@@ -802,7 +802,7 @@\n \t\t\t\t\t\t\t}\n \t\t\t\t\t\t}\n \t\t\t\t\t} else { \u002F\u002F don't do preg match (never required for RSS).\n-\t\t\t\t\t\t$template = stripcslashes( str_replace( '{' . $key . '}', $value, $template ) );\n+\t\t\t\t\t\t$template = wp_unslash( str_replace( '{' . $key . '}', $value, $template ) );\n \t\t\t\t\t}\n \t\t\t\t} \u002F\u002F end {$key check.\n \t\t\t}\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fmy-tickets\u002F2.1.1\u002Fmt-receipt.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fmy-tickets\u002F2.1.2\u002Fmt-receipt.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fmy-tickets\u002F2.1.1\u002Fmt-receipt.php\t2025-11-30 19:38:36.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fmy-tickets\u002F2.1.2\u002Fmt-receipt.php\t2026-02-24 21:48:10.000000000 +0000\n@@ -27,7 +27,7 @@\n \t\t\t\t$nonce       = isset( $_POST['_wpnonce'] ) ? $_POST['_wpnonce'] : false;\n \t\t\t\t$verify      = wp_verify_nonce( $nonce, 'mt-verify-email' );\n \t\t\t\t$email       = sanitize_text_field( $_POST['mt-verify-email'] );\n-\t\t\t\t$is_verified = ( $verify && $email === get_post_meta( $receipt->ID, '_email', true ) ) ? true : false;\n+\t\t\t\t$is_verified = ( $verify && get_post_meta( $receipt->ID, '_email', true ) === $email ) ? true : false;\n \t\t\t}\n \t\t\t$cookie_receipt = ( isset( $_COOKIE['mt_purchase_receipt'] ) ) ? $_COOKIE['mt_purchase_receipt'] : false;\n \t\t\t\u002F\u002F Allow conditions: within 10 minutes of purchase & browser has a matching cookie; current user can view reports; user has verified email.\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fmy-tickets\u002F2.1.1\u002Fmy-tickets.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fmy-tickets\u002F2.1.2\u002Fmy-tickets.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fmy-tickets\u002F2.1.1\u002Fmy-tickets.php\t2025-11-30 19:38:36.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fmy-tickets\u002F2.1.2\u002Fmy-tickets.php\t2026-02-24 21:48:10.000000000 +0000\n@@ -17,11 +17,11 @@\n  * License:     GPL-2.0+\n  * License URI: http:\u002F\u002Fwww.gnu.org\u002Flicense\u002Fgpl-2.0.txt\n  * Domain Path: lang\n- * Version:     2.1.1\n+ * Version:     2.1.2\n  *\u002F\n \n \u002F*\n-\tCopyright 2014-2025  Joe Dolson (email : joe@joedolson.com)\n+\tCopyright 2014-2026  Joe Dolson (email : joe@joedolson.com)\n \n \tThis program is free software; you can redistribute it and\u002For modify\n \tit under the terms of the GNU General Public License as published by\n@@ -44,7 +44,7 @@\n  * @return string Current My Tickets version.\n  *\u002F\n function mt_get_current_version() {\n-\t$mt_version = '2.1.1';\n+\t$mt_version = '2.1.2';\n \n \treturn $mt_version;\n }","The exploit methodology involves targeting the WordPress AJAX endpoint (\u002Fwp-admin\u002Fadmin-ajax.php) using actions registered for unauthenticated users. An attacker first navigates to a front-end event page to extract a valid security nonce (e.g., mt-cart-nonce or mt-load-model). Once obtained, the attacker sends a POST request to the AJAX endpoint. For example, by specifying the action 'mt_ajax_handler' and function 'save_address', the attacker can attempt to manipulate user metadata despite being unauthenticated. Alternatively, using 'mt_ajax_load_model' allows the attacker to trigger data model loading logic that is intended to be protected by authorization checks.","gemini-3-flash-preview","2026-04-18 02:02:39","2026-04-18 02:03:26",{"type":41,"vulnerable_version":42,"fixed_version":11,"vulnerable_browse":43,"vulnerable_zip":44,"fixed_browse":45,"fixed_zip":46,"all_tags":47},"plugin","2.1.1","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fmy-tickets\u002Ftags\u002F2.1.1","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fmy-tickets.2.1.1.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fmy-tickets\u002Ftags\u002F2.1.2","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fmy-tickets.2.1.2.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fmy-tickets\u002Ftags"]