Text to Speech (TTS) by Mementor <= 1.9.8 - Use of Hardcoded Password to Unauthenticated Remote Database Access
Description
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.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:NTechnical Details
<=1.9.8What Changed in the Fix
Changes introduced in v1.9.9
Source Code
WordPress.org SVN# Research Plan: CVE-2026-1233 - Hardcoded Database Credentials in Text to Speech (TTS) by Mementor ## 1. Vulnerability Summary The **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` …
Show full research plan
Research Plan: CVE-2026-1233 - Hardcoded Database Credentials in Text to Speech (TTS) by Mementor
1. Vulnerability Summary
The 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.
2. Attack Vector Analysis
- Target File:
wp-content/plugins/text-to-speech-tts/includes/class-mementor-tts-remote-telemetry.php - Vulnerability Type: Information Exposure / Hardcoded Credentials (CWE-798).
- Authentication: None required. The vulnerability is present in the source code of the plugin, which is publicly accessible.
- 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).
3. Code Flow
- The plugin defines a class
Mementor_TTS_Remote_Telemetryinincludes/class-mementor-tts-remote-telemetry.php. - Within this class, private properties are defined containing Base64-encoded (double-encoded) strings:
$enc_host: Hostname of the remote MySQL server.$enc_db: Database name.$enc_user: Database username.$enc_pass: Database password.
- 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. - Since PHP source files are readable by anyone with access to the plugin files (or via SVN/GitHub), these "obfuscated" credentials can be reversed.
4. Nonce Acquisition Strategy
No nonce is required.
This 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.
5. Exploitation Strategy
The exploitation involves retrieving the plugin file and decoding the hardcoded strings.
Step-by-Step Plan:
- Retrieve File Content: Read the content of
wp-content/plugins/text-to-speech-tts/includes/class-mementor-tts-remote-telemetry.php. - Extract Encrypted Strings: Locate the following lines:
private $enc_host = 'YjNOc2J6SXViV1Z0Wlc1MGIzSXVibTg9'; private $enc_db = 'YldWdFpXNTBiM0pmZEhSemNHeDFaMmx1WkdGMFlRPT0='; private $enc_user = 'YldWdFpXNTBiM0pmZEhSemNHeDFaMmx1WkdGMFlYVnpjZz09'; private $enc_pass = 'UlRWTWJtZHJkbHBoTkZGNldGUkxSRUptWlVZPQ=='; - Decode Logic: The strings are double-Base64 encoded.
- Perform
base64_decode()on the string. - Perform
base64_decode()again on the result.
- Perform
- 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.
Example Decoding (Manual Verification):
- Host:
YjNOc2J6SXViV1Z0Wlc1MGIzSXVibTg9- Decode 1:
b3NsbzIubWVudG9yLm8= - Decode 2:
oslo2.mementor.o(likelyoslo2.mementor.no)
- Decode 1:
- Password:
UlRWTWJtZHJkbHBoTkZGNldGUkxSRUptWlVZPQ==- Decode 1:
RTVMbmdrdlphNFF6WFRLREJmZUY= - Decode 2:
E5LngkvZa4QzXTKDBfeE
- Decode 1:
6. Test Data Setup
- Plugin Installation: Install the
text-to-speech-ttsplugin version 1.9.8. - Activation: Activate the plugin.
- Verification: Ensure the file
wp-content/plugins/text-to-speech-tts/includes/class-mementor-tts-remote-telemetry.phpexists and contains the$enc_variables.
7. Expected Results
- The attacker successfully reads the PHP source file.
- The attacker extracts the four
$enc_strings. - After double Base64 decoding, the attacker obtains cleartext MySQL credentials:
- Host: (Decoded string)
- Database: (Decoded string)
- User: (Decoded string)
- Password: (Decoded string)
8. Verification Steps
After performing the extraction via script/agent:
- Use
wp-clito verify the values currently stored in the class match the expected vulnerable ones:wp eval 'require_once "wp-content/plugins/text-to-speech-tts/includes/class-mementor-tts-remote-telemetry.php"; $ref = new ReflectionClass("Mementor_TTS_Remote_Telemetry"); $props = $ref->getDefaultProperties(); echo "Host: " . $props["enc_host"];' - Run a local PHP script to perform the double decoding and output the cleartext.
9. Alternative Approaches
If 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://downloads.wordpress.org/plugin/text-to-speech-tts.1.9.8.zip to extract the same credentials.
For the purpose of an automated PoC on a live site, the agent should:
- Try to use
http_requestto see if a sensitive file (likereadme.txt) is accessible to confirm the plugin version. - Use
wp_cli(if available in the environment) to cat the content of the target PHP file. - If
wp_cliis not available, the agent relies on the fact that the credentials are baked into the distributed code.
Summary
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.
Vulnerable Code
// includes/class-mementor-tts-remote-telemetry.php (Lines 23-28) /** * Encrypted database credentials * These are obfuscated to prevent easy access */ private $enc_host = 'YjNOc2J6SXViV1Z0Wlc1MGIzSXVibTg9'; private $enc_db = 'YldWdFpXNTBiM0pmZEhSemNHeDFaMmx1WkdGMFlRPT0='; private $enc_user = 'YldWdFpXNTBiM0pmZEhSemNHeDFaMmx1WkdGMFlYVnpjZz09'; private $enc_pass = 'UlRWTWJtZHJkbHBoTkZGNldGUkxSRUptWlVZPQ=='; --- // includes/class-mementor-tts-remote-telemetry.php (Lines 275-285) private function insert_remote_data($data) { // Decrypt credentials $host = base64_decode(base64_decode($this->enc_host)); $dbname = base64_decode(base64_decode($this->enc_db)); $username = base64_decode(base64_decode($this->enc_user)); $password = base64_decode(base64_decode($this->enc_pass)); // Create connection using mysqli $mysqli = new mysqli($host, $username, $password, $dbname);
Security Fix
@@ -20,16 +20,13 @@ private static $instance = null; /** - * Encrypted database credentials - * These are obfuscated to prevent easy access + * Remote telemetry API endpoint + * Uses secure HTTPS API instead of direct database connection */ - private $enc_host = 'YjNOc2J6SXViV1Z0Wlc1MGIzSXVibTg9'; - private $enc_db = 'YldWdFpXNTBiM0pmZEhSemNHeDFaMmx1WkdGMFlRPT0='; - private $enc_user = 'YldWdFpXNTBiM0pmZEhSemNHeDFaMmx1WkdGMFlYVnpjZz09'; - private $enc_pass = 'UlRWTWJtZHJkbHBoTkZGNldGUkxSRUptWlVZPQ=='; - + private $api_endpoint = 'https://crm.mementor.no/plugin/api/telemetry/v1/collect.php'; + /** - * Table name for telemetry data + * Table name for telemetry data (used for reference only) */ private $table_name = 'tts_usage_data'; @@ -265,102 +262,75 @@ } /** - * Insert data into remote database - * - * @param array $data Data to insert + * Send data to remote telemetry API + * + * Uses secure HTTPS POST instead of direct database connection + * to prevent credential exposure (CVE fix for versions <= 1.9.3) + * + * @param array $data Data to send * @return bool Success */ private function insert_remote_data($data) { - // Decrypt credentials - $host = base64_decode(base64_decode($this->enc_host)); - $dbname = base64_decode(base64_decode($this->enc_db)); - $username = base64_decode(base64_decode($this->enc_user)); - $password = base64_decode(base64_decode($this->enc_pass)); - - // Create connection using mysqli - $mysqli = new mysqli($host, $username, $password, $dbname); - - // Check connection - if ($mysqli->connect_error) { + // Generate request signature for authentication + $timestamp = time(); + $nonce = wp_generate_password(16, false); + $signature = hash_hmac('sha256', $data['domain'] . $timestamp . $nonce, 'mementor_tts_telemetry_v1'); + + // Prepare request body + $body = array( + 'telemetry_data' => $data, + 'timestamp' => $timestamp, + 'nonce' => $nonce, + 'signature' => $signature, + 'api_version' => '1.0' + ); + + // Send via secure HTTPS POST using WordPress HTTP API + $response = wp_remote_post($this->api_endpoint, array( + 'method' => 'POST', + 'timeout' => 15, + 'redirection' => 5, + 'httpversion' => '1.1', + 'blocking' => true, + 'headers' => array( + 'Content-Type' => 'application/json', + 'X-Telemetry-Source' => 'mementor-tts-plugin', + 'X-Plugin-Version' => MEMENTOR_TTS_VERSION + ), + 'body' => wp_json_encode($body), + 'sslverify' => true + )); + + // Check for errors + if (is_wp_error($response)) { if (mementor_tts_is_debug_enabled()) { - error_log('Mementor TTS: Failed to connect to telemetry database'); + error_log('Mementor TTS: Telemetry API request failed - ' . $response->get_error_message()); } return false; } - - // Set charset - $mysqli->set_charset('utf8mb4'); - - // Prepare SQL with INSERT ... ON DUPLICATE KEY UPDATE - // This will update only if data has changed - $sql = "INSERT INTO {$this->table_name} ( ... )"; - - // ... (rest of the mysqli logic)
Exploit Outline
Exploitation does not require a dynamic endpoint but rather focuses on extracting hardcoded secrets from the plugin's source code. 1. Locate the file `wp-content/plugins/text-to-speech-tts/includes/class-mementor-tts-remote-telemetry.php` (accessible via file system, SVN, or local file inclusion). 2. Identify the four private properties: `$enc_host`, `$enc_db`, `$enc_user`, and `$enc_pass` containing Base64-encoded strings. 3. The strings are double-Base64 encoded (a common obfuscation technique). For example, a string like 'YjNOc2J6SXViV1Z0Wlc1MGIzSXVibTg9' must be passed through `base64_decode()` twice. 4. Once decoded, the attacker obtains cleartext credentials (host, database name, username, and password) for a remote MySQL server. 5. 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.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.