Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions cleantalk/config.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
<?php

//warning: do not use ";" symbol in strings without serialization!
//Settings
$antispam_activity_status = true;
$registrations_test = true;
$general_postdata_test = false;
$spam_firewall = true;
$general_post_exclusion_usage = false;
// exclusion by service field
$service_field_in_post_exclusion_enabled = false;
//form post data signs exclusions
$form_post_exclusions_enabled = false;
$form_post_signs_exclusions_set = array (
);

// Statistics
$sfw_last_update = 0;
Expand Down
135 changes: 131 additions & 4 deletions cleantalk/inc/admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ function uninstall( $files = array() ){
File::replace__variable( $path_to_config, 'registrations_test', true );
File::replace__variable( $path_to_config, 'general_postdata_test', false );
File::replace__variable( $path_to_config, 'spam_firewall', true );
File::replace__variable( $path_to_config, 'general_post_exclusion_usage', false );
File::replace__variable( $path_to_config, 'service_field_in_post_exclusion_enabled', false );

// Deleting cron tasks
File::replace__variable( CLEANTALK_CRON_FILE, 'tasks', array() );
Expand Down Expand Up @@ -300,13 +300,13 @@ function apbct__plugin_update_message() {
*/
function apbct__cscart_js_snippet() {
global $apikey, $apbct_salt, $detected_cms;

// Only for CsCart
if ($detected_cms != 'cscart') return;

$apbct_checkjs_hash = apbct_checkjs_hash($apikey, $apbct_salt);
?>

<div class="highlight">
<h4>Add this code to all pages of the site (use the basic template). Detailed instruction is <a href="https://blog.cleantalk.org/protecting-cs-cart-website-from-spam/">here</a></h4>
<pre tabindex="0" class="chroma">
Expand All @@ -320,3 +320,130 @@ function apbct__cscart_js_snippet() {

<?php
}

/**
* @return string
*/
function apbct__prepare_form_sign_exclusions_textarea()
{
global $form_post_signs_exclusions_set;

if (!is_array($form_post_signs_exclusions_set)) {
$form_post_signs_exclusions_set = array();
}

$hint_text = 'Regular expression. If the form contains any of these signs in POST array keys or in value of "action" key, the whole form submission is excluded from spam checking.';
$link_learn_more = 'https://cleantalk.org/help/exclusion-by-form-signs?utm_id=&utm_term=&utm_source=admin_panel&utm_medium=settings&utm_content=uni_hint_exclusions__form_signs&utm_campaign=uni_links';

$template = '
<p>%s</br><span style="%s"><a href="%s" target="_blank">Learn more</a></span></p>
<textarea id="form_signs_exclusions-textarea" name="form_signs_exclusions-textarea" style="%s">%s</textarea>
';
$signs = '';
foreach ( $form_post_signs_exclusions_set as $sign) {
if (is_string($sign)) {
$signs .= $sign . "\r\n";
}
}

$style_textarea = 'word-break: break-all; padding: 1%; background: #fff; width: 100%';
$style_span = 'display: flex; justify-content: flex-end; margin: 1%';

return sprintf($template, $hint_text, $style_span, $link_learn_more, $style_textarea, htmlspecialchars($signs));
}

function apbct__prepare_service_field_exclusion_layout()
{
global $exclusion_key;

if (!empty($exclusion_key)) {
$service_field = htmlspecialchars('<input id="any_id_1" name="ct_service_data" type="hidden" value="'. $exclusion_key .'">');
} else {
$service_field = 'Error! Can not gain exclusion key.';
}

$hint_text = 'Regular expression. If the form contains any of these signs in POST array keys or in value of "action" key, the whole form submission is excluded from spam checking.';
$style = 'border: solid 1px; word-break: break-all; padding: 1%; background: #fff;';

$template = '
<p>%s</p>
<div id="exclusion-html" style="%s">
%s
</div>
';

return $exclusion_key ? sprintf($template, $hint_text, $style, $service_field) : $service_field;
}
/**
* Sanitize and validate exclusions.
* Explode given string by commas and trim each string.
* Cut first 20 entities if more than 20 given. Remove duplicates.
* Skip element if it's empty. Validate entity as URL. Cut first 128 chars if more than 128 given
*
* Return false if exclusion is bad
* Return sanitized string if all is ok
*
* @param string $exclusions
* @param bool $regexp
*
* @return bool|string|array
*/
function apbct_settings__sanitize__exclusions($exclusions, $return_array = false, $regexp = true, $urls = false)
{
if ( ! is_string($exclusions) ) {
return false;
}

$result = array();
$type = 0;

if ( ! empty($exclusions) ) {
if ( strpos($exclusions, "\r\n") !== false ) {
$exclusions = explode("\r\n", $exclusions);
$type = 2;
} elseif ( strpos($exclusions, "\n") !== false ) {
$exclusions = explode("\n", $exclusions);
$type = 1;
} else {
$exclusions = explode(',', $exclusions);
}
//Drop duplicates first (before cut)
$exclusions = array_unique($exclusions);
//Take first 20 exclusions entities
$exclusions = array_slice($exclusions, 0, 20);
//Sanitizing
foreach ($exclusions as $exclusion) {
//Cut exclusion if more than 128 symbols gained
$sanitized_exclusion = substr($exclusion, 0, 128);
$sanitized_exclusion = trim($sanitized_exclusion);

if ( ! empty($sanitized_exclusion) ) {
if ( $regexp ) {
if ( @preg_match('/' . $exclusion . '/', '') === false) {
return false;
}
} elseif ( $urls ) {
if (
( strpos($exclusion, 'http://') !== false || strpos($exclusion, 'https://') !== false ) &&
filter_var($exclusion, FILTER_VALIDATE_URL)
) {
return false;
}
}
$result[] = $sanitized_exclusion;
}
}
}
if ($return_array) {
return $result;
}
switch ( $type ) {
case 0:
default:
return implode(',', $result);
case 1:
return implode("\n", $result);
case 2:
return implode("\r\n", $result);
}
}
66 changes: 46 additions & 20 deletions cleantalk/inc/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ function apbct_spam_test($data){
$registrations_test,
$general_postdata_test,
$detected_cms,
$exclusion_key,
$general_post_exclusion_usage;
$form_post_signs_exclusions_set;

// Patch for old PHP versions.
require_once( CLEANTALK_ROOT . 'lib' . DS . 'ct_phpFix.php');
Expand Down Expand Up @@ -64,15 +63,6 @@ function apbct_spam_test($data){
$registration = true;
}

//init exclusions array if general_post_exclusion_usage is enabled
if ( isset($exclusion_key, $general_post_exclusion_usage) && $general_post_exclusion_usage ) {
$exclusions_in_post = array(
'ct_service_data' => $exclusion_key,
);
} else {
$exclusions_in_post = array();
}

$url_exclusions = array();

if (
Expand All @@ -86,15 +76,13 @@ function apbct_spam_test($data){
);
}



// Skip check if
if ( $skip || // Skip flag set by apbct_get_fields_any()
(!$sender_email && !$general_postdata_test) || // No email detected and general post data test is disabled
($registration && !$registrations_test) || // It's registration and registration check is disabled
(apbct_check__exclusions()) || // main exclusion function
(apbct_check__exclusions_in_post($exclusions_in_post)) || // Has an exclusions in POST
(apbct_check__url_exclusions($url_exclusions)) // Has an exclusions in URL
(apbct_check__exclusions_general()) || // main exclusion function
(apbct_check__url_exclusions($url_exclusions)) || // Has an exclusions in URL
(apbct_check__form_signs_exclusions($data, $form_post_signs_exclusions_set)) // Has an exclusions in POST fields
) {
$skip = true;
}
Expand Down Expand Up @@ -497,13 +485,12 @@ function apbct_check__url_exclusions( $exclusions = array() ){
global $detected_cms;

//custom login word transform ruleset
$login_word = 'login';
if ( isset($detected_cms) ) {
switch ( $detected_cms ) {
//moodle case
case 'moodle':
{
$login_word = 'login/index.php';
$exclusions[] = 'login/index.php';
break;
}
case 'OpenMage':
Expand All @@ -514,7 +501,6 @@ function apbct_check__url_exclusions( $exclusions = array() ){
}
}
}
$exclusions[] = $login_word;

foreach ( $exclusions as $name => $exclusion ){
if( \Cleantalk\Variables\Server::has_string('REQUEST_URI', $exclusion ) ){
Expand All @@ -525,10 +511,42 @@ function apbct_check__url_exclusions( $exclusions = array() ){
return false;
}

/**
* Check POST array for the exclusion form signs. Listen for array keys or for value in case if key is "action".
* @param array $form_data The POST array or another filtered array of form data.
* @param array $exclusions
* @return bool True if exclusion found in the keys of array, false otherwise.
*/
function apbct_check__form_signs_exclusions($form_data, $exclusions)
{
if ( is_array($exclusions) && is_array($form_data) ) {
foreach ( $exclusions as $exclusion ) {
foreach ($form_data as $key => $value) {
if ( !empty($value) && is_array($value) ) {
if ( apbct_check__form_signs_exclusions($value, $exclusions) ) {
return true;
}
}
$haystack = ($key === 'action' || $key === 'data') ? $value : $key;
if (
$haystack === $exclusion ||
(is_string($haystack) && stripos($haystack, $exclusion) !== false) ||
(is_string($haystack) && preg_match('@' . $exclusion . '@', $haystack) === 1)
) {
return true;
}
}
}
return false;
}
return false;
}


/**
* Another function for excluding validation based on any number of parameters
*/
function apbct_check__exclusions() {
function apbct_check__exclusions_general() {

global $detected_cms;

Expand Down Expand Up @@ -573,6 +591,14 @@ function apbct_check__exclusions() {
return true;
}

//init exclusions array if service_field_in_post_exclusion is enabled
if ( isset($exclusion_key, $service_field_in_post_exclusion_enabled) && $service_field_in_post_exclusion_enabled ) {
$service_field_exclusion = array(
'ct_service_data' => $exclusion_key,
);
return apbct_check__exclusions_in_post($service_field_exclusion);
}

if (\Cleantalk\Variables\Get::equal('controller', 'ajax') &&
\Cleantalk\Variables\Get::equal('do', 'passwordStrength')
) {
Expand Down
18 changes: 15 additions & 3 deletions cleantalk/js/custom.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,23 @@ jQuery(document).ready(function($) {
});

//set the block with special tag in dependence of post_exclusion_usage statement
$('#general_post_exclusion_usage').on('click', function(event) {
$('#service_field_in_post_exclusion_enabled').on('click', function(event) {
let state = 'none'
if ($('#general_post_exclusion_usage').prop('checked')){
if ($('#service_field_in_post_exclusion_enabled').prop('checked')){
state = 'inherit'
}
$('#exclusions-div').css('display',state)
});

//show array of exclusions
$('#form_post_exclusions_signs_usage').on('click', function(event) {
let state = 'none'
if ($('#form_post_exclusions_signs_usage').prop('checked')){
state = 'inherit'
}
$('#form_signs_exclusions-div').css('display',state)
});


$('#btn-login').on('click', function(event) {
login();
Expand Down Expand Up @@ -290,7 +299,10 @@ jQuery(document).ready(function($) {
registrations_test: $('#check_reg').is(':checked') ? 1 : 0,
general_postdata_test: $('#check_without_email').is(':checked') ? 1 : 0,
spam_firewall: $('#enable_sfw').is(':checked') ? 1 : 0,
general_post_exclusion_usage: $('#general_post_exclusion_usage').is(':checked') ? 1 : 0,
service_field_in_post_exclusion_enabled: $('#service_field_in_post_exclusion_enabled').is(':checked') ? 1 : 0,
// form post signs exclusion
form_post_exclusions_enabled: $('#form_post_exclusions_signs_usage').is(':checked') ? 1 : 0,
form_post_exclusions_signs_string: $('textarea#form_signs_exclusions-textarea').val(),
},
{
callback: function(result, data, params, obj) {
Expand Down
10 changes: 6 additions & 4 deletions cleantalk/lib/Cleantalk/Antispam/Cleantalk.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class Cleantalk {
/**
* Function checks whether it is possible to publish the message
* @param CleantalkRequest $request
* @return type
* @return CleantalkResponse
*/
public function isAllowMessage(CleantalkRequest $request) {
$msg = $this->createMsg('check_message', $request);
Expand Down Expand Up @@ -242,7 +242,7 @@ function_exists('base64_encode')
/**
* httpRequest
* @param $msg
* @return boolean|CleantalkResponse
* @return CleantalkResponse
*/
private function httpRequest($msg) {

Expand Down Expand Up @@ -375,8 +375,10 @@ public function get_servers_ip($host)

/**
* Send JSON request to servers
* @param $msg
* @return boolean|\CleantalkResponse
* @param $url
* @param $data
* @param $server_timeout
* @return boolean|CleantalkResponse
*/
private function sendRequest($url, $data, $server_timeout = 3)
{
Expand Down
Loading