Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/text-to-speech-tts/includes/class-mementor-tts-remote-telemetry.php
+++ b/text-to-speech-tts/includes/class-mementor-tts-remote-telemetry.php
@@ -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} (
- domain, date, user_type, plugin_version, pro_version,
- generations, characters_total, shared_api_uses, shared_api_characters,
- pro_api_uses, pro_api_characters, user_api_uses, user_api_characters,
- errors, php_version, wp_version, country, created_at
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
- ON DUPLICATE KEY UPDATE
- user_type = IF(VALUES(user_type) != user_type, VALUES(user_type), user_type),
- plugin_version = IF(VALUES(plugin_version) != plugin_version, VALUES(plugin_version), plugin_version),
- pro_version = IF(VALUES(pro_version) != pro_version OR pro_version IS NULL, VALUES(pro_version), pro_version),
- generations = generations + VALUES(generations),
- characters_total = characters_total + VALUES(characters_total),
- shared_api_uses = shared_api_uses + VALUES(shared_api_uses),
- shared_api_characters = shared_api_characters + VALUES(shared_api_characters),
- pro_api_uses = pro_api_uses + VALUES(pro_api_uses),
- pro_api_characters = pro_api_characters + VALUES(pro_api_characters),
- user_api_uses = user_api_uses + VALUES(user_api_uses),
- user_api_characters = user_api_characters + VALUES(user_api_characters),
- errors = errors + VALUES(errors),
- php_version = IF(VALUES(php_version) != php_version, VALUES(php_version), php_version),
- wp_version = IF(VALUES(wp_version) != wp_version, VALUES(wp_version), wp_version),
- country = IF(VALUES(country) != country AND country IS NOT NULL, VALUES(country), country),
- created_at = VALUES(created_at)";
-
- // Prepare statement
- $stmt = $mysqli->prepare($sql);
-
- if (!$stmt) {
- $mysqli->close();
- return false;
- }
-
- // Bind parameters
- $stmt->bind_param(
- 'sssssiiiiiiiissss',
- $data['domain'],
- $data['date'],
- $data['user_type'],
- $data['plugin_version'],
- $data['pro_version'],
- $data['generations'],
- $data['characters_total'],
- $data['shared_api_uses'],
- $data['shared_api_characters'],
- $data['pro_api_uses'],
- $data['pro_api_characters'],
- $data['user_api_uses'],
- $data['user_api_characters'],
- $data['errors'],
- $data['php_version'],
- $data['wp_version'],
- $data['country'],
- $data['created_at']
- );
-
- // Execute
- $result = $stmt->execute();
-
- // Clean up
- $stmt->close();
- $mysqli->close();
-
- return $result;
+
+ // Check response code
+ $response_code = wp_remote_retrieve_response_code($response);
+
+ if ($response_code >= 200 && $response_code < 300) {
+ return true;
+ }
+
+ if (mementor_tts_is_debug_enabled()) {
+ error_log('Mementor TTS: Telemetry API returned status ' . $response_code);
+ }
+
+ return false;
}
/**
- * Create table structure (for reference)
- * This SQL should be run on the remote database
+ * Get table structure (for vendor API backend reference only)
+ *
+ * Note: As of version 1.9.8, telemetry uses a secure HTTPS API endpoint
+ * instead of direct database connection. This method is kept for
+ * documentation purposes only.
+ *
+ * @return string SQL table structure
*/
public function get_table_structure() {
return "
--- a/text-to-speech-tts/text-to-speech-tts.php
+++ b/text-to-speech-tts/text-to-speech-tts.php
@@ -8,7 +8,7 @@
* Plugin Name: Text to Speech (TTS) by Mementor
* Plugin URI: https://mementor.no/en/wordpress-plugins/text-to-speech/
* Description: The easiest Text-to-Speech plugin for WordPress. Add natural voices, boost accessibility, and engage visitors with an instant audio player.
- * Version: 1.9.8
+ * Version: 1.9.9
* Author: Mementor AS
* Author URI: https://mementor.no/en/
* License: GPL-3.0+
@@ -25,7 +25,7 @@
}
// Define plugin constants
-define('MEMENTOR_TTS_VERSION', '1.9.8');
+define('MEMENTOR_TTS_VERSION', '1.9.9');
define('MEMENTOR_TTS_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('MEMENTOR_TTS_PLUGIN_URL', plugin_dir_url(__FILE__));
define('MEMENTOR_TTS_PLUGIN_BASENAME', plugin_basename(__FILE__));