--- a/cliengo/admin/class-cliengo-form.php
+++ b/cliengo/admin/class-cliengo-form.php
@@ -46,6 +46,11 @@
const PROD_ENV = true;
/**
+ * Regex pattern for validating chatbot tokens (two 24-char hex strings separated by a dash)
+ */
+ const CHATBOT_TOKEN_PATTERN = '/^[0-9a-f]{24}-[0-9a-f]{24}$/i';
+
+ /**
* Initialize the class and set its properties.
*
* @since 1.0.0
@@ -60,9 +65,26 @@
}
/**
+ * Validates a chatbot token server-side.
+ * Token must be two 24-character hex strings separated by a dash.
+ *
+ * @param string $token The chatbot token to validate.
+ * @return bool Whether the token is valid.
+ */
+ private static function validate_chatbot_token( $token ) {
+ return is_string( $token ) && preg_match( self::CHATBOT_TOKEN_PATTERN, $token );
+ }
+
+ /**
* Fetches and returns all session variables
*/
public function restore_session() {
+ if ( ! current_user_can( 'manage_options' ) ) {
+ wp_die( 'Error: You do not have sufficient permissions to perform this action.' );
+ }
+
+ check_ajax_referer( 'restore_session_action', 'restore_session_nonce' );
+
$account = get_option( 'cliengo_session' );
$session = array(
'token' => stripslashes( get_option( 'cliengo_chatbot_token' ) ),
@@ -79,23 +101,45 @@
*/
public function update_chatbot_token()
{
- // Check user permissions
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( 'Error: You do not have sufficient permissions to perform this action. Please contact the site administrator.' );
}
- // Check nonce
- if ( ! isset( $_POST['update_chatbot_token_nonce'] ) || ! wp_verify_nonce( $_POST['update_chatbot_token_nonce'], 'update_chatbot_token_action' ) ) {
- wp_die('Security Error: Security check failed. Please reload the page and try again.');
+ check_ajax_referer( 'update_chatbot_token_action', 'update_chatbot_token_nonce' );
+
+ $raw_token = isset( $_POST['chatbot_token'] ) ? wp_unslash( $_POST['chatbot_token'] ) : '';
+ $chatbot_token = sanitize_text_field( $raw_token );
+ $position = isset( $_POST['position_chatbot'] ) ? sanitize_text_field( wp_unslash( $_POST['position_chatbot'] ) ) : 'right';
+
+ // Reject if sanitization altered the value (indicates malicious input)
+ if ( $chatbot_token !== $raw_token ) {
+ wp_die( 'Error: Invalid chatbot token — contains disallowed characters.' );
+ }
+
+ // Whitelist position values
+ if ( ! in_array( $position, array( 'left', 'right' ), true ) ) {
+ $position = 'right';
+ }
+
+ if ( empty( $chatbot_token ) ) {
+ // Clear token and remove script
+ $this->update_cliengo_option( 'cliengo_chatbot_token', '' );
+ $this->update_cliengo_option( 'cliengo_chatbot_position', $position );
+ wp_delete_file( plugin_dir_path( __FILE__ ) . '../public/js/script_install_cliengo.js' );
+ echo wp_json_encode( true );
+ wp_die();
}
- $response = $this->update_cliengo_option('cliengo_chatbot_token', $_POST['chatbot_token'])
- && $this->update_cliengo_option('cliengo_chatbot_position', $_POST['position_chatbot']);
- if ($_POST['chatbot_token'] == null) {
- // If it came null, remove script!
- wp_delete_file(plugin_dir_path( __FILE__ ) . '../public/js/script_install_cliengo.js');
- } else if ($response) {
- Cliengo_Form::create_install_code_cliengo($_POST['chatbot_token']);
+ // Validate token format server-side
+ if ( ! self::validate_chatbot_token( $chatbot_token ) ) {
+ wp_die( 'Error: Invalid chatbot token format.' );
+ }
+
+ $response = $this->update_cliengo_option( 'cliengo_chatbot_token', $chatbot_token )
+ && $this->update_cliengo_option( 'cliengo_chatbot_position', $position );
+
+ if ( $response ) {
+ Cliengo_Form::create_install_code_cliengo( $chatbot_token );
}
echo wp_json_encode($response);
@@ -108,16 +152,20 @@
*/
public function update_chatbot_position()
{
- // Check user permissions
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( 'Error: You do not have sufficient permissions to perform this action. Please contact the site administrator.' );
}
- // Verificar nonce
- if ( ! isset( $_POST['update_chatbot_position_nonce'] ) || ! wp_verify_nonce( $_POST['update_chatbot_position_nonce'], 'update_chatbot_position_action' ) ) {
- wp_die('Security Error: Security check failed. Please reload the page and try again.');
+ check_ajax_referer( 'update_chatbot_position_action', 'update_chatbot_position_nonce' );
+
+ $position = isset( $_POST['position_chatbot'] ) ? sanitize_text_field( wp_unslash( $_POST['position_chatbot'] ) ) : 'right';
+
+ // Whitelist position values
+ if ( ! in_array( $position, array( 'left', 'right' ), true ) ) {
+ $position = 'right';
}
- echo esc_html($this->update_cliengo_option('cliengo_chatbot_position', wp_kses_post($_POST['position_chatbot'])));
+
+ echo wp_json_encode( $this->update_cliengo_option( 'cliengo_chatbot_position', $position ) );
wp_die();
}
@@ -127,19 +175,30 @@
*/
public function update_session()
{
- // Check user permissions
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( 'Error: You do not have sufficient permissions to perform this action. Please contact the site administrator.' );
}
- if ( ! isset( $_POST['update_session_nonce'] ) || ! wp_verify_nonce( $_POST['update_session_nonce'], 'update_session_action' ) ) {
- wp_die('Security Error: Security check failed. Please reload the page and try again.');
- }
+ check_ajax_referer( 'update_session_action', 'update_session_nonce' );
$response = false;
- if (isset($_POST['chatbot_session'])) {
- $response = $this->update_cliengo_option('cliengo_session', $_POST['chatbot_session']);
+ if ( isset( $_POST['chatbot_session'] ) ) {
+ $raw_session = wp_unslash( $_POST['chatbot_session'] );
+
+ // Validate JSON structure if non-empty
+ if ( ! empty( $raw_session ) ) {
+ $decoded = json_decode( $raw_session, true );
+ if ( json_last_error() !== JSON_ERROR_NONE ) {
+ wp_die( 'Error: Invalid session data format.' );
+ }
+ // Re-encode to sanitize the JSON
+ $sanitized_session = wp_json_encode( $decoded );
+ } else {
+ $sanitized_session = '';
+ }
+
+ $response = $this->update_cliengo_option( 'cliengo_session', $sanitized_session );
}
echo wp_json_encode($response);
@@ -153,21 +212,30 @@
*/
public function wordpress_login()
{
- if ( ! isset( $_POST['wordpress_login_nonce'] ) || ! wp_verify_nonce( $_POST['wordpress_login_nonce'], 'wordpress_login_action' ) ) {
- wp_die('Security Error: Security check failed. Please reload the page and try again.');
+ if ( ! current_user_can( 'manage_options' ) ) {
+ wp_die( 'Error: You do not have sufficient permissions to perform this action. Please contact the site administrator.' );
}
+ check_ajax_referer( 'wordpress_login_action', 'wordpress_login_nonce' );
+
+ $username = isset( $_POST['username'] ) ? sanitize_email( wp_unslash( $_POST['username'] ) ) : '';
+ $password = isset( $_POST['password'] ) ? wp_unslash( $_POST['password'] ) : '';
+
$api_host = Cliengo_Form::PROD_ENV ? 'https://api.cliengo.com' : 'https://api.stagecliengo.com';
- $body = array('username' => $_POST['username'], 'password' => $_POST['password']);
+ $body = array( 'username' => $username, 'password' => $password );
$api_response = wp_remote_request("$api_host/1.0/wordpress/login", array(
'method' => 'POST',
'headers' => array(
'content-type' => 'application/json',
),
'body' => wp_json_encode($body),
- 'timeout' => 30 // Default is 5 seconds
+ 'timeout' => 30
));
+ if ( is_wp_error( $api_response ) ) {
+ wp_die( 'Error: Could not connect to Cliengo API.', 500 );
+ }
+
if ($api_response['response']['code'] == 200) {
echo wp_json_encode($api_response['body']);
wp_die();
@@ -184,20 +252,22 @@
*/
private function update_cliengo_option ($option, $new_value)
{
- // Obtenemos opción existente.
+ // Whitelist allowed option names
+ $allowed_options = array( 'cliengo_chatbot_token', 'cliengo_chatbot_position', 'cliengo_session' );
+ if ( ! in_array( $option, $allowed_options, true ) ) {
+ return false;
+ }
+
$current = get_option($option);
$response = true;
- // Si la opción ya existe, la actualizamos.
if ($current !== false)
{
if (strcmp($current, $new_value) !== 0)
- // Actualizamos si el valor actual de la opción es distinto al nuevo.
$response = update_option($option, $new_value);
}
else
{
- // Agregamos nueva opción.
$response = add_option($option, $new_value);
}
@@ -211,15 +281,21 @@
*/
public static function create_install_code_cliengo($chatbot_token)
{
- $array_chatbot_token = explode('-',$chatbot_token); //esto se encarga de dividir el chatbot token
- // $array_chatbot_token[0] = Company ID
- // $array_chatbot_token[1] = Website ID
+ // Validate token format before building script
+ if ( ! self::validate_chatbot_token( $chatbot_token ) ) {
+ return;
+ }
+
+ $array_chatbot_token = explode('-',$chatbot_token);
+ // Both parts are already validated as 24-char hex strings by validate_chatbot_token
+ $company_id = $array_chatbot_token[0];
+ $website_id = $array_chatbot_token[1];
+
$install_code_cliengo = '(function(){var ldk=document.createElement("script"); ldk.type="text/javascript";';
- $install_code_cliengo .= 'ldk.async=true; ldk.src="https://s.cliengo.com/weboptimizer/' . $array_chatbot_token[0] . '/';
- $install_code_cliengo .= $array_chatbot_token[1];
+ $install_code_cliengo .= 'ldk.async=true; ldk.src="https://s.cliengo.com/weboptimizer/' . $company_id . '/';
+ $install_code_cliengo .= $website_id;
$install_code_cliengo .= '.js?platform=wordpress"; var s=document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(ldk, s);})();';
- // Eliminamos cualquier salto de línea posible
$install_code_cliengo = str_replace(array("r", "n"), '', $install_code_cliengo);
Cliengo_Form::write_to_file_install_code_cliengo_js($install_code_cliengo);
@@ -253,19 +329,29 @@
*/
public function wp_registration()
{
- if ( ! isset( $_POST['wp_registration_nonce'] ) || ! wp_verify_nonce( $_POST['wp_registration_nonce'], 'wp_registration_action' ) ) {
- wp_die('Security Error: Security check failed. Please reload the page and try again.');
+ if ( ! current_user_can( 'manage_options' ) ) {
+ wp_die( 'Error: You do not have sufficient permissions to perform this action. Please contact the site administrator.' );
}
+ check_ajax_referer( 'wp_registration_action', 'wp_registration_nonce' );
+
+ $username = isset( $_POST['username'] ) ? sanitize_text_field( wp_unslash( $_POST['username'] ) ) : '';
+ $email = isset( $_POST['email'] ) ? sanitize_email( wp_unslash( $_POST['email'] ) ) : '';
+ $password = isset( $_POST['password'] ) ? wp_unslash( $_POST['password'] ) : '';
+ $source_name = isset( $_POST['sourceName'] ) ? esc_url_raw( wp_unslash( $_POST['sourceName'] ) ) : '';
+ $account_name = isset( $_POST['accountName'] ) ? sanitize_text_field( wp_unslash( $_POST['accountName'] ) ) : '';
+ $origin_url = isset( $_POST['originUrl'] ) ? esc_url_raw( wp_unslash( $_POST['originUrl'] ) ) : '';
+
$api_host = Cliengo_Form::PROD_ENV ? 'https://api.cliengo.com' : 'https://api.stagecliengo.com';
$lang = get_locale();
- $body = array('username' => $_POST['username'],
- 'email' => $_POST['email'],
- 'password' => $_POST['password'],
- 'sourceName' => $_POST['sourceName'],
- 'accountName' => $_POST['accountName'],
+ $body = array(
+ 'username' => $username,
+ 'email' => $email,
+ 'password' => $password,
+ 'sourceName' => $source_name,
+ 'accountName' => $account_name,
'language' => substr($lang, 0, 2),
- 'originUrl' => $_POST['originUrl']
+ 'originUrl' => $origin_url
);
$api_response = wp_remote_request("$api_host/1.0/wordpress/signup", array(
@@ -274,8 +360,13 @@
'content-type' => 'application/json',
),
'body' => wp_json_encode($body),
- 'timeout' => 30 // Default is 5 seconds
+ 'timeout' => 30
));
+
+ if ( is_wp_error( $api_response ) ) {
+ wp_die( 'Error: Could not connect to Cliengo API.', 500 );
+ }
+
echo wp_json_encode($api_response['body']);
wp_die('', esc_html($api_response['response']['code']));
}
--- a/cliengo/admin/partials/cliengo-admin-display.php
+++ b/cliengo/admin/partials/cliengo-admin-display.php
@@ -17,6 +17,7 @@
<?php wp_nonce_field('update_session_action', 'update_session_nonce'); ?>
<?php wp_nonce_field('wordpress_login_action', 'wordpress_login_nonce'); ?>
<?php wp_nonce_field('wp_registration_action', 'wp_registration_nonce'); ?>
+<?php wp_nonce_field('restore_session_action', 'restore_session_nonce'); ?>
<script type="text/javascript">
var ajaxurl = "<?php echo esc_url(admin_url('admin-ajax.php')); ?>";
var siteUrl = "<?php echo esc_url(get_site_url()); ?>";
@@ -32,6 +33,7 @@
<input type="hidden" id="update_session_nonce" name="update_session_nonce" value="<?php echo esc_attr(wp_create_nonce('update_session_action')); ?>" />
<input type="hidden" id="wordpress_login_nonce" name="wordpress_login_nonce" value="<?php echo esc_attr(wp_create_nonce('wordpress_login_action')); ?>" />
<input type="hidden" id="wp_registration_nonce" name="wp_registration_nonce" value="<?php echo esc_attr(wp_create_nonce('wp_registration_action')); ?>" />
+ <input type="hidden" id="restore_session_nonce" name="restore_session_nonce" value="<?php echo esc_attr(wp_create_nonce('restore_session_action')); ?>" />
<div class="container" style="margin-top: 5%" v-if="!loading.rendering">
<div class="row col-lg-12" style="margin-bottom: 20px;">
<?php echo '<img src="'. esc_url(plugin_dir_url(__FILE__)) . '../images/logo.png'.'" alt="">' ?>
--- a/cliengo/cliengo.php
+++ b/cliengo/cliengo.php
@@ -16,7 +16,7 @@
* Plugin Name: Cliengo - Chatbot
* Plugin URI: http://cliengo.com/?utm_source=wordpress_plugin&utm_medium=wordpress
* Description: Cliengo helps you escalate your business process by automating the different points of contact with your customers and providing 24/7 responses. Multi-language: English/Spanish/Portuguese
- * Version: 3.0.4
+ * Version: 3.0.5
* Author: Cliengo
* Author URI: http://cliengo.com/?utm_source=wordpress_plugin&utm_medium=wordpress
* License: GPL-2.0+
@@ -39,7 +39,7 @@
* Start at version 1.0.0 and use SemVer - https://semver.org
* Rename this for your plugin and update it as you release new versions.
*/
-define( 'CLIENGO_VERSION', '3.0.4' );
+define( 'CLIENGO_VERSION', '3.0.5' );
/**
* The code that runs during plugin activation.
--- a/cliengo/includes/class-cliengo.php
+++ b/cliengo/includes/class-cliengo.php
@@ -164,13 +164,11 @@
$this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_scripts' );
$this->loader->add_action( 'admin_menu', $plugin_admin, 'cliengo_options_page' );
$this->loader->add_action( 'wp_ajax_update_chatbot_token', $plugin_admin_form, 'update_chatbot_token' );
- $this->loader->add_action( 'wp_ajax_nopriv_update_chatbot_token', $plugin_admin_form, 'update_chatbot_token' );
$this->loader->add_action( 'wp_ajax_wordpress_login', $plugin_admin_form, 'wordpress_login' );
- $this->loader->add_action('wp_ajax_wp_registration', $plugin_admin_form, 'wp_registration');
- $this->loader->add_action( 'wp_ajax_nopriv_wp_registration', $plugin_admin_form, 'wp_registration' );
- $this->loader->add_action('wp_ajax_update_session', $plugin_admin_form, 'update_session');
- $this->loader->add_action('wp_ajax_update_chatbot_position', $plugin_admin_form, 'update_chatbot_position');
- $this->loader->add_action('wp_ajax_restore_session', $plugin_admin_form, 'restore_session');
+ $this->loader->add_action( 'wp_ajax_wp_registration', $plugin_admin_form, 'wp_registration' );
+ $this->loader->add_action( 'wp_ajax_update_session', $plugin_admin_form, 'update_session' );
+ $this->loader->add_action( 'wp_ajax_update_chatbot_position', $plugin_admin_form, 'update_chatbot_position' );
+ $this->loader->add_action( 'wp_ajax_restore_session', $plugin_admin_form, 'restore_session' );
}
/**