From df91d2b1ba8c9fbf91a6ce8032616831303b4306 Mon Sep 17 00:00:00 2001 From: AntonV1211 Date: Fri, 4 Sep 2026 13:52:02 +0700 Subject: [PATCH 1/3] Fix. RemoteCalls. Edits by update_settings --- cleantalk.php | 29 ------------------- .../PluginSettingsPage/SettingsField.php | 13 +++++++-- lib/Cleantalk/ApbctWP/RemoteCalls.php | 9 ------ lib/Cleantalk/ApbctWP/State.php | 1 - 4 files changed, 10 insertions(+), 42 deletions(-) diff --git a/cleantalk.php b/cleantalk.php index 791a47555..93138042c 100644 --- a/cleantalk.php +++ b/cleantalk.php @@ -2349,35 +2349,6 @@ function apbct_rc__uninstall_plugin__check_deactivate() $apbct->plugin_deactivated = true; } -/** - * @param $source - * - * @return bool - */ -function apbct_rc__update_settings($source) -{ - global $apbct; - - foreach ( $apbct->default_settings as $setting => $def_value ) { - if ( array_key_exists($setting, $source) ) { - if ($setting === 'apikey') { - continue; - } - $var = $source[$setting]; - $type = gettype($def_value); - settype($var, $type); - if ( $type === 'string' ) { - $var = preg_replace(array('/=/', '/`/'), '', $var); - } - $apbct->settings[$setting] = $var; - } - } - - $apbct->save('settings'); - - return true; -} - /** * @param string $key * @param string $plugin diff --git a/lib/Cleantalk/ApbctWP/PluginSettingsPage/SettingsField.php b/lib/Cleantalk/ApbctWP/PluginSettingsPage/SettingsField.php index 824d3d166..9a2a3d73a 100644 --- a/lib/Cleantalk/ApbctWP/PluginSettingsPage/SettingsField.php +++ b/lib/Cleantalk/ApbctWP/PluginSettingsPage/SettingsField.php @@ -412,7 +412,7 @@ private function getInputText() $data = [ 'name' => isset($this->params['name']) ? $this->params['name'] : '', 'type' => isset($this->params['type']) ? $this->params['type'] : '', - 'value' => $this->value, + 'value' => esc_attr(is_array($this->value) ? implode(', ', $this->value) : (string)$this->value), 'placeholder' => isset($this->params['placeholder']) ? 'placeholder="' . $this->params['placeholder'] . '"' : '', 'disabled' => $this->disabled_string, 'required' => isset($this->params['required']) && $this->params['required'] ? 'required="required"' : '', @@ -482,6 +482,11 @@ private function getInputTextarea() { $title_layout = '

{{title}} {{popup_description}}

'; + $raw_value = empty($this->value) ? TT::getArrayValueAsString($this->params, 'value') : $this->value; + if (is_array($raw_value)) { + $raw_value = implode(', ', $raw_value); + } + $data = [ 'title' => isset($this->params['title']) ? $this->params['title'] : '', 'type' => isset($this->params['type']) ? $this->params['type'] : '', @@ -491,7 +496,9 @@ private function getInputTextarea() 'disabled' => $this->disabled_string, 'required' => isset($this->params['required']) && $this->params['required'] ? 'required="required"' : '', 'childrens' => isset($this->params['childrens']) ? 'onchange="apbctSettingsDependencies(\'' . $this->children_string . '\')" ' : '', - 'value' => empty($this->value) ? TT::getArrayValueAsString($this->params, 'value') : $this->value, + // Escape stored setting to keep any HTML/JS in textarea content inert (defense-in-depth against tainted + // stored values that may have bypassed setting validation). + 'value' => esc_textarea((string)$raw_value), ]; $layout = ''; @@ -519,7 +526,7 @@ private function getInputColor() $data = [ 'name' => isset($this->params['name']) ? $this->params['name'] : '', 'type' => isset($this->params['type']) ? $this->params['type'] : '', - 'value' => $this->value, + 'value' => esc_attr(is_array($this->value) ? implode(', ', $this->value) : (string)$this->value), 'disabled' => $this->disabled_string, 'required' => isset($this->params['required']) && $this->params['required'] ? 'required="required"' : '', 'childrens' => isset($this->params['childrens']) ? 'onchange="apbctSettingsDependencies(\'' . $this->children_string . '\')" ' : '', diff --git a/lib/Cleantalk/ApbctWP/RemoteCalls.php b/lib/Cleantalk/ApbctWP/RemoteCalls.php index a14c19c3a..9be3b865e 100644 --- a/lib/Cleantalk/ApbctWP/RemoteCalls.php +++ b/lib/Cleantalk/ApbctWP/RemoteCalls.php @@ -399,15 +399,6 @@ public static function action__activate_plugin() // phpcs:ignore PSR1.Methods.Ca return apbct_rc__activate_plugin(Request::get('plugin')); } - /** - * Update settings. - * @deprecated Since 6.85, see https://app.doboard.com/1/task/36680 - */ - public static function action__update_settings() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps - { - return apbct_rc__update_settings($_REQUEST); - } - /** * Deactivate plugin */ diff --git a/lib/Cleantalk/ApbctWP/State.php b/lib/Cleantalk/ApbctWP/State.php index e0d637726..53c0ff27b 100644 --- a/lib/Cleantalk/ApbctWP/State.php +++ b/lib/Cleantalk/ApbctWP/State.php @@ -285,7 +285,6 @@ class State extends \Cleantalk\Common\State //Common 'close_renew_banner' => array('last_call' => 0, 'cooldown' => 0), 'check_website' => array('last_call' => 0, 'cooldown' => 0), - 'update_settings' => array('last_call' => 0, 'cooldown' => 0), 'run_service_template_get' => array('last_call' => 0, 'cooldown' => 60), 'license_update' => array('last_call' => 0, 'cooldown' => 0), From 454a505c0eee71b1e118dc8a7cbeb9a5e437eb20 Mon Sep 17 00:00:00 2001 From: AntonV1211 Date: Fri, 4 Sep 2026 13:53:46 +0700 Subject: [PATCH 2/3] Fix. RemoteCalls. Edits by update_settings --- lib/Cleantalk/ApbctWP/PluginSettingsPage/SettingsField.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/Cleantalk/ApbctWP/PluginSettingsPage/SettingsField.php b/lib/Cleantalk/ApbctWP/PluginSettingsPage/SettingsField.php index 9a2a3d73a..a4fc546f4 100644 --- a/lib/Cleantalk/ApbctWP/PluginSettingsPage/SettingsField.php +++ b/lib/Cleantalk/ApbctWP/PluginSettingsPage/SettingsField.php @@ -496,8 +496,6 @@ private function getInputTextarea() 'disabled' => $this->disabled_string, 'required' => isset($this->params['required']) && $this->params['required'] ? 'required="required"' : '', 'childrens' => isset($this->params['childrens']) ? 'onchange="apbctSettingsDependencies(\'' . $this->children_string . '\')" ' : '', - // Escape stored setting to keep any HTML/JS in textarea content inert (defense-in-depth against tainted - // stored values that may have bypassed setting validation). 'value' => esc_textarea((string)$raw_value), ]; From 531914184584241f8e16e0687821db6b145d8372 Mon Sep 17 00:00:00 2001 From: AntonV1211 Date: Fri, 4 Sep 2026 16:40:54 +0700 Subject: [PATCH 3/3] Fix. Code. Edit check_value --- cleantalk.php | 4 ++-- tests/RootFile/TestCheckValueSalt.php | 16 +++++++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/cleantalk.php b/cleantalk.php index 93138042c..2d49bd553 100644 --- a/cleantalk.php +++ b/cleantalk.php @@ -2627,7 +2627,7 @@ function apbct_cookie() // Cookie names to validate $cookie_test_value = array( 'cookies_names' => array(), - 'check_value' => $apbct->api_key . $apbct->data['salt'], + 'check_value' => $apbct->api_key . $apbct->data['salt'] . '_apbct_cookies_test', ); // We need to skip the domain attribute for prevent including the dot to the cookie's domain on the client. @@ -2722,7 +2722,7 @@ function apbct_cookies_test() return 0; } - $check_string = $apbct->api_key . $apbct->data['salt']; + $check_string = $apbct->api_key . $apbct->data['salt'] . '_apbct_cookies_test'; // generate value $cookie_names = TT::getArrayValueAsArray($cookie_test, 'cookies_names'); foreach ( $cookie_names as $cookie_name ) { diff --git a/tests/RootFile/TestCheckValueSalt.php b/tests/RootFile/TestCheckValueSalt.php index e64d1be33..aa3c53e1d 100644 --- a/tests/RootFile/TestCheckValueSalt.php +++ b/tests/RootFile/TestCheckValueSalt.php @@ -49,18 +49,24 @@ public function testCheckValueWithSaltDiffersFromWithout() { global $apbct; - $with_salt = md5($apbct->api_key . $apbct->data['salt']); + $with_suffix = md5($apbct->api_key . $apbct->data['salt'] . '_apbct_cookies_test'); $without_salt = md5($apbct->api_key); + $rc_bearer = md5($apbct->api_key . $apbct->data['salt']); $this->assertNotEquals( $without_salt, - $with_salt, + $with_suffix, 'check_value must not equal md5(api_key) alone - salt must change the hash' ); + $this->assertNotEquals( + $rc_bearer, + $with_suffix, + 'check_value must not equal the RC bearer md5(api_key + salt) - purpose suffix must domain-separate it' + ); } /** - * Test that apbct_cookies_test() validates a cookie computed WITH salt. + * Test that apbct_cookies_test() validates a cookie computed WITH salt and purpose suffix. */ public function testApbctCookiesTestValidatesWithSalt() { @@ -68,7 +74,7 @@ public function testApbctCookiesTestValidatesWithSalt() $cookie_test_value = array( 'cookies_names' => array(), - 'check_value' => md5($apbct->api_key . $apbct->data['salt']), + 'check_value' => md5($apbct->api_key . $apbct->data['salt'] . '_apbct_cookies_test'), ); $cookie_prefix = function_exists('apbct__get_cookie_prefix') ? apbct__get_cookie_prefix() : ''; @@ -111,7 +117,7 @@ public function testApbctCookiesTestValidatesWithSaltAndTimestamp() $cookie_test_value = array( 'cookies_names' => array('ct_ps_timestamp'), - 'check_value' => md5($apbct->api_key . $apbct->data['salt'] . $timestamp), + 'check_value' => md5($apbct->api_key . $apbct->data['salt'] . '_apbct_cookies_test' . $timestamp), ); $cookie_prefix = function_exists('apbct__get_cookie_prefix') ? apbct__get_cookie_prefix() : '';