Changeset 3402920
- Timestamp:
- 11/25/2025 11:38:59 PM (4 months ago)
- Location:
- cf7-antispam
- Files:
-
- 175 added
- 26 edited
-
tags/0.7.2 (added)
-
tags/0.7.2/LICENSE (added)
-
tags/0.7.2/admin (added)
-
tags/0.7.2/admin/CF7_AntiSpam_Admin_Charts.php (added)
-
tags/0.7.2/admin/CF7_AntiSpam_Admin_Core.php (added)
-
tags/0.7.2/admin/CF7_AntiSpam_Admin_Customizations.php (added)
-
tags/0.7.2/admin/CF7_AntiSpam_Admin_Display.php (added)
-
tags/0.7.2/admin/CF7_AntiSpam_Admin_Tools.php (added)
-
tags/0.7.2/assets (added)
-
tags/0.7.2/assets/icon.svg (added)
-
tags/0.7.2/build (added)
-
tags/0.7.2/build/admin-scripts-rtl.css (added)
-
tags/0.7.2/build/admin-scripts.asset.php (added)
-
tags/0.7.2/build/admin-scripts.css (added)
-
tags/0.7.2/build/admin-scripts.js (added)
-
tags/0.7.2/build/script.asset.php (added)
-
tags/0.7.2/build/script.js (added)
-
tags/0.7.2/cf7-antispam.php (added)
-
tags/0.7.2/composer.json (added)
-
tags/0.7.2/core (added)
-
tags/0.7.2/core/CF7_AntiSpam.php (added)
-
tags/0.7.2/core/CF7_AntiSpam_B8.php (added)
-
tags/0.7.2/core/CF7_AntiSpam_Filters.php (added)
-
tags/0.7.2/core/CF7_AntiSpam_Flamingo.php (added)
-
tags/0.7.2/core/CF7_AntiSpam_Frontend.php (added)
-
tags/0.7.2/core/CF7_AntiSpam_Loader.php (added)
-
tags/0.7.2/core/CF7_AntiSpam_Rest_Api.php (added)
-
tags/0.7.2/core/CF7_AntiSpam_i18n.php (added)
-
tags/0.7.2/core/CF7_Antispam_Blacklist.php (added)
-
tags/0.7.2/core/CF7_Antispam_Geoip.php (added)
-
tags/0.7.2/core/CF7_Antispam_Service.php (added)
-
tags/0.7.2/core/b8 (added)
-
tags/0.7.2/core/b8/README.md (added)
-
tags/0.7.2/core/b8/README.md.license (added)
-
tags/0.7.2/core/b8/b8 (added)
-
tags/0.7.2/core/b8/b8/b8.php (added)
-
tags/0.7.2/core/b8/b8/degenerator (added)
-
tags/0.7.2/core/b8/b8/degenerator/standard.php (added)
-
tags/0.7.2/core/b8/b8/lexer (added)
-
tags/0.7.2/core/b8/b8/lexer/standard.php (added)
-
tags/0.7.2/core/b8/b8/storage (added)
-
tags/0.7.2/core/b8/b8/storage/dba.php (added)
-
tags/0.7.2/core/b8/b8/storage/mysql.php (added)
-
tags/0.7.2/core/b8/b8/storage/sqlite.php (added)
-
tags/0.7.2/core/b8/b8/storage/storage_base.php (added)
-
tags/0.7.2/core/functions.php (added)
-
tags/0.7.2/engine (added)
-
tags/0.7.2/engine/CF7_AntiSpam_Activator.php (added)
-
tags/0.7.2/engine/CF7_AntiSpam_Deactivator.php (added)
-
tags/0.7.2/engine/CF7_AntiSpam_Uninstaller.php (added)
-
tags/0.7.2/engine/CF7_AntiSpam_Updater.php (added)
-
tags/0.7.2/languages (added)
-
tags/0.7.2/languages/cf7-antispam.pot (added)
-
tags/0.7.2/languages/readme.txt (added)
-
tags/0.7.2/package.json (added)
-
tags/0.7.2/readme.txt (added)
-
tags/0.7.2/vendor (added)
-
tags/0.7.2/vendor/autoload.php (added)
-
tags/0.7.2/vendor/composer (added)
-
tags/0.7.2/vendor/composer/ClassLoader.php (added)
-
tags/0.7.2/vendor/composer/InstalledVersions.php (added)
-
tags/0.7.2/vendor/composer/LICENSE (added)
-
tags/0.7.2/vendor/composer/autoload_classmap.php (added)
-
tags/0.7.2/vendor/composer/autoload_namespaces.php (added)
-
tags/0.7.2/vendor/composer/autoload_psr4.php (added)
-
tags/0.7.2/vendor/composer/autoload_real.php (added)
-
tags/0.7.2/vendor/composer/autoload_static.php (added)
-
tags/0.7.2/vendor/composer/ca-bundle (added)
-
tags/0.7.2/vendor/composer/ca-bundle/LICENSE (added)
-
tags/0.7.2/vendor/composer/ca-bundle/README.md (added)
-
tags/0.7.2/vendor/composer/ca-bundle/composer.json (added)
-
tags/0.7.2/vendor/composer/ca-bundle/res (added)
-
tags/0.7.2/vendor/composer/ca-bundle/res/cacert.pem (added)
-
tags/0.7.2/vendor/composer/ca-bundle/src (added)
-
tags/0.7.2/vendor/composer/ca-bundle/src/CaBundle.php (added)
-
tags/0.7.2/vendor/composer/installed.json (added)
-
tags/0.7.2/vendor/composer/installed.php (added)
-
tags/0.7.2/vendor/geoip2 (added)
-
tags/0.7.2/vendor/geoip2/geoip2 (added)
-
tags/0.7.2/vendor/geoip2/geoip2/CHANGELOG.md (added)
-
tags/0.7.2/vendor/geoip2/geoip2/LICENSE (added)
-
tags/0.7.2/vendor/geoip2/geoip2/README.md (added)
-
tags/0.7.2/vendor/geoip2/geoip2/composer.json (added)
-
tags/0.7.2/vendor/geoip2/geoip2/examples (added)
-
tags/0.7.2/vendor/geoip2/geoip2/examples/benchmark.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Database (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Database/Reader.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Exception (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Exception/AddressNotFoundException.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Exception/AuthenticationException.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Exception/GeoIp2Exception.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Exception/HttpException.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Exception/InvalidRequestException.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Exception/OutOfQueriesException.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Model (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Model/AbstractModel.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Model/AnonymousIp.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Model/Asn.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Model/City.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Model/ConnectionType.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Model/Country.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Model/Domain.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Model/Enterprise.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Model/Insights.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Model/Isp.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/ProviderInterface.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Record (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Record/AbstractPlaceRecord.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Record/AbstractRecord.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Record/City.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Record/Continent.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Record/Country.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Record/Location.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Record/MaxMind.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Record/Postal.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Record/RepresentedCountry.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Record/Subdivision.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Record/Traits.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/Util.php (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/WebService (added)
-
tags/0.7.2/vendor/geoip2/geoip2/src/WebService/Client.php (added)
-
tags/0.7.2/vendor/maxmind (added)
-
tags/0.7.2/vendor/maxmind-db (added)
-
tags/0.7.2/vendor/maxmind-db/reader (added)
-
tags/0.7.2/vendor/maxmind-db/reader/CHANGELOG.md (added)
-
tags/0.7.2/vendor/maxmind-db/reader/LICENSE (added)
-
tags/0.7.2/vendor/maxmind-db/reader/README.md (added)
-
tags/0.7.2/vendor/maxmind-db/reader/autoload.php (added)
-
tags/0.7.2/vendor/maxmind-db/reader/composer.json (added)
-
tags/0.7.2/vendor/maxmind-db/reader/ext (added)
-
tags/0.7.2/vendor/maxmind-db/reader/ext/config.m4 (added)
-
tags/0.7.2/vendor/maxmind-db/reader/ext/config.w32 (added)
-
tags/0.7.2/vendor/maxmind-db/reader/ext/maxminddb.c (added)
-
tags/0.7.2/vendor/maxmind-db/reader/ext/php_maxminddb.h (added)
-
tags/0.7.2/vendor/maxmind-db/reader/ext/tests (added)
-
tags/0.7.2/vendor/maxmind-db/reader/ext/tests/001-load.phpt (added)
-
tags/0.7.2/vendor/maxmind-db/reader/ext/tests/002-final.phpt (added)
-
tags/0.7.2/vendor/maxmind-db/reader/ext/tests/003-open-basedir.phpt (added)
-
tags/0.7.2/vendor/maxmind-db/reader/package.xml (added)
-
tags/0.7.2/vendor/maxmind-db/reader/src (added)
-
tags/0.7.2/vendor/maxmind-db/reader/src/MaxMind (added)
-
tags/0.7.2/vendor/maxmind-db/reader/src/MaxMind/Db (added)
-
tags/0.7.2/vendor/maxmind-db/reader/src/MaxMind/Db/Reader (added)
-
tags/0.7.2/vendor/maxmind-db/reader/src/MaxMind/Db/Reader.php (added)
-
tags/0.7.2/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Decoder.php (added)
-
tags/0.7.2/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/InvalidDatabaseException.php (added)
-
tags/0.7.2/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Metadata.php (added)
-
tags/0.7.2/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Util.php (added)
-
tags/0.7.2/vendor/maxmind/web-service-common (added)
-
tags/0.7.2/vendor/maxmind/web-service-common/CHANGELOG.md (added)
-
tags/0.7.2/vendor/maxmind/web-service-common/LICENSE (added)
-
tags/0.7.2/vendor/maxmind/web-service-common/README.md (added)
-
tags/0.7.2/vendor/maxmind/web-service-common/composer.json (added)
-
tags/0.7.2/vendor/maxmind/web-service-common/dev-bin (added)
-
tags/0.7.2/vendor/maxmind/web-service-common/dev-bin/release.sh (added)
-
tags/0.7.2/vendor/maxmind/web-service-common/phpstan.neon (added)
-
tags/0.7.2/vendor/maxmind/web-service-common/src (added)
-
tags/0.7.2/vendor/maxmind/web-service-common/src/Exception (added)
-
tags/0.7.2/vendor/maxmind/web-service-common/src/Exception/AuthenticationException.php (added)
-
tags/0.7.2/vendor/maxmind/web-service-common/src/Exception/HttpException.php (added)
-
tags/0.7.2/vendor/maxmind/web-service-common/src/Exception/InsufficientFundsException.php (added)
-
tags/0.7.2/vendor/maxmind/web-service-common/src/Exception/InvalidInputException.php (added)
-
tags/0.7.2/vendor/maxmind/web-service-common/src/Exception/InvalidRequestException.php (added)
-
tags/0.7.2/vendor/maxmind/web-service-common/src/Exception/IpAddressNotFoundException.php (added)
-
tags/0.7.2/vendor/maxmind/web-service-common/src/Exception/PermissionRequiredException.php (added)
-
tags/0.7.2/vendor/maxmind/web-service-common/src/Exception/WebServiceException.php (added)
-
tags/0.7.2/vendor/maxmind/web-service-common/src/WebService (added)
-
tags/0.7.2/vendor/maxmind/web-service-common/src/WebService/Client.php (added)
-
tags/0.7.2/vendor/maxmind/web-service-common/src/WebService/Http (added)
-
tags/0.7.2/vendor/maxmind/web-service-common/src/WebService/Http/CurlRequest.php (added)
-
tags/0.7.2/vendor/maxmind/web-service-common/src/WebService/Http/Request.php (added)
-
tags/0.7.2/vendor/maxmind/web-service-common/src/WebService/Http/RequestFactory.php (added)
-
trunk/admin/CF7_AntiSpam_Admin_Customizations.php (modified) (7 diffs)
-
trunk/admin/CF7_AntiSpam_Admin_Display.php (modified) (3 diffs)
-
trunk/admin/CF7_AntiSpam_Admin_Tools.php (modified) (4 diffs)
-
trunk/cf7-antispam.php (modified) (2 diffs)
-
trunk/composer.json (added)
-
trunk/core/CF7_AntiSpam.php (modified) (2 diffs)
-
trunk/core/CF7_AntiSpam_Filters.php (modified) (8 diffs)
-
trunk/core/CF7_AntiSpam_Flamingo.php (modified) (7 diffs)
-
trunk/core/CF7_AntiSpam_Frontend.php (modified) (10 diffs)
-
trunk/core/CF7_Antispam_Blacklist.php (modified) (4 diffs)
-
trunk/core/functions.php (modified) (2 diffs)
-
trunk/engine/CF7_AntiSpam_Activator.php (modified) (3 diffs)
-
trunk/languages/cf7-antispam.pot (modified) (45 diffs)
-
trunk/package.json (added)
-
trunk/readme.txt (modified) (2 diffs)
-
trunk/vendor/composer/installed.json (modified) (7 diffs)
-
trunk/vendor/composer/installed.php (modified) (4 diffs)
-
trunk/vendor/maxmind-db/reader/CHANGELOG.md (modified) (1 diff)
-
trunk/vendor/maxmind-db/reader/README.md (modified) (4 diffs)
-
trunk/vendor/maxmind-db/reader/composer.json (modified) (2 diffs)
-
trunk/vendor/maxmind-db/reader/ext/php_maxminddb.h (modified) (1 diff)
-
trunk/vendor/maxmind-db/reader/package.xml (modified) (2 diffs)
-
trunk/vendor/maxmind-db/reader/src/MaxMind/Db/Reader.php (modified) (2 diffs)
-
trunk/vendor/maxmind/web-service-common/CHANGELOG.md (modified) (1 diff)
-
trunk/vendor/maxmind/web-service-common/README.md (modified) (1 diff)
-
trunk/vendor/maxmind/web-service-common/composer.json (modified) (1 diff)
-
trunk/vendor/maxmind/web-service-common/src/WebService/Client.php (modified) (9 diffs)
-
trunk/vendor/maxmind/web-service-common/src/WebService/Http/CurlRequest.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
cf7-antispam/trunk/admin/CF7_AntiSpam_Admin_Customizations.php
r3389259 r3402920 573 573 /* Enable customizations */ 574 574 add_settings_field( 575 'cf7a_customizations_class', 576 __( 'Your unique css class', 'cf7-antispam' ), 577 array( $this, 'cf7a_customizations_class_callback' ), 578 'cf7a-settings', 579 'cf7a_customizations' 580 ); 581 582 /* Enable customizations */ 583 add_settings_field( 584 'cf7a_customizations_prefix', 585 __( 'Your unique fields prefix', 'cf7-antispam' ), 586 array( $this, 'cf7a_customizations_prefix_callback' ), 587 'cf7a-settings', 588 'cf7a_customizations' 589 ); 590 591 /* Enable customizations */ 592 add_settings_field( 593 'cf7a_cipher', 594 __( 'The encryption method', 'cf7-antispam' ), 595 array( $this, 'cf7a_customizations_cipher_callback' ), 596 'cf7a-settings', 597 'cf7a_customizations' 598 ); 599 600 /* Section Optimizations */ 601 add_settings_section( 602 'cf7a_optimizations', 603 __( 'Optimizations', 'cf7-antispam' ), 604 array( $this, 'cf7a_optimizations' ), 605 'cf7a-settings' 606 ); 607 608 /* Settings Script optimizations */ 609 add_settings_field( 610 'cf7a_optimizations_scripts', 611 __( 'Optimize scripts loading', 'cf7-antispam' ), 612 array( $this, 'cf7a_optimizations_scripts_callback' ), 613 'cf7a-settings', 614 'cf7a_optimizations' 615 ); 616 617 /* Disable cf7 form reload if the page is cached */ 618 add_settings_field( 575 619 'cf7a_disable_reload', 576 620 __( 'Disable cf7 form reload if the page is cached', 'cf7-antispam' ), 577 621 array( $this, 'cf7a_disable_reload_callback' ), 578 622 'cf7a-settings', 579 'cf7a_customizations' 580 ); 581 582 /* Enable customizations */ 583 add_settings_field( 584 'cf7a_customizations_class', 585 __( 'Your unique css class', 'cf7-antispam' ), 586 array( $this, 'cf7a_customizations_class_callback' ), 587 'cf7a-settings', 588 'cf7a_customizations' 589 ); 590 591 /* Enable customizations */ 592 add_settings_field( 593 'cf7a_customizations_prefix', 594 __( 'Your unique fields prefix', 'cf7-antispam' ), 595 array( $this, 'cf7a_customizations_prefix_callback' ), 596 'cf7a-settings', 597 'cf7a_customizations' 598 ); 599 600 /* Enable customizations */ 601 add_settings_field( 602 'cf7a_cipher', 603 __( 'The encryption method', 'cf7-antispam' ), 604 array( $this, 'cf7a_customizations_cipher_callback' ), 605 'cf7a-settings', 606 'cf7a_customizations' 623 'cf7a_optimizations' 607 624 ); 608 625 … … 1071 1088 $new_input['cf7a_enabled'] = isset( $input['cf7a_enabled'] ) ? 1 : 0; 1072 1089 1073 $new_input['cf7a_enable'] = isset( $input['cf7a_enable'] ) ? $input['cf7a_enable'] :$new_input['cf7a_enable'];1090 $new_input['cf7a_enable'] = $input['cf7a_enable'] ?? $new_input['cf7a_enable']; 1074 1091 1075 1092 /* bot fingerprint */ … … 1266 1283 } 1267 1284 1285 /* Optimizations */ 1286 $new_input['optimize_scripts_loading'] = !empty( $input['optimize_scripts_loading'] ) ? 1 : 0; 1287 $new_input['cf7a_disable_reload'] = !empty( $input['cf7a_disable_reload'] ) ? 1 : 0; 1288 1268 1289 /* Customizations */ 1269 $new_input['cf7a_disable_reload'] = isset( $input['cf7a_disable_reload'] ) ? 1 : 0;1270 1271 1290 $input['cf7a_customizations_class'] = sanitize_html_class( $input['cf7a_customizations_class'] ); 1272 1291 $new_input['cf7a_customizations_class'] = ! empty( $input['cf7a_customizations_class'] ) ? sanitize_html_class( $input['cf7a_customizations_class'] ) : CF7ANTISPAM_HONEYPOT_CLASS; … … 1415 1434 // the upload button for the database if the download is disabled 1416 1435 printf( '<input type="button" id="geoip_force_download" class="button cf7a_action" data-action="force-geoip-download" data-callback="update-geoip-status" data-nonce="%s" value="%s" />', 1417 wp_create_nonce( 'cf7a-nonce'),1436 esc_attr(wp_create_nonce( 'cf7a-nonce' )), 1418 1437 esc_attr__( 'Force Download', 'cf7-antispam' ) 1419 1438 ); … … 1428 1447 esc_html__( 'No file selected', 'cf7-antispam' ) 1429 1448 ); 1430 echo '<p class="geoip_dbfile text-xs"> Accepted formats: .mmdb or .tar.gz </p>';1449 printf( '<p class="geoip_dbfile text-xs">%s</p>', esc_html__( 'Accepted formats: .mmdb or .tar.gz', 'cf7-antispam' ) ); 1431 1450 } 1432 1451 … … 1733 1752 } 1734 1753 1735 1736 /** It creates a checkbox with the id of "cf7a_disable_reload_callback" */1737 public function cf7a_disable_reload_callback() {1738 printf(1739 '<input type="checkbox" id="cf7a_disable_reload" name="cf7a_options[cf7a_disable_reload]" %s />',1740 ! empty( $this->options['cf7a_disable_reload'] ) ? 'checked="true"' : ''1741 );1742 }1743 1754 /** It creates a checkbox with the id of "cf7a_customizations_class_callback" */ 1744 1755 public function cf7a_customizations_class_callback() { … … 1779 1790 } 1780 1791 1792 /** It prints the optimizations info */ 1793 public function cf7a_optimizations() { 1794 printf( '<p>%s</p>', esc_html__( 'You can optimize the loading performance of the antispam scripts. Since optimization is a risky business, we do not recommend enabling this option without trying it first.', 'cf7-antispam' ) ); 1795 } 1796 1797 /** It creates a checkbox with the id of "optimize_scripts_loading" */ 1798 public function cf7a_optimizations_scripts_callback() { 1799 printf( 1800 '<input type="checkbox" id="optimize_scripts_loading" name="cf7a_options[optimize_scripts_loading]" %s />', 1801 ! empty( $this->options['optimize_scripts_loading'] ) ? 'checked="true"' : '' 1802 ); 1803 } 1804 1805 /** It creates a checkbox with the id of "cf7a_disable_reload_callback" */ 1806 public function cf7a_disable_reload_callback() { 1807 printf( 1808 '<input type="checkbox" id="cf7a_disable_reload" name="cf7a_options[cf7a_disable_reload]" %s />', 1809 ! empty( $this->options['cf7a_disable_reload'] ) ? 'checked="true"' : '' 1810 ); 1811 } 1812 1781 1813 1782 1814 /** It creates a checkbox with the id of "cf7a_score_fingerprinting_callback" */ -
cf7-antispam/trunk/admin/CF7_AntiSpam_Admin_Display.php
r3389259 r3402920 821 821 } 822 822 823 private function get_plugin_version( $plugin_file ) { 824 if ( file_exists( $plugin_file ) ) { 825 $plugin_data = get_plugin_data( $plugin_file ); 826 if ( ! empty( $plugin_data['Version'] ) ) { 827 return $plugin_data['Version']; 828 } 829 } 830 return 'Not installed'; 831 } 832 823 833 /** 824 834 * It returns a string containing a formatted HTML table with the plugin's options … … 827 837 */ 828 838 private function cf7a_get_debug_info_options() { 839 global $wpdb; 840 $cf7_plugin_file = WP_PLUGIN_DIR . '/contact-form-7/wp-contact-form-7.php'; 841 $flamingo_plugin_file = WP_PLUGIN_DIR . '/flamingo/flamingo.php'; 842 $debug_data = array( 843 'cf7a_version' => CF7ANTISPAM_VERSION, 844 'cf7a_options' => $this->options, 845 'wp_version' => get_bloginfo( 'version' ), 846 'contact_form_7_version' => $this->get_plugin_version($cf7_plugin_file), 847 'flamingo_version' => $this->get_plugin_version($flamingo_plugin_file), 848 'php_version' => PHP_VERSION, 849 'mysql_version' => $wpdb->db_version(), 850 'plugins' => array_map(function($plugin) { 851 return $plugin['Name'] . ' (' . $plugin['Version'] . ')'; 852 }, get_plugins()), 853 'wp_debug' => WP_DEBUG ? 'Enabled' : 'Disabled', 854 'wp_debug_log' => WP_DEBUG_LOG ? 'Enabled' : 'Disabled', 855 'wp_debug_display' => WP_DEBUG_DISPLAY ? 'Enabled' : 'Disabled', 856 'wp_memory_limit' => WP_MEMORY_LIMIT, 857 'php_memory_limit' => ini_get( 'memory_limit' ), 858 'upload_max_size' => ini_get( 'upload_max_size' ), 859 'post_max_size' => ini_get( 'post_max_size' ), 860 ); 829 861 printf( '<h2 class="title">%s</h2>', esc_html__( 'Options debug', 'cf7-antispam' ) ); 830 862 printf( … … 833 865 esc_html( 834 866 htmlentities( 835 print_r( $ this->options, true ) // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r867 print_r( $debug_data, true ) // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r 836 868 ) 837 869 ) -
cf7-antispam/trunk/admin/CF7_AntiSpam_Admin_Tools.php
r3389259 r3402920 2 2 3 3 namespace CF7_AntiSpam\Admin; 4 5 use CF7_AntiSpam\Core\CF7_AntiSpam;6 use CF7_AntiSpam\Core\CF7_AntiSpam_Filters;7 use CF7_AntiSpam\Core\CF7_AntiSpam_Flamingo;8 use CF7_AntiSpam\Engine\CF7_AntiSpam_Uninstaller;9 4 10 5 /** … … 24 19 * It sets a transient with the name of `cf7a_notice` and the value of the notice 25 20 * 26 * @param string $message The message you want to display.27 * @param string $type error, warning, success, info.21 * @param string $message The message you want to display. 22 * @param string $type error, warning, success, info. 28 23 * @param boolean $dismissible when the notice needs the close button. 29 24 */ 30 public static function cf7a_push_notice( $message = 'generic', $type = 'error',$dismissible = true ) {25 public static function cf7a_push_notice( string $message = 'generic', string $type = 'error', bool $dismissible = true ) { 31 26 $class = "notice notice-$type"; 32 27 $class .= $dismissible ? ' is-dismissible' : ''; … … 35 30 } 36 31 32 /** 33 * It exports the blacklist 34 */ 37 35 public static function cf7a_export_blacklist() { 38 36 global $wpdb; … … 68 66 } 69 67 } 68 69 /** 70 * It sends an email to the admin 71 * 72 * @param string $subject the mail message subject 73 * @param string $recipient the mail recipient 74 * @param string $body the mail message content 75 * @param string $sender the mail message sender 76 */ 77 public function send_email_to_admin( string $subject, string $recipient, string $body, string $sender ) { 78 /** 79 * Filter cf7-antispam before resend an email who was spammed 80 * 81 * @param string $body the mail message content 82 * @param string $sender the mail message sender 83 * @param string $subject the mail message subject 84 * @param string $recipient the mail recipient 85 * 86 * @returns string the mail body content 87 */ 88 $body = apply_filters( 'cf7a_before_resend_email', $body, $sender, $subject, $recipient ); 89 90 // Set up headers correctly 91 $site_name = get_bloginfo( 'name' ); 92 $from_email = get_option( 'admin_email' ); 93 94 $headers = "From: {$site_name} <{$from_email}>\n"; 95 $headers .= "Content-Type: text/html\n"; 96 $headers .= "X-WPCF7-Content-Type: text/html\n"; 97 $headers .= "Reply-To: {$sender}\n"; 98 99 /* send the email */ 100 return wp_mail( $recipient, $subject, $body, $headers ); 101 } 70 102 } -
cf7-antispam/trunk/cf7-antispam.php
r3392568 r3402920 6 6 * Text Domain: cf7-antispam 7 7 * Domain Path: /languages 8 * Version: 0.7. 18 * Version: 0.7.2 9 9 * License: GPLv2 or later 10 * Requires Plugins: contact-form-7 10 11 * 11 12 * @package cf7-antispam … … 20 21 define( 'CF7ANTISPAM_NAME', 'cf7-antispam' ); 21 22 22 define( 'CF7ANTISPAM_VERSION', '0.7. 1' );23 define( 'CF7ANTISPAM_VERSION', '0.7.2' ); 23 24 24 25 define( 'CF7ANTISPAM_PLUGIN', __FILE__ ); -
cf7-antispam/trunk/core/CF7_AntiSpam.php
r3389259 r3402920 169 169 170 170 /* the unspam routine */ 171 add_action( 'cf7a_cron', array( $plugin_antispam, 'cf7a_cron_unban' ) ); 171 $blacklist = new CF7_Antispam_Blacklist(); 172 add_action( 'cf7a_cron', array( $blacklist, 'cf7a_cron_unban' ) ); 172 173 173 174 /* flamingo */ … … 260 261 $plugin_frontend = new CF7_AntiSpam_Frontend( $this->get_plugin_name(), $this->get_version() ); 261 262 262 $this->loader->add_action( 'wp', $plugin_frontend, 'setup' ); 263 $plugin_frontend->setup(); 264 $plugin_frontend->load_scripts(); 263 265 } 264 266 } -
cf7-antispam/trunk/core/CF7_AntiSpam_Filters.php
r3392568 r3402920 12 12 namespace CF7_AntiSpam\Core; 13 13 14 use CF7_AntiSpam\Admin\CF7_AntiSpam_Admin_Tools; 14 15 use Exception; 15 16 use WPCF7_Submission; … … 22 23 /** 23 24 * CF7_AntiSpam_Filters constructor. 25 * Registers the individual spam checks to the custom filter hook. 24 26 */ 25 27 public function __construct() { 26 } 28 // Priority 5: Whitelist checks (should run first to stop processing if safe) 29 add_filter( 'cf7a_spam_check_chain', array( $this, 'filter_ip_whitelist' ), 5 ); 30 31 // Priority 10: Standard checks 32 add_filter( 'cf7a_spam_check_chain', array( $this, 'filter_empty_ip' ), 10 ); 33 add_filter( 'cf7a_spam_check_chain', array( $this, 'filter_bad_ip' ), 10 ); 34 add_filter( 'cf7a_spam_check_chain', array( $this, 'filter_ip_blacklist_history' ), 10 ); 35 add_filter( 'cf7a_spam_check_chain', array( $this, 'filter_honeyform' ), 10 ); 36 37 // Checks that originally ran only if score < 1 (See logic inside methods) 38 add_filter( 'cf7a_spam_check_chain', array( $this, 'filter_referrer_protocol' ), 10 ); 39 add_filter( 'cf7a_spam_check_chain', array( $this, 'filter_plugin_version' ), 10 ); 40 add_filter( 'cf7a_spam_check_chain', array( $this, 'filter_bot_fingerprint' ), 10 ); 41 add_filter( 'cf7a_spam_check_chain', array( $this, 'filter_bot_fingerprint_extras' ), 10 ); 42 add_filter( 'cf7a_spam_check_chain', array( $this, 'filter_language' ), 10 ); 43 add_filter( 'cf7a_spam_check_chain', array( $this, 'filter_geoip' ), 10 ); 44 add_filter( 'cf7a_spam_check_chain', array( $this, 'filter_time_submission' ), 10 ); 45 add_filter( 'cf7a_spam_check_chain', array( $this, 'filter_bad_email_strings' ), 10 ); 46 add_filter( 'cf7a_spam_check_chain', array( $this, 'filter_user_agent' ), 10 ); 47 add_filter( 'cf7a_spam_check_chain', array( $this, 'filter_bad_words' ), 10 ); 48 add_filter( 'cf7a_spam_check_chain', array( $this, 'filter_dnsbl' ), 10 ); 49 add_filter( 'cf7a_spam_check_chain', array( $this, 'filter_honeypot' ), 10 ); 50 51 // Priority 20: Bayesian filter 52 add_filter( 'cf7a_spam_check_chain', array( $this, 'filter_b8_bayesian' ), 20 ); 53 } 54 55 // --------------------- 56 // STATIC HELPER METHODS 57 // --------------------- 27 58 28 59 /** … … 75 106 public static function cf7a_check_dnsbl( $reverse_ip, $dnsbl ) { 76 107 return checkdnsrr( $reverse_ip . '.' . $dnsbl . '.', 'A' ); 77 }78 79 /* CF7_AntiSpam_Filters blacklists */80 81 /**82 * It takes an IP address as a parameter, validates it, and then returns the row from the database that matches that IP83 * address84 *85 * @param string $ip - The IP address to check.86 *87 * @return array|object|null - the row from the database that matches the IP address.88 */89 public static function cf7a_blacklist_get_ip( $ip ) {90 $ip = filter_var( $ip, FILTER_VALIDATE_IP );91 if ( $ip ) {92 global $wpdb;93 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching94 $r = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM %i WHERE ip = %s", $wpdb->prefix . 'cf7a_blacklist', $ip ) );95 if ( $r ) {96 return $r;97 }98 }99 100 return null;101 }102 103 /**104 * It gets the row from the database where the id is equal to the id passed to the function105 *106 * @param int $id The ID of the blacklist item.107 *108 * @return object|false the row from the database that matches the id.109 */110 public function cf7a_blacklist_get_id( $id ) {111 if ( is_int( $id ) ) {112 global $wpdb;113 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching114 return $wpdb->get_row( $wpdb->prepare( "SELECT * FROM %i WHERE id = %s", $wpdb->prefix . 'cf7a_blacklist', $id ) );115 }116 }117 118 /**119 * It adds an IP address to the blacklist.120 *121 * @param string $ip The IP address to ban.122 * @param array $reason The reason why the IP is being banned.123 * @param float $spam_score This is the number of points that will be added to the IP's spam score.124 *125 * @return bool true if the given id was banned126 */127 public function cf7a_ban_by_ip( string $ip, array $reason = array(), $spam_score = 1 ): bool {128 $ip = filter_var( $ip, FILTER_VALIDATE_IP );129 130 if ( $ip ) {131 global $wpdb;132 133 $ip_row = self::cf7a_blacklist_get_ip( $ip );134 135 if ( $ip_row ) {136 // if the ip is in the blacklist, update the status137 $status = isset( $ip_row->status ) ? floatval( $ip_row->status ) + floatval( $spam_score ) : 1;138 139 } else {140 // if the ip is not in the blacklist, add it and initialize the status141 $status = floatval( $spam_score );142 }143 144 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching145 $r = $wpdb->replace(146 $wpdb->prefix . 'cf7a_blacklist',147 array(148 'ip' => $ip,149 'status' => $status,150 'meta' => serialize(151 array(152 'reason' => $reason,153 'meta' => null,154 )155 ),156 ),157 array( '%s', '%d', '%s' )158 );159 160 if ( $r > - 1 ) {161 return true;162 }163 }164 165 return false;166 }167 168 /**169 * It deletes the IP address from the database170 *171 * @param string $ip The IP address to unban.172 *173 * @return int|false The number of rows deleted.174 */175 public function cf7a_unban_by_ip( $ip ) {176 $ip = filter_var( $ip, FILTER_VALIDATE_IP );177 178 if ( $ip ) {179 global $wpdb;180 181 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching182 $r = $wpdb->delete(183 $wpdb->prefix . 'cf7a_blacklist',184 array(185 'ip' => $ip,186 ),187 array(188 '%s',189 )190 );191 192 return ! is_wp_error( $r ) ? $r : $wpdb->last_error;193 }194 195 return false;196 }197 198 /**199 * It deletes a row from the database table200 *201 * @param int $id The ID of the entry to delete.202 *203 * @return int The number of rows affected by the query.204 */205 public function cf7a_unban_by_id( $id ) {206 $id = intval( $id );207 208 global $wpdb;209 210 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching211 $r = $wpdb->delete(212 $wpdb->prefix . 'cf7a_blacklist',213 array(214 'id' => $id,215 ),216 array(217 '%d',218 )219 );220 221 return ! is_wp_error( $r ) ? $r : $wpdb->last_error;222 }223 224 /**225 * It updates the status of all the users in the blacklist table by subtracting 1 from the status column.226 *227 * Then it deletes all the users whose status is 0.228 * The status column is the number of days the user is banned for.229 * So if the user is banned for 3 days, the status column will be 3. After the first day, the status column will be 2. After the second day, the status column will be 1. After the third day, the status column will be 0.230 * When the status column is 0, the user is unbanned.231 *232 * The function returns true if the user is unbanned.233 *234 * @return true.235 */236 public function cf7a_cron_unban() {237 global $wpdb;238 239 /* We remove 1 from the status column */240 $status_decrement = 1;241 242 /* Below 0 is not anymore a valid status for a blacklist entry, so we can remove it */243 $lower_bound = 0;244 245 $blacklist_table = $wpdb->prefix . 'cf7a_blacklist';246 247 /* removes a status count at each balcklisted ip */248 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching249 $updated = $wpdb->query( $wpdb->prepare( "UPDATE %i SET `status` = `status` - %d", $blacklist_table, $status_decrement ) );250 cf7a_log( "Status updated for blacklisted (score -1) - $updated users", 1 );251 252 /* when the line has 0 in status, we can remove it from the blacklist */253 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching254 $updated_deletion = $wpdb->delete(255 $blacklist_table,256 array( 'status' => $lower_bound ),257 array( '%d' )258 );259 cf7a_log( "Removed {$updated_deletion} users from blacklist", 1 );260 261 return true;262 108 } 263 109 … … 368 214 } 369 215 216 // ------------------------ 217 // MAIN FILTER ORCHESTRATOR 218 // ------------------------ 370 219 371 220 /** 372 221 * CF7_AntiSpam_Filters The antispam filter 222 * 223 * @param boolean $spam - spam or not. 224 * 225 * @return boolean 226 */ 227 /** 228 * CF7_AntiSpam_Filters The antispam filter 229 * Refactored to use a filter chain pipeline. 373 230 * 374 231 * @param boolean $spam - spam or not. … … 390 247 $contact_form = $submission->get_contact_form(); 391 248 392 /* get the tag used in the form */ 249 /* Get plugin options */ 250 $options = get_option( 'cf7a_options', array() ); 251 252 /* Check the period of grace and, if it is expired, reset the error count */ 253 if ( !empty( $options['last_update_data']['errors'] ) ) { 254 $period_of_grace = apply_filters('cf7a_period_of_grace', WEEK_IN_SECONDS); 255 if ( time() - $options['last_update_data']['time'] > $period_of_grace ) { 256 $options['last_update_data']['errors'] = array(); 257 } 258 // then save the updated options to the database 259 update_option( 'cf7a_options', $options ); 260 } 261 262 /* Get basic submission details */ 393 263 $mail_tags = $contact_form->scan_form_tags(); 394 395 /* get the sender email field using the flamingo defined */396 264 $email_tag = sanitize_title( cf7a_get_mail_meta( $contact_form->pref( 'flamingo_email' ) ) ); 397 265 $emails = isset( $posted_data[ $email_tag ] ) ? array( $posted_data[ $email_tag ] ) : $this->scan_email_tags( $mail_tags ); 398 266 399 /* Getting the message field(s) from the form.*/267 /* Getting the message field(s) */ 400 268 $message_tag = sanitize_text_field( $contact_form->pref( 'flamingo_message' ) ); 401 269 $message_meta = cf7a_get_mail_meta( $message_tag ); … … 404 272 /** 405 273 * Let developers hack the message 406 *407 * @param string $message the mail message content408 * @param array $posted_data the email metadata409 274 */ 410 275 $message = apply_filters( 'cf7a_message_before_processing', $message, $posted_data ); 411 276 412 /* this plugin options */ 413 $options = get_option( 'cf7a_options', array() ); 414 $prefix = sanitize_html_class( $options['cf7a_customizations_prefix'] ); 415 416 /** 417 * The data of the user who sent this email 418 */ 419 420 /* IP */ 421 $real_remote_ip = isset( $_POST[ $prefix . 'address' ] ) ? cf7a_decrypt( sanitize_text_field( wp_unslash( $_POST[ $prefix . 'address' ] ) ), $options['cf7a_cipher'] ) : false; 277 /* Prepare IP and basic user data */ 278 $prefix = sanitize_text_field( $options['cf7a_customizations_prefix'] ); 279 // The right way to do this is BEFORE decrypting and THEN sanitize, because sanitized data are stripped of any special characters 280 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 281 $real_remote_ip = isset( $_POST[ $prefix . 'address' ] ) ? sanitize_text_field( wp_unslash( cf7a_decrypt( $_POST[ $prefix . 'address' ], $options['cf7a_cipher'] ) ) ) : false; 422 282 $remote_ip = $real_remote_ip ? filter_var( $real_remote_ip, FILTER_VALIDATE_IP ) : false; 423 283 $cf7_remote_ip = filter_var( $submission->get_meta( 'remote_ip' ), FILTER_VALIDATE_IP ); 424 425 /* CF7A version */ 426 $cf7a_version = isset( $_POST[ $prefix . 'version' ] ) ? cf7a_decrypt( sanitize_text_field( wp_unslash( $_POST[ $prefix . 'version' ] ) ), $options['cf7a_cipher'] ) : false; 427 428 /* client referer */ 429 $cf7a_referer = isset( $_POST[ $prefix . 'referer' ] ) ? cf7a_decrypt( sanitize_text_field( wp_unslash( $_POST[ $prefix . 'referer' ] ) ), $options['cf7a_cipher'] ) : false; 430 $cf7a_protocol = isset( $_POST[ $prefix . 'protocol' ] ) ? cf7a_decrypt( sanitize_text_field( wp_unslash( $_POST[ $prefix . 'protocol' ] ) ), $options['cf7a_cipher'] ) : false; 431 432 /* CF7 user agent */ 433 $user_agent = sanitize_text_field( $submission->get_meta( 'user_agent' ) ); 434 435 /* Timestamp checks */ 436 $timestamp = isset( $_POST[ $prefix . '_timestamp' ] ) ? intval( cf7a_decrypt( sanitize_text_field( wp_unslash( $_POST[ $prefix . '_timestamp' ] ) ), $options['cf7a_cipher'] ) ) : 0; 437 438 /* Can be cached so isn't safe to use -> $submission->get_meta( 'timestamp' ); */ 439 $time_now = time(); 440 $time_elapsed_min = intval( $options['check_time_min'] ); 441 $time_elapsed_max = intval( $options['check_time_max'] ); 442 443 /* Checks sender has a blacklisted ip address */ 444 $bad_ip_list = isset( $options['bad_ip_list'] ) ? $options['bad_ip_list'] : array(); 445 446 /* Checks sender has a blacklisted ip address */ 447 $ip_whitelist = isset( $options['ip_whitelist'] ) ? $options['ip_whitelist'] : array(); 448 449 /* Checks if the mail contains bad words */ 450 $bad_words = isset( $options['bad_words_list'] ) ? $options['bad_words_list'] : array(); 451 452 /* Checks if the mail contains bad user agent */ 453 $bad_user_agent_list = isset( $options['bad_user_agent_list'] ) ? $options['bad_user_agent_list'] : array(); 454 455 /* Check sender mail has prohibited string */ 456 $bad_email_strings = isset( $options['bad_email_strings_list'] ) ? $options['bad_email_strings_list'] : array(); 284 $user_agent = sanitize_text_field( $submission->get_meta( 'user_agent' ) ); 285 286 // ------------------------------------------------------------- 287 // BUILD THE DATA OBJECT (Context) 288 // ------------------------------------------------------------- 289 $spam_data = array( 290 'submission' => $submission, 291 'options' => $options, 292 'posted_data' => $posted_data, 293 'remote_ip' => $remote_ip, 294 'cf7_remote_ip' => $cf7_remote_ip, 295 'emails' => $emails, 296 'message' => $message, 297 'mail_tags' => $mail_tags, 298 'user_agent' => $user_agent, 299 // State trackers 300 'spam_score' => 0, 301 'is_spam' => $spam, 302 'reasons' => array(), 303 'is_whitelisted'=> false, // Flag to stop processing 304 ); 457 305 458 306 /** 459 * Scoring 307 * RUN THE FILTER CHAIN 308 * This triggers all the checks registered in __construct 460 309 */ 461 462 /* b8 threshold */ 463 $b8_threshold = floatval( $options['b8_threshold'] ); 464 $b8_threshold = $b8_threshold > 0 && $b8_threshold < 1 ? $b8_threshold : 1; 465 466 /* cf7-antispam version check, fingerprinting, fingerprints extras (for each failed test) */ 467 $score_fingerprinting = floatval( $options['score']['_fingerprinting'] ); 468 469 /* time lower or higher than the limits entered */ 470 $score_time = floatval( $options['score']['_time'] ); 471 472 /* blacklisted ip (with bad ip list), bad string in email or in message fields, bad user agent */ 473 $score_bad_string = floatval( $options['score']['_bad_string'] ); 474 475 /* dsnbl score (for each server found) */ 476 $score_dnsbl = floatval( $options['score']['_dnsbl'] ); 477 478 /* honeypot */ 479 $score_honeypot = floatval( $options['score']['_honeypot'] ); 480 481 /* no http refer, language check fail */ 482 $score_warn = floatval( $options['score']['_warn'] ); 483 484 /* already blacklisted, language check fail, ip or user agent or timestamp fields missing */ 485 $score_detection = floatval( $options['score']['_detection'] ); 486 487 /* initialize the spam data collection */ 488 $reason = array(); 489 $spam_score = 0; 310 $spam_data = apply_filters( 'cf7a_spam_check_chain', $spam_data ); 490 311 491 312 /** 492 * Checks for IP and return immediately if it is whitelisted 313 * BAYESIAN FILTER (B8) 314 * Placed explicitly here to ensure it runs at the end of the function, 315 * regardless of previous spam detection (unless whitelisted). 493 316 */ 494 if ( ! empty( $ip_whitelist ) ) { 495 foreach ( $ip_whitelist as $good_ip ) { 496 $good_ip = filter_var( $good_ip, FILTER_VALIDATE_IP ); 497 498 if ( false !== stripos( (string) $remote_ip, (string) $good_ip ) ) { 499 return false; 500 } 501 } 502 } 317 $spam_data = apply_filters( 'cf7a_check_b8', $spam_data ); 318 319 // Extract results 320 $spam_score = $spam_data['spam_score']; 321 $reason = $spam_data['reasons']; 322 $spam = $spam_data['is_spam']; 323 $remote_ip = $spam_data['remote_ip'] ? $spam_data['remote_ip'] : $spam_data['cf7_remote_ip']; 503 324 504 325 /** 505 * Checking if the IP address is empty. If it is empty, it will add a score of 10 to the spam score and add a reason to the reason array. 506 */ 507 if ( ! $remote_ip ) { 508 $remote_ip = $cf7_remote_ip ? $cf7_remote_ip : null; 509 510 ++$spam_score; 511 $spam = true; 512 $reason['no_ip'] = 'Address field empty'; 513 514 cf7a_log( "ip address field of $remote_ip is empty, this means it has been modified, removed or hacked! (i'm getting the real ip from http header)", 1 ); 515 } 516 517 /** 518 * Checks if the IP is filtered 519 */ 520 if ( intval( $options['check_bad_ip'] ) === 1 ) { 521 foreach ( $bad_ip_list as $bad_ip ) { 522 $bad_ip = filter_var( $bad_ip, FILTER_VALIDATE_IP ); 523 524 if ( false !== stripos( (string) $remote_ip, (string) $bad_ip ) ) { 525 ++$spam_score; 526 $spam = true; 527 $reason['bad_ip'][] = $bad_ip; 528 } 529 } 530 531 if ( ! empty( $reason['bad_ip'] ) ) { 532 $reason['bad_ip'] = implode( ', ', $reason['bad_ip'] ); 533 534 cf7a_log( "The ip address $remote_ip is listed into bad ip list (contains {$reason['bad_ip']})", 1 ); 535 } 536 } 537 538 /** 539 * Checking if the IP address was already blacklisted - no mercy 😎 540 */ 541 if ( $remote_ip && $options['max_attempts'] ) { 542 $ip_data = self::cf7a_blacklist_get_ip( $remote_ip ); 543 $ip_data_status = isset( $ip_data->status ) ? intval( $ip_data->status ) : 0; 544 $max_attempts = intval( $options['max_attempts'] ); 545 546 /* if the current ip has tried more times than allowed */ 547 if ( $ip_data_status >= $max_attempts ) { 548 ++$spam_score; 549 $spam = true; 550 $reason['blacklisted score'] = $ip_data_status + $spam_score; 551 552 cf7a_log( "The $remote_ip is already blacklisted, status $ip_data_status", 1 ); 553 } elseif ( CF7ANTISPAM_DEBUG && $ip_data_status > 0 ) { 554 555 /* Wanr only if the number of attempts is higher than 0 but lower than the max attempts */ 556 cf7a_log( 557 sprintf( 558 "The $remote_ip is already blacklisted (score $ip_data_status) but still has %d attempts left", 559 $max_attempts - $ip_data_status 560 ), 561 1 562 ); 563 } 564 } 565 566 /** 567 * Checking if the honeyForm field is empty. If it is not empty, then it is a bot. 568 */ 569 if ( intval( $options['check_honeyform'] ) === 1 ) { 570 $form_class = sanitize_html_class( $options['cf7a_customizations_class'] ); 571 572 /* get the "marker" field */ 573 if ( isset( $_POST[ '_wpcf7_' . $form_class ] ) ) { 574 ++$spam_score; 575 $spam = true; 576 $reason['honeyform'] = 'true'; 577 } 578 } 579 580 /** 581 * If the mail was marked as spam no more checks are needed. 582 * This will save server computing power, this ip has already been banned so there's no reason for further processing 583 */ 584 if ( $spam_score < 1 && ! $spam ) { 585 /** 586 * Check the client http refer 587 * it is much more likely that it is a bot that lands on the page without a referrer than a human that pastes in the address bar the url of the contact form. 588 */ 589 if ( intval( $options['check_refer'] ) === 1 ) { 590 if ( ! $cf7a_referer ) { 591 $spam_score += $score_warn; 592 $reason['no_referrer'] = 'client has referrer address'; 593 594 cf7a_log( "the $remote_ip has reached the contact form page without any referrer", 1 ); 595 } 596 } 597 598 if ( $cf7a_protocol ) { 599 if ( in_array( $cf7a_protocol, array( 'HTTP/1.0', 'HTTP/1.1', 'HTTP/1.2' ) ) ) { 600 $spam_score += $score_warn; 601 $reason['no_protocol'] = 'client has a bot-like connection protocol'; 602 603 cf7a_log( "the $remote_ip has a bot-like connection protocol (HTTP/1.X)", 1 ); 604 } 605 } 606 607 /** 608 * Check the CF7 AntiSpam version field 609 */ 610 if ( ! $cf7a_version ) { 611 $spam_score += $score_fingerprinting; 612 $reason['data_mismatch'] = "Version mismatch '$cf7a_version' != '" . CF7ANTISPAM_VERSION . "'"; 613 614 cf7a_log( "Incorrect data submitted by $remote_ip in the hidden field _version, may have been modified, removed or hacked", 1 ); 615 } 616 617 /** 618 * If enabled fingerprints bots 619 */ 620 if ( intval( $options['check_bot_fingerprint'] ) === 1 ) { 621 $bot_fingerprint = array( 622 'timezone' => ! empty( $_POST[ $prefix . 'timezone' ] ) ? sanitize_text_field( wp_unslash( $_POST[ $prefix . 'timezone' ] ) ) : null, 623 'platform' => ! empty( $_POST[ $prefix . 'platform' ] ) ? sanitize_text_field( wp_unslash( $_POST[ $prefix . 'platform' ] ) ) : null, 624 'screens' => ! empty( $_POST[ $prefix . 'screens' ] ) ? sanitize_text_field( wp_unslash( $_POST[ $prefix . 'screens' ] ) ) : null, 625 'memory' => ! empty( $_POST[ $prefix . 'memory' ] ) ? intval( $_POST[ $prefix . 'memory' ] ) : null, 626 'user_agent' => ! empty( $_POST[ $prefix . 'user_agent' ] ) ? sanitize_text_field( wp_unslash( $_POST[ $prefix . 'user_agent' ] ) ) : null, 627 /* deprecated 👇 TODO: replace with a user agent parser */ 628 'app_version' => ! empty( $_POST[ $prefix . 'app_version' ] ) ? sanitize_text_field( wp_unslash( $_POST[ $prefix . 'app_version' ] ) ) : null, 629 'webdriver' => ! empty( $_POST[ $prefix . 'webdriver' ] ) ? sanitize_text_field( wp_unslash( $_POST[ $prefix . 'webdriver' ] ) ) : null, 630 'session_storage' => ! empty( $_POST[ $prefix . 'session_storage' ] ) ? intval( $_POST[ $prefix . 'session_storage' ] ) : null, 631 'bot_fingerprint' => ! empty( $_POST[ $prefix . 'bot_fingerprint' ] ) ? sanitize_text_field( wp_unslash( $_POST[ $prefix . 'bot_fingerprint' ] ) ) : null, 632 'touch' => ! empty( $_POST[ $prefix . 'touch' ] ), 633 ); 634 635 $fails = array(); 636 if ( ! $bot_fingerprint['timezone'] ) { 637 $fails[] = 'timezone'; 638 } 639 if ( ! $bot_fingerprint['platform'] ) { 640 $fails[] = 'platform'; 641 } 642 if ( ! $bot_fingerprint['screens'] ) { 643 $fails[] = 'screens'; 644 } 645 if ( ! $bot_fingerprint['user_agent'] ) { 646 $fails[] = 'user_agent'; 647 } 648 if ( ! $bot_fingerprint['app_version'] ) { 649 $fails[] = 'app_version'; 650 } 651 if ( ! $bot_fingerprint['webdriver'] ) { 652 $fails[] = 'webdriver'; 653 } 654 if ( ! $bot_fingerprint['session_storage'] ) { 655 $fails[] = 'session_storage'; 656 } 657 if ( 5 !== strlen( $bot_fingerprint['bot_fingerprint'] ) ) { 658 $fails[] = 'bot_fingerprint'; 659 } 660 661 /* navigator deviceMemory isn't available with Ios, FireFox and ie - https://developer.mozilla.org/en-US/docs/Web/API/Navigator/deviceMemory */ 662 if ( isset( $_POST[ $prefix . 'isIos' ] ) || isset( $_POST[ $prefix . 'isFFox' ] ) || isset( $_POST[ $prefix . 'isIE' ] ) ) { 663 if ( $bot_fingerprint['memory'] ) { 664 $fails[] = 'memory_supported'; 665 } 666 } elseif ( ! $bot_fingerprint['memory'] ) { 667 $fails[] = 'memory'; 668 } 669 670 if ( isset( $_POST[ $prefix . 'isIos' ] ) || isset( $_POST[ $prefix . 'isAndroid' ] ) ) { 671 if ( ! $bot_fingerprint['touch'] ) { 672 $fails[] = 'touch'; 673 } 674 } 675 676 /* increment the spam score if needed, then log the result */ 677 if ( ! empty( $fails ) ) { 678 $spam_score += count( $fails ) * $score_fingerprinting; 679 $reason['bot_fingerprint'] = implode( ', ', $fails ); 680 681 cf7a_log( "The $remote_ip ip hasn't passed " . count( $fails ) . ' / ' . count( $bot_fingerprint ) . " of the bot fingerprint test ({$reason['bot_fingerprint']})", 1 ); 682 cf7a_log( $bot_fingerprint, 2 ); 683 } 684 } 685 686 /** 687 * Bot fingerprints extras 688 */ 689 if ( intval( $options['check_bot_fingerprint_extras'] ) === 1 ) { 690 $bot_fingerprint_extras = array( 691 'activity' => ! empty( $_POST[ $prefix . 'activity' ] ) ? intval( $_POST[ $prefix . 'activity' ] ) : 0, 692 'mouseclick_activity' => ! empty( $_POST[ $prefix . 'mouseclick_activity' ] ) && sanitize_text_field( wp_unslash( $_POST[ $prefix . 'mouseclick_activity' ] ) ) === 'passed', 693 'mousemove_activity' => ! empty( $_POST[ $prefix . 'mousemove_activity' ] ) && sanitize_text_field( wp_unslash( $_POST[ $prefix . 'mousemove_activity' ] ) ) === 'passed', 694 'webgl' => ! empty( $_POST[ $prefix . 'webgl' ] ) && sanitize_text_field( wp_unslash( $_POST[ $prefix . 'webgl' ] ) ) === 'passed', 695 'webgl_render' => ! empty( $_POST[ $prefix . 'webgl_render' ] ) && sanitize_text_field( wp_unslash( $_POST[ $prefix . 'webgl_render' ] ) ) === 'passed', 696 'bot_fingerprint_extras' => empty( $_POST[ $prefix . 'bot_fingerprint_extras' ] ), 697 // has to be empty! 698 ); 699 700 $fails = array(); 701 if ( $bot_fingerprint_extras['activity'] < 3 ) { 702 $fails[] = "activity {$bot_fingerprint_extras["activity"]}"; 703 } 704 if ( empty( $bot_fingerprint_extras['mouseclick_activity'] ) ) { 705 $fails[] = 'mouseclick_activity'; 706 } 707 if ( empty( $bot_fingerprint_extras['mousemove_activity'] ) ) { 708 $fails[] = 'mousemove_activity'; 709 } 710 if ( empty( $bot_fingerprint_extras['webgl'] ) ) { 711 $fails[] = 'webgl'; 712 } 713 if ( empty( $bot_fingerprint_extras['webgl_render'] ) ) { 714 $fails[] = 'webgl_render'; 715 } 716 if ( empty( $bot_fingerprint_extras['bot_fingerprint_extras'] ) ) { 717 $fails[] = 'bot_fingerprint_extras'; 718 } 719 720 if ( ! empty( $fails ) ) { 721 $spam_score += count( $fails ) * $score_fingerprinting; 722 $reason['bot_fingerprint_extras'] = implode( ', ', $fails ); 723 724 cf7a_log( "The $remote_ip ip hasn't passed " . count( $fails ) . ' / ' . count( $bot_fingerprint_extras ) . " of the bot fingerprint extra test ({$reason['bot_fingerprint_extras']})", 1 ); 725 cf7a_log( $bot_fingerprint_extras, 2 ); 726 } 727 } 728 729 /** 730 * Check the browser / headers language 731 */ 732 if ( intval( $options['check_language'] ) === 1 ) { 733 /* prefix '_cf7a_' */ 734 $languages = array(); 735 $languages['browser_language'] = ! empty( $_POST[ $prefix . 'browser_language' ] ) ? sanitize_text_field( wp_unslash( $_POST[ $prefix . 'browser_language' ] ) ) : null; 736 $languages['accept_language'] = isset( $_POST[ $prefix . '_language' ] ) ? cf7a_decrypt( sanitize_text_field( wp_unslash( $_POST[ $prefix . '_language' ] ) ), $options['cf7a_cipher'] ) : null; 737 738 /** 739 * Language checks 740 */ 741 if ( empty( $languages['browser_language'] ) ) { 742 $spam_score += $score_detection; 743 $reason['browser_language'] = 'missing browser language'; 744 } else { 745 $languages_locales = cf7a_get_browser_languages_locales_array( $languages['browser_language'] ); 746 $languages['browser'] = $languages_locales['languages']; 747 } 748 749 if ( empty( $languages['accept_language'] ) ) { 750 $spam_score += $score_detection; 751 $reason['language_field'] = 'missing language field'; 752 } else { 753 $languages['accept'] = cf7a_get_accept_language_array( $languages['accept_language'] ); 754 } 755 756 if ( ! empty( $languages['accept'] ) && ! empty( $languages['browser'] ) ) { 757 if ( ! array_intersect( $languages['browser'], $languages['accept'] ) ) { 758 $spam_score += $score_detection; 759 760 /* checks if http accept language is the same of javascript navigator.languages */ 761 $reason['language_incoherence'] = 'languages detected not coherent (' . implode( '-', $languages['browser'] ) . ' vs ' . implode( '-', $languages['accept'] ) . ')'; 762 } 763 764 /* check if the language is allowed and if is disallowed */ 765 $client_languages = array_unique( array_merge( $languages['browser'], $languages['accept'] ) ); 766 767 /* extract options and assign them to local variables */ 768 $languages_allowed = isset( $options['languages_locales']['allowed'] ) ? $this->cf7a_get_languages_or_locales( $options['languages_locales']['allowed'], 'languages' ) : array(); 769 $languages_disallowed = isset( $options['languages_locales']['disallowed'] ) ? $this->cf7a_get_languages_or_locales( $options['languages_locales']['disallowed'], 'languages' ) : array(); 770 771 $language_disallowed = $this->cf7a_check_languages_locales_allowed( $client_languages, $languages_disallowed, $languages_allowed ); 772 773 if ( false === $language_disallowed ) { 774 $spam_score += $score_detection; 775 $reason['browser_language'] = implode( ', ', $client_languages ); 776 } 777 } 778 } 779 780 /** 781 * Geo-ip verification 782 */ 783 if ( intval( $options['check_geo_location'] ) === 1 ) { 784 $geoip = new CF7_Antispam_Geoip(); 785 786 $locales_allowed = $this->cf7a_get_languages_or_locales( $options['languages_locales']['allowed'], 'locales' ); 787 $locales_disallowed = $this->cf7a_get_languages_or_locales( $options['languages_locales']['disallowed'], 'locales' ); 788 789 if ( ! empty( $geoip ) ) { 790 try { 791 /* check if the ip is available into geo-ip database, then create an array with county and continent */ 792 $geoip_data = $geoip->check_ip( $remote_ip ); 793 $geoip_continent = isset( $geoip_data['continent'] ) ? ( $geoip_data['continent'] ) : false; 794 $geoip_country = isset( $geoip_data['country'] ) ? ( $geoip_data['country'] ) : false; 795 $geo_data = array_filter( array( $geoip_continent, $geoip_country ) ); 796 797 if ( ! empty( $geo_data ) ) { 798 /* 799 then check if the detected country is among the allowed and disallowed languages */ 800 // Check if the country is allowed by country by splitting browser headers 2nd arg since ISO is coherent 801 if ( false === $this->cf7a_check_languages_locales_allowed( $geo_data, $locales_disallowed, $locales_allowed ) ) { 802 $reason['geo_ip'] = $geoip_continent . '-' . $geoip_country; 803 $spam_score += $score_warn; 804 805 cf7a_log( "The $remote_ip is not allowed by geoip" . $reason['geo_ip'], 1 ); 806 } 807 } else { 808 $reason['no_geo_ip'] = 'unknown ip'; 809 } 810 } catch ( Exception $e ) { 811 cf7a_log( "unable to check geoip for $remote_ip - " . $e->getMessage(), 1 ); 812 } 813 } 814 } 815 816 /** 817 * Check if the time to submit the email 818 */ 819 if ( intval( $options['check_time'] ) === 1 ) { 820 if ( ! $timestamp ) { 821 $spam_score += $score_detection; 822 $reason['timestamp'] = 'undefined'; 823 824 cf7a_log( "The $remote_ip ip _timestamp field is missing, probable form hacking attempt from $remote_ip", 1 ); 825 } else { 826 $time_elapsed = $time_now - $timestamp; 827 828 /** 829 * Check if the time to submit the email il lower than expected 830 */ 831 if ( 0 !== $time_elapsed_min && $time_elapsed < $time_elapsed_min ) { 832 $spam_score += $score_time; 833 $reason['min_time_elapsed'] = $time_elapsed; 834 835 cf7a_log( "The $remote_ip ip took too little time to fill in the form - elapsed $time_elapsed seconds < $time_elapsed_min seconds expected", 1 ); 836 } 837 838 /** 839 * Check if the time to submit the email il higher than expected 840 */ 841 if ( 0 !== $time_elapsed_max && $time_elapsed > $time_elapsed_max ) { 842 $spam_score += $score_time; 843 $reason['max_time_elapsed'] = $time_elapsed; 844 845 cf7a_log( "The $remote_ip ip took too much time to fill in the form - elapsed $time_elapsed seconds > $time_elapsed_max seconds expected", 1 ); 846 } 847 } 848 } 849 850 /** 851 * Check if e-mails contain prohibited words, for instance, check if the sender is the same as the website domain, 852 * because it is an attempt to circumvent the controls, because the e-mail client cannot blacklist the e-mail itself, 853 * we must prevent this. 854 */ 855 if ( intval( $options['check_bad_email_strings'] ) === 1 && ! empty( $emails ) ) { 856 foreach ( $emails as $email ) { 857 foreach ( $bad_email_strings as $bad_email_string ) { 858 if ( false !== stripos( strtolower( $email ), strtolower( $bad_email_string ) ) ) { 859 $spam_score += $score_bad_string; 860 $reason['email_blacklisted'][] = $bad_email_string; 861 } 862 } 863 } 864 865 if ( isset( $reason['email_blacklisted'] ) ) { 866 $reason['email_blacklisted'] = implode( ',', $reason['email_blacklisted'] ); 867 868 cf7a_log( "The ip address $remote_ip sent a mail using the email address {$reason['email_blacklisted']} that contains the bad string {$reason['email_blacklisted']}", 1 ); 869 } 870 } 871 872 /** 873 * Checks if the emails user agent is denied 874 */ 875 if ( intval( $options['check_bad_user_agent'] ) === 1 ) { 876 if ( ! $user_agent ) { 877 $spam_score += $score_detection; 878 $reason['user_agent'] = 'empty'; 879 880 cf7a_log( "The $remote_ip ip user agent is empty, look like a spambot", 1 ); 881 } else { 882 foreach ( $bad_user_agent_list as $bad_user_agent ) { 883 if ( false !== stripos( strtolower( $user_agent ), strtolower( $bad_user_agent ) ) ) { 884 $spam_score += $score_bad_string; 885 $reason['user_agent'][] = $bad_user_agent; 886 } 887 } 888 889 if ( isset( $reason['user_agent'] ) && is_array( $reason['user_agent'] ) ) { 890 $reason['user_agent'] = implode( ', ', $reason['user_agent'] ); 891 cf7a_log( "The $remote_ip ip user agent was listed into bad user agent list - $user_agent contains " . $reason['user_agent'], 1 ); 892 } 893 } 894 } 895 896 /** 897 * Search for prohibited words 898 */ 899 if ( 1 === intval( $options['check_bad_words'] ) && '' !== $message ) { 900 901 /* to search strings into message without space and case-insensitive */ 902 $message_compressed = $this->cf7a_simplify_text( $message ); 903 904 foreach ( $bad_words as $bad_word ) { 905 if ( false !== stripos( $message_compressed, $this->cf7a_simplify_text( $bad_word ) ) ) { 906 $spam_score += $score_bad_string; 907 $reason['bad_word'][] = $bad_word; 908 } 909 } 910 911 if ( ! empty( $reason['bad_word'] ) ) { 912 $reason['bad_word'] = implode( ',', $reason['bad_word'] ); 913 914 cf7a_log( "$remote_ip has bad word in message " . $reason['bad_word'], 1 ); 915 } 916 } 917 918 /** 919 * Check the remote ip if is listed into Domain Name System Blacklists 920 * DNS blacklist are spam blocking DNS like lists that allow to block messages from specific systems that have a history of sending spam 921 * inspiration taken from https://gist.github.com/tbreuss/74da96ff5f976ce770e6628badbd7dfc 922 */ 923 if ( intval( $options['check_dnsbl'] ) === 1 && $remote_ip ) { 924 $reverse_ip = ''; 925 926 if ( filter_var( $remote_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ) { 927 $reverse_ip = $this->cf7a_reverse_ipv4( $remote_ip ); 928 } elseif ( filter_var( $remote_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) { 929 $reverse_ip = $this->cf7a_reverse_ipv6( $remote_ip ); 930 } 931 932 foreach ( $options['dnsbl_list'] as $dnsbl ) { 933 if ( $this->cf7a_check_dnsbl( $reverse_ip, $dnsbl ) ) { 934 $reason['dsnbl'][] = $dnsbl; 935 $spam_score += $score_dnsbl; 936 } 937 } 938 939 if ( isset( $reason['dsnbl'] ) && is_array( $reason['dsnbl'] ) ) { 940 $dsnbl_count = count( $reason['dsnbl'] ); 941 $reason['dsnbl'] = implode( ', ', $reason['dsnbl'] ); 942 943 cf7a_log( "$remote_ip has tried to send an email but is listed $dsnbl_count times in the Domain Name System Blacklists ({$reason['dsnbl']})", 1 ); 944 } 945 } 946 947 /** 948 * Checks Honeypots input if they are filled 949 */ 950 if ( $options['check_honeypot'] ) { 951 952 /* collect the input "name" value of the type="text" tags of the submitted form */ 953 foreach ( $mail_tags as $mail_tag ) { 954 if ( 'text' === $mail_tag['type'] || 'text*' === $mail_tag['type'] ) { 955 $mail_tag_text[] = $mail_tag['name']; 956 } 957 } 958 959 if ( ! empty( $mail_tag_text ) ) { 960 961 /* get the collection of the generated (fake) input name used as honeypots name value */ 962 $input_names = cf7a_get_honeypot_input_names( $options['honeypot_input_names'] ); 963 964 $mail_tag_count = count( $input_names ); 965 966 for ( $i = 0; $i < $mail_tag_count; $i++ ) { 967 968 /* check if any posted input name value has a name from the honeypot names array, if yes the bot has fallen into the trap and filled the input */ 969 $has_honeypot = ! empty( $_POST[ $input_names[ $i ] ] ); 970 971 /* check only if it's set and if it is different from "" */ 972 if ( $has_honeypot ) { 973 $spam_score += $score_honeypot; 974 $reason['honeypot'][] = $input_names[ $i ]; 975 } 976 } 977 978 if ( ! empty( $reason['honeypot'] ) ) { 979 $reason['honeypot'] = implode( ', ', $reason['honeypot'] ); 980 981 cf7a_log( "The $remote_ip has filled the input honeypot(s) {$reason['honeypot']}", 1 ); 982 } 983 } 984 } 985 } 986 987 /** 988 * Filter before Bayesian filter B8 326 * Final filter before the ban 989 327 * 990 * @param bool $spam true if the mail was detected as spam 991 * @param array $message the mail message content 992 * @param null|WPCF7_Submission $submission the mail message submission instance 993 */ 994 $spam = apply_filters( 'cf7a_before_b8', $spam, $message, $submission ); 995 996 /** 997 * B8 is a statistical "Bayesian" spam filter 998 * https://nasauber.de/opensource/b8/ 999 */ 1000 $text = stripslashes( $message ); 1001 \assert( \is_string( $text ) ); 1002 1003 if ( $options['enable_b8'] && $message && ! isset( $reason['blacklisted'] ) ) { 1004 $cf7a_b8 = new CF7_AntiSpam_B8(); 1005 $rating = round( $cf7a_b8->cf7a_b8_classify( $text ), 2 ); 1006 1007 /* Checking the rating of the message, and if it is greater than the threshold */ 1008 if ( $rating >= $b8_threshold ) { 1009 $reason['b8'] = $rating; 1010 $spam_score += $score_detection; 1011 1012 cf7a_log( "B8 rating $rating / 1", 1 ); 1013 } 1014 1015 /* Checking if the spam score is greater than or equal to 1. If it is, it sets the spam variable to true. */ 1016 if ( $spam_score >= 1 ) { 1017 /* if B8 isn't enabled we only need to mark as spam and leave a log */ 1018 cf7a_log( "$remote_ip will be rejected because suspected of spam! (score $spam_score / 1)", 1 ); 1019 $cf7a_b8->cf7a_b8_learn_spam( $text ); 1020 } elseif ( $rating < $b8_threshold * 0.5 ) { 1021 /* the mail has been classified as ham and is below half the 'alert value', so we can let B8 learn what is considered (a probable) ham */ 1022 cf7a_log( "B8 detect spamminess of $rating (below the half of the threshold of $b8_threshold) so the mail from $remote_ip will be marked as ham", 1 ); 1023 $cf7a_b8->cf7a_b8_learn_ham( $text ); 1024 } 1025 } 1026 1027 /** 1028 * Filter with the antispam results (before ban). 1029 * 1030 * @param boolean $spam true if the mail was detected as spam 1031 * @param string $message the mail message content 1032 * @param null|WPCF7_Submission $submission the mail message submission instance 328 * @param bool $spam 329 * @param string $message 330 * @param WPCF7_Submission $submission 1033 331 */ 1034 332 $spam = apply_filters( 'cf7a_additional_spam_filters', $spam, $message, $submission ); 1035 333 1036 /* if the spam score is lower than 1 the mail is ham so return the value as this is a filter*/1037 if ( $spam_score < 1 ) {1038 return $spam; 1039 } 1040 1041 /* ...otherwise the mail is spam, taking the array $reason and compressing it into a string.*/334 /* If the spam score is lower than 1 the mail is ham */ 335 if ( $spam_score < 1 && ! $spam ) { 336 return $spam; // Usually false 337 } 338 339 /* Prepare for ban/logging */ 1042 340 $reasons_for_ban = cf7a_compress_array( $reason ); 1043 341 1044 /* If the auto-store ip is enabled (and NOT in extended debug mode)*/1045 if ( $options['autostore_bad_ip'] ) {1046 if ( self::cf7a_ban_by_ip( $remote_ip, $reason, round( $spam_score ) ) ) {1047 /* Log the antispam result in extended debug mode */342 /* If the auto-store ip is enabled */ 343 if ( isset($options['autostore_bad_ip']) && $options['autostore_bad_ip'] ) { 344 $blacklist = new CF7_Antispam_Blacklist(); 345 if ( CF7_Antispam_Blacklist::cf7a_ban_by_ip( $remote_ip, $reason, round( $spam_score ) ) ) { 1048 346 cf7a_log( "Ban for $remote_ip - results - " . $reasons_for_ban, 2 ); 1049 347 } else { … … 1052 350 } 1053 351 1054 /* Store the ban reason into mail post metadata */352 /* Store the ban reason into mail post-metadata */ 1055 353 $submission->add_spam_log( 1056 354 array( … … 1060 358 ); 1061 359 1062 /* case closed */1063 1064 360 return true; 1065 361 } 362 363 // ------------------------- 364 // INDIVIDUAL FILTER METHODS 365 // ------------------------- 366 367 /** 368 * Checks for IP whitelist. 369 */ 370 public function filter_ip_whitelist( $data ) { 371 $ip_whitelist = $data['options']['ip_whitelist'] ?? array(); 372 373 if ( ! empty( $ip_whitelist ) && $data['remote_ip'] ) { 374 foreach ( $ip_whitelist as $good_ip ) { 375 $good_ip = filter_var( $good_ip, FILTER_VALIDATE_IP ); 376 if ( false !== stripos( (string) $data['remote_ip'], (string) $good_ip ) ) { 377 $data['is_whitelisted'] = true; 378 return $data; 379 } 380 } 381 } 382 return $data; 383 } 384 385 /** 386 * Checks if IP is empty. 387 */ 388 public function filter_empty_ip( $data ) { 389 if ( $data['is_whitelisted'] ) return $data; 390 391 if ( ! $data['remote_ip'] ) { 392 // Fallback to CF7 IP if main is missing, but flag as spam 393 $data['remote_ip'] = $data['cf7_remote_ip'] ? $data['cf7_remote_ip'] : null; 394 395 $data['spam_score']++; 396 $data['is_spam'] = true; 397 $data['reasons']['no_ip'] = 'Address field empty'; 398 399 cf7a_log( "ip address field of {$data['remote_ip']} is empty, this means it has been modified, removed or hacked!", 1 ); 400 } 401 return $data; 402 } 403 404 /** 405 * Checks against local bad IP list. 406 */ 407 public function filter_bad_ip( $data ) { 408 if ( $data['is_whitelisted'] ) return $data; 409 410 $options = $data['options']; 411 $bad_ip_list = isset( $options['bad_ip_list'] ) ? $options['bad_ip_list'] : array(); 412 413 if ( intval( $options['check_bad_ip'] ) === 1 && $data['remote_ip'] ) { 414 foreach ( $bad_ip_list as $bad_ip ) { 415 $bad_ip = filter_var( $bad_ip, FILTER_VALIDATE_IP ); 416 if ( false !== stripos( (string) $data['remote_ip'], (string) $bad_ip ) ) { 417 $data['spam_score']++; 418 $data['is_spam'] = true; 419 $data['reasons']['bad_ip'][] = $bad_ip; 420 } 421 } 422 423 if ( ! empty( $data['reasons']['bad_ip'] ) && is_array($data['reasons']['bad_ip']) ) { 424 $ip_string = implode( ', ', $data['reasons']['bad_ip'] ); 425 $data['reasons']['bad_ip'] = $ip_string; // Flatten for log 426 cf7a_log( "The ip address {$data['remote_ip']} is listed into bad ip list (contains $ip_string)", 1 ); 427 } 428 } 429 return $data; 430 } 431 432 /** 433 * Checks if IP is already in the database blacklist history. 434 */ 435 public function filter_ip_blacklist_history( $data ) { 436 if ( $data['is_whitelisted'] ) return $data; 437 438 $options = $data['options']; 439 if ( $data['remote_ip'] && $options['max_attempts'] ) { 440 $ip_data = CF7_Antispam_Blacklist::cf7a_blacklist_get_ip( $data['remote_ip'] ); 441 $ip_data_status = isset( $ip_data->status ) ? intval( $ip_data->status ) : 0; 442 $max_attempts = intval( $options['max_attempts'] ); 443 444 if ( $ip_data_status >= $max_attempts ) { 445 $data['spam_score']++; 446 $data['is_spam'] = true; 447 $data['reasons']['blacklisted score'] = $ip_data_status + $data['spam_score']; 448 449 cf7a_log( "The {$data['remote_ip']} is already blacklisted, status $ip_data_status", 1 ); 450 } elseif ( defined('CF7ANTISPAM_DEBUG') && CF7ANTISPAM_DEBUG && $ip_data_status > 0 ) { 451 cf7a_log( sprintf( "The {$data['remote_ip']} is already blacklisted (score $ip_data_status) but still has %d attempts left", $max_attempts - $ip_data_status ), 1 ); 452 } 453 } 454 return $data; 455 } 456 457 /** 458 * Checks the HoneyForm (CSS hidden field). 459 */ 460 public function filter_honeyform( $data ) { 461 if ( $data['is_whitelisted'] ) return $data; 462 463 $options = $data['options']; 464 if ( intval( $options['check_honeyform'] ) === 1 ) { 465 $form_class = sanitize_html_class( $options['cf7a_customizations_class'] ); 466 467 if ( isset( $_POST[ '_wpcf7_' . $form_class ] ) ) { 468 $data['spam_score']++; 469 $data['is_spam'] = true; 470 $data['reasons']['honeyform'] = 'true'; 471 } 472 } 473 return $data; 474 } 475 476 /** 477 * Checks Referrer and Protocol. 478 * Note: In original code, this only runs if spam_score < 1. 479 */ 480 public function filter_referrer_protocol( $data ) { 481 if ( $data['is_whitelisted'] ) return $data; 482 if ( $data['is_spam'] ) return $data; 483 484 $options = $data['options']; 485 $prefix = sanitize_text_field( $options['cf7a_customizations_prefix'] ); 486 $score_warn = floatval( $options['score']['_warn'] ); 487 488 if ( intval( $options['check_refer'] ) === 1 ) { 489 // The right way to do this is BEFORE decrypting and THEN sanitize, because sanitized data are stripped of any special characters 490 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 491 $cf7a_referer = isset( $_POST[ $prefix . 'referer' ] ) ? sanitize_text_field( wp_unslash( cf7a_decrypt($_POST[ $prefix . 'referer' ], $options['cf7a_cipher'] ) ) ) : false; 492 if ( ! $cf7a_referer ) { 493 $data['spam_score'] += $score_warn; 494 $data['reasons']['no_referrer'] = 'client has referrer address'; 495 cf7a_log( "the {$data['remote_ip']} has reached the contact form page without any referrer", 1 ); 496 } 497 } 498 499 // The right way to do this is BEFORE decrypting and THEN sanitize, because sanitized data are stripped of any special characters 500 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 501 $cf7a_protocol = isset( $_POST[ $prefix . 'protocol' ] ) ? sanitize_text_field( wp_unslash( cf7a_decrypt( $_POST[ $prefix . 'protocol' ], $options['cf7a_cipher'] ) ) ) : false; 502 if ( $cf7a_protocol ) { 503 if ( in_array( $cf7a_protocol, array( 'HTTP/1.0', 'HTTP/1.1', 'HTTP/1.2' ) ) ) { 504 $data['spam_score'] += $score_warn; 505 $data['reasons']['no_protocol'] = 'client has a bot-like connection protocol'; 506 cf7a_log( "the {$data['remote_ip']} has a bot-like connection protocol (HTTP/1.X)", 1 ); 507 } 508 } 509 return $data; 510 } 511 512 /** 513 * Checks Plugin Version match. 514 */ 515 public function filter_plugin_version( $data ) { 516 if ( $data['is_whitelisted'] ) return $data; 517 if ( $data['is_spam'] ) return $data; 518 519 $options = $data['options']; 520 $prefix = sanitize_text_field( $options['cf7a_customizations_prefix'] ); 521 $score_fingerprinting = floatval( $options['score']['_fingerprinting'] ); 522 523 // The right way to do this is BEFORE decrypting and THEN sanitize, because sanitized data are stripped of any special characters 524 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 525 $cf7a_version = isset( $_POST[ $prefix . 'version' ] ) ? sanitize_text_field( wp_unslash( cf7a_decrypt( $_POST[ $prefix . 'version' ], $options['cf7a_cipher'] ) ) ) : false; 526 527 // CASE A: Version field is completely missing or empty -> SPAM 528 if ( ! $cf7a_version ) { 529 $data['spam_score'] += $score_fingerprinting; 530 $data['reasons']['data_mismatch'] = sprintf( "Version mismatch (empty) != '%s'", CF7ANTISPAM_VERSION ); 531 cf7a_log( sprintf( "The 'version' field submitted by %s is empty", $data['remote_ip'] ), 1 ); 532 533 return $data; 534 } 535 536 // CASE B: Version matches current version -> OK 537 if ( $cf7a_version === CF7ANTISPAM_VERSION ) { 538 return $data; 539 } 540 541 // CASE C: Version Mismatch logic (Cache vs Spam) 542 // Retrieve update data stored during the last plugin update 543 $last_update_data = $options['last_update_data'] ?? null; 544 545 // Check if we have update data and if the submitted version matches the PREVIOUS version 546 $is_old_version_match = ( $last_update_data && isset( $last_update_data['old_version'] ) && $cf7a_version === $last_update_data['old_version'] ); 547 548 // Check if the update happened less than a week ago 549 $period_of_grace = apply_filters('cf7a_period_of_grace', WEEK_IN_SECONDS); 550 $is_within_grace_period = ( $last_update_data && isset( $last_update_data['time'] ) && ( time() - $last_update_data['time'] ) < $period_of_grace ); 551 552 if ( $is_old_version_match && $is_within_grace_period ) { 553 554 // --- CACHE ISSUE DETECTED (FALLBACK) --- 555 // Do NOT mark as spam. This is likely a cached user. 556 557 cf7a_log( "Cache mismatch detected for IP {$data['remote_ip']}. Submitted: $cf7a_version. Expected: " . CF7ANTISPAM_VERSION, 1 ); 558 559 // Record the error 560 if ( ! isset( $options['last_update_data']['errors'] ) ) { 561 $options['last_update_data']['errors'] = array(); 562 } 563 564 // Add error details 565 $options['last_update_data']['errors'][] = array( 566 'ip' => $data['remote_ip'], 567 'time' => time(), 568 ); 569 570 $error_count = count( $options['last_update_data']['errors'] ); 571 572 // Check trigger for email notification (Exactly on the 5th error) 573 $cf7a_period_of_grace_max_attempts = intval(apply_filters( 'cf7a_period_of_grace_max_attempts', 5)); 574 if ( $cf7a_period_of_grace_max_attempts === $error_count || $error_count * 3 === $cf7a_period_of_grace_max_attempts ) { 575 $this->send_cache_warning_email( $options['last_update_data'] ); 576 cf7a_log( "Cache warning email sent to admin.", 1 ); 577 } 578 579 // SAVE OPTIONS: We must save the error count to the database 580 // Update the local $options variable first so subsequent filters use it if needed (though unlikely) 581 $data['options'] = $options; 582 583 // Persist to DB 584 update_option( 'cf7a_options', $options ); 585 586 } else { 587 588 // --- REAL SPAM / INVALID VERSION --- 589 // Either the grace period expired, or the version is completely random 590 591 $data['spam_score'] += $score_fingerprinting; 592 $data['reasons']['data_mismatch'] = "Version mismatch '$cf7a_version' != '" . CF7ANTISPAM_VERSION . "'"; 593 cf7a_log( "The 'version' field submitted by {$data['remote_ip']} is mismatching (expired grace period or invalid)", 1 ); 594 } 595 596 return $data; 597 } 598 599 /** 600 * Checks Browser Fingerprint (JS based). 601 */ 602 public function filter_bot_fingerprint( $data ) { 603 if ( $data['is_whitelisted'] ) return $data; 604 if ( $data['is_spam'] ) return $data; 605 606 $options = $data['options']; 607 if ( intval( $options['check_bot_fingerprint'] ) !== 1 ) return $data; 608 609 $prefix = sanitize_text_field( $options['cf7a_customizations_prefix'] ); 610 $score_fingerprinting = floatval( $options['score']['_fingerprinting'] ); 611 612 $bot_fingerprint = array( 613 'timezone' => ! empty( $_POST[ $prefix . 'timezone' ] ) ? sanitize_text_field( wp_unslash( $_POST[ $prefix . 'timezone' ] ) ) : null, 614 'platform' => ! empty( $_POST[ $prefix . 'platform' ] ) ? sanitize_text_field( wp_unslash( $_POST[ $prefix . 'platform' ] ) ) : null, 615 'screens' => ! empty( $_POST[ $prefix . 'screens' ] ) ? sanitize_text_field( wp_unslash( $_POST[ $prefix . 'screens' ] ) ) : null, 616 'memory' => ! empty( $_POST[ $prefix . 'memory' ] ) ? intval( $_POST[ $prefix . 'memory' ] ) : null, 617 'user_agent' => ! empty( $_POST[ $prefix . 'user_agent' ] ) ? sanitize_text_field( wp_unslash( $_POST[ $prefix . 'user_agent' ] ) ) : null, 618 'app_version' => ! empty( $_POST[ $prefix . 'app_version' ] ) ? sanitize_text_field( wp_unslash( $_POST[ $prefix . 'app_version' ] ) ) : null, 619 'webdriver' => ! empty( $_POST[ $prefix . 'webdriver' ] ) ? sanitize_text_field( wp_unslash( $_POST[ $prefix . 'webdriver' ] ) ) : null, 620 'session_storage' => ! empty( $_POST[ $prefix . 'session_storage' ] ) ? intval( $_POST[ $prefix . 'session_storage' ] ) : null, 621 'bot_fingerprint' => ! empty( $_POST[ $prefix . 'bot_fingerprint' ] ) ? sanitize_text_field( wp_unslash( $_POST[ $prefix . 'bot_fingerprint' ] ) ) : null, 622 'touch' => ! empty( $_POST[ $prefix . 'touch' ] ), 623 ); 624 625 $fails = array(); 626 if ( ! $bot_fingerprint['timezone'] ) $fails[] = 'timezone'; 627 if ( ! $bot_fingerprint['platform'] ) $fails[] = 'platform'; 628 if ( ! $bot_fingerprint['screens'] ) $fails[] = 'screens'; 629 if ( ! $bot_fingerprint['user_agent'] ) $fails[] = 'user_agent'; 630 if ( ! $bot_fingerprint['app_version'] ) $fails[] = 'app_version'; 631 if ( ! $bot_fingerprint['webdriver'] ) $fails[] = 'webdriver'; 632 if ( ! $bot_fingerprint['session_storage'] ) $fails[] = 'session_storage'; 633 if ( 5 !== strlen( $bot_fingerprint['bot_fingerprint'] ) ) $fails[] = 'bot_fingerprint'; 634 635 if ( isset( $_POST[ $prefix . 'isIos' ] ) || isset( $_POST[ $prefix . 'isFFox' ] ) || isset( $_POST[ $prefix . 'isIE' ] ) ) { 636 if ( $bot_fingerprint['memory'] ) $fails[] = 'memory_supported'; 637 } elseif ( ! $bot_fingerprint['memory'] ) { 638 $fails[] = 'memory'; 639 } 640 641 if ( isset( $_POST[ $prefix . 'isIos' ] ) || isset( $_POST[ $prefix . 'isAndroid' ] ) ) { 642 if ( ! $bot_fingerprint['touch'] ) $fails[] = 'touch'; 643 } 644 645 if ( ! empty( $fails ) ) { 646 $data['spam_score'] += count( $fails ) * $score_fingerprinting; 647 $data['reasons']['bot_fingerprint'] = implode( ', ', $fails ); 648 cf7a_log( "The {$data['remote_ip']} ip hasn't passed fingerprint test ({$data['reasons']['bot_fingerprint']})", 1 ); 649 } 650 651 return $data; 652 } 653 654 /** 655 * Checks Bot Fingerprint Extras (User activity). 656 */ 657 public function filter_bot_fingerprint_extras( $data ) { 658 if ( $data['is_whitelisted'] ) return $data; 659 if ( $data['is_spam'] ) return $data; 660 661 $options = $data['options']; 662 if ( intval( $options['check_bot_fingerprint_extras'] ) !== 1 ) return $data; 663 664 $prefix = sanitize_text_field( $options['cf7a_customizations_prefix'] ); 665 $score_fingerprinting = floatval( $options['score']['_fingerprinting'] ); 666 667 $extras = array( 668 'activity' => ! empty( $_POST[ $prefix . 'activity' ] ) ? intval( $_POST[ $prefix . 'activity' ] ) : 0, 669 'mouseclick_activity' => ! empty( $_POST[ $prefix . 'mouseclick_activity' ] ) && sanitize_text_field( wp_unslash( $_POST[ $prefix . 'mouseclick_activity' ] ) ) === 'passed', 670 'mousemove_activity' => ! empty( $_POST[ $prefix . 'mousemove_activity' ] ) && sanitize_text_field( wp_unslash( $_POST[ $prefix . 'mousemove_activity' ] ) ) === 'passed', 671 'webgl' => ! empty( $_POST[ $prefix . 'webgl' ] ) && sanitize_text_field( wp_unslash( $_POST[ $prefix . 'webgl' ] ) ) === 'passed', 672 'webgl_render' => ! empty( $_POST[ $prefix . 'webgl_render' ] ) && sanitize_text_field( wp_unslash( $_POST[ $prefix . 'webgl_render' ] ) ) === 'passed', 673 'bot_fingerprint_extras' => empty( $_POST[ $prefix . 'bot_fingerprint_extras' ] ), 674 ); 675 676 $fails = array(); 677 if ( $extras['activity'] < 3 ) $fails[] = "activity {$extras["activity"]}"; 678 if ( empty( $extras['mouseclick_activity'] ) ) $fails[] = 'mouseclick_activity'; 679 if ( empty( $extras['mousemove_activity'] ) ) $fails[] = 'mousemove_activity'; 680 if ( empty( $extras['webgl'] ) ) $fails[] = 'webgl'; 681 if ( empty( $extras['webgl_render'] ) ) $fails[] = 'webgl_render'; 682 if ( empty( $extras['bot_fingerprint_extras'] ) ) $fails[] = 'bot_fingerprint_extras'; 683 684 if ( ! empty( $fails ) ) { 685 $data['spam_score'] += count( $fails ) * $score_fingerprinting; 686 $data['reasons']['bot_fingerprint_extras'] = implode( ', ', $fails ); 687 cf7a_log( "The {$data['remote_ip']} ip hasn't passed fingerprint extra test", 1 ); 688 } 689 690 return $data; 691 } 692 693 /** 694 * Checks Language consistency. 695 */ 696 public function filter_language( $data ) { 697 if ( $data['is_whitelisted'] ) return $data; 698 if ( $data['is_spam'] ) return $data; 699 700 $options = $data['options']; 701 if ( intval( $options['check_language'] ) !== 1 ) return $data; 702 703 $prefix = sanitize_text_field( $options['cf7a_customizations_prefix'] ); 704 $score_detection = floatval( $options['score']['_detection'] ); 705 706 $languages = array(); 707 $languages['browser_language'] = ! empty( $_POST[ $prefix . 'browser_language' ] ) ? sanitize_text_field( wp_unslash( $_POST[ $prefix . 'browser_language' ] ) ) : null; 708 709 // The right way to do this is BEFORE decrypting and THEN sanitize, because sanitized data are stripped of any special characters 710 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 711 $languages['accept_language'] = isset( $_POST[ $prefix . '_language' ] ) ? sanitize_text_field( wp_unslash( cf7a_decrypt( $_POST[ $prefix . '_language' ], $options['cf7a_cipher'] ) ) ) : null; 712 713 if ( empty( $languages['browser_language'] ) ) { 714 $data['spam_score'] += $score_detection; 715 $data['reasons']['browser_language'] = 'missing browser language'; 716 } else { 717 $languages_locales = cf7a_get_browser_languages_locales_array( $languages['browser_language'] ); 718 $languages['browser'] = $languages_locales['languages']; 719 } 720 721 if ( empty( $languages['accept_language'] ) ) { 722 $data['spam_score'] += $score_detection; 723 $data['reasons']['language_field'] = 'missing language field'; 724 } else { 725 $languages['accept'] = cf7a_get_accept_language_array( $languages['accept_language'] ); 726 } 727 728 if ( ! empty( $languages['accept'] ) && ! empty( $languages['browser'] ) ) { 729 if ( ! array_intersect( $languages['browser'], $languages['accept'] ) ) { 730 $data['spam_score'] += $score_detection; 731 $data['reasons']['language_incoherence'] = 'languages detected not coherent'; 732 } 733 734 $client_languages = array_unique( array_merge( $languages['browser'], $languages['accept'] ) ); 735 $languages_allowed = isset( $options['languages_locales']['allowed'] ) ? $this->cf7a_get_languages_or_locales( $options['languages_locales']['allowed'], 'languages' ) : array(); 736 $languages_disallowed = isset( $options['languages_locales']['disallowed'] ) ? $this->cf7a_get_languages_or_locales( $options['languages_locales']['disallowed'], 'languages' ) : array(); 737 738 $language_disallowed = $this->cf7a_check_languages_locales_allowed( $client_languages, $languages_disallowed, $languages_allowed ); 739 740 if ( false === $language_disallowed ) { 741 $data['spam_score'] += $score_detection; 742 $data['reasons']['browser_language'] = implode( ', ', $client_languages ); 743 } 744 } 745 return $data; 746 } 747 748 /** 749 * Checks GeoIP Location. 750 */ 751 public function filter_geoip( $data ) { 752 if ( $data['is_whitelisted'] ) return $data; 753 if ( $data['is_spam'] ) return $data; 754 755 $options = $data['options']; 756 if ( intval( $options['check_geo_location'] ) !== 1 ) return $data; 757 758 $geoip = new CF7_Antispam_Geoip(); 759 $score_warn = floatval( $options['score']['_warn'] ); 760 $locales_allowed = $this->cf7a_get_languages_or_locales( $options['languages_locales']['allowed'], 'locales' ); 761 $locales_disallowed = $this->cf7a_get_languages_or_locales( $options['languages_locales']['disallowed'], 'locales' ); 762 763 if ( ! empty( $geoip ) ) { 764 try { 765 $geoip_data = $geoip->check_ip( $data['remote_ip'] ); 766 $geoip_continent = isset( $geoip_data['continent'] ) ? ( $geoip_data['continent'] ) : false; 767 $geoip_country = isset( $geoip_data['country'] ) ? ( $geoip_data['country'] ) : false; 768 $geo_data = array_filter( array( $geoip_continent, $geoip_country ) ); 769 770 if ( ! empty( $geo_data ) ) { 771 if ( false === $this->cf7a_check_languages_locales_allowed( $geo_data, $locales_disallowed, $locales_allowed ) ) { 772 $data['reasons']['geo_ip'] = $geoip_continent . '-' . $geoip_country; 773 $data['spam_score'] += $score_warn; 774 cf7a_log( "The {$data['remote_ip']} is not allowed by geoip" . $data['reasons']['geo_ip'], 1 ); 775 } 776 } else { 777 $data['reasons']['no_geo_ip'] = 'unknown ip'; 778 } 779 } catch ( Exception $e ) { 780 cf7a_log( "unable to check geoip for {$data['remote_ip']} - " . $e->getMessage(), 1 ); 781 } 782 } 783 return $data; 784 } 785 786 /** 787 * Checks Time of submission. 788 */ 789 public function filter_time_submission( $data ) { 790 if ( $data['is_whitelisted'] ) return $data; 791 if ( $data['is_spam'] ) return $data; 792 793 $options = $data['options']; 794 if ( intval( $options['check_time'] ) !== 1 ) return $data; 795 796 $prefix = sanitize_text_field( $options['cf7a_customizations_prefix'] ); 797 798 $score_time = floatval( $options['score']['_time'] ); 799 $score_detection = floatval( $options['score']['_detection'] ); 800 801 // The right way to do this is BEFORE decrypting and THEN sanitize, because sanitized data are stripped of any special characters 802 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 803 $timestamp = isset( $_POST[ $prefix . '_timestamp' ] ) ? intval( cf7a_decrypt( $_POST[ $prefix . '_timestamp' ], $options['cf7a_cipher'] ) ) : 0; 804 $time_now = time(); 805 $time_elapsed_min = intval( $options['check_time_min'] ); 806 $time_elapsed_max = intval( $options['check_time_max'] ); 807 808 if ( ! $timestamp ) { 809 $data['spam_score'] += $score_detection; 810 $data['reasons']['timestamp'] = 'missing field'; 811 cf7a_log( "The {$data['remote_ip']} ip _timestamp field is missing", 1 ); 812 } else { 813 $time_elapsed = $time_now - $timestamp; 814 815 if ( 0 !== $time_elapsed_min && $time_elapsed < $time_elapsed_min ) { 816 $data['spam_score'] += $score_time; 817 $data['reasons']['min_time_elapsed'] = $time_elapsed; 818 cf7a_log( "The {$data['remote_ip']} ip took too little time ($time_elapsed s)", 1 ); 819 } 820 821 if ( 0 !== $time_elapsed_max && $time_elapsed > $time_elapsed_max ) { 822 $data['spam_score'] += $score_time; 823 $data['reasons']['max_time_elapsed'] = $time_elapsed; 824 cf7a_log( "The {$data['remote_ip']} ip took too much time ($time_elapsed s)", 1 ); 825 } 826 } 827 return $data; 828 } 829 830 /** 831 * Checks for bad strings inside the email address. 832 */ 833 public function filter_bad_email_strings( $data ) { 834 if ( $data['is_whitelisted'] ) return $data; 835 if ( $data['is_spam'] ) return $data; 836 837 $options = $data['options']; 838 if ( intval( $options['check_bad_email_strings'] ) !== 1 || empty( $data['emails'] ) ) return $data; 839 840 $score_bad_string = floatval( $options['score']['_bad_string'] ); 841 $bad_email_strings = isset( $options['bad_email_strings_list'] ) ? $options['bad_email_strings_list'] : array(); 842 843 foreach ( $data['emails'] as $email ) { 844 foreach ( $bad_email_strings as $bad_email_string ) { 845 if ( false !== stripos( strtolower( $email ), strtolower( $bad_email_string ) ) ) { 846 $data['spam_score'] += $score_bad_string; 847 $data['reasons']['email_blacklisted'][] = $bad_email_string; 848 } 849 } 850 } 851 852 if ( isset( $data['reasons']['email_blacklisted'] ) && is_array($data['reasons']['email_blacklisted']) ) { 853 $data['reasons']['email_blacklisted'] = implode( ',', $data['reasons']['email_blacklisted'] ); 854 cf7a_log( "The ip address {$data['remote_ip']} sent a mail using bad string {$data['reasons']['email_blacklisted']}", 1 ); 855 } 856 857 return $data; 858 } 859 860 /** 861 * Checks User Agent. 862 */ 863 public function filter_user_agent( $data ) { 864 if ( $data['is_whitelisted'] ) return $data; 865 if ( $data['is_spam'] ) return $data; 866 867 $options = $data['options']; 868 if ( intval( $options['check_bad_user_agent'] ) !== 1 ) return $data; 869 870 $score_detection = floatval( $options['score']['_detection'] ); 871 $score_bad_string = floatval( $options['score']['_bad_string'] ); 872 $bad_user_agent_list = isset( $options['bad_user_agent_list'] ) ? $options['bad_user_agent_list'] : array(); 873 874 if ( ! $data['user_agent'] ) { 875 $data['spam_score'] += $score_detection; 876 $data['reasons']['user_agent'] = 'empty'; 877 cf7a_log( "The {$data['remote_ip']} ip user agent is empty", 1 ); 878 } else { 879 foreach ( $bad_user_agent_list as $bad_user_agent ) { 880 if ( false !== stripos( strtolower( $data['user_agent'] ), strtolower( $bad_user_agent ) ) ) { 881 $data['spam_score'] += $score_bad_string; 882 $data['reasons']['user_agent'][] = $bad_user_agent; 883 } 884 } 885 886 if ( isset( $data['reasons']['user_agent'] ) && is_array( $data['reasons']['user_agent'] ) ) { 887 $data['reasons']['user_agent'] = implode( ', ', $data['reasons']['user_agent'] ); 888 cf7a_log( "The {$data['remote_ip']} ip user agent was listed into bad user agent list", 1 ); 889 } 890 } 891 return $data; 892 } 893 894 /** 895 * Checks for bad words in message. 896 */ 897 public function filter_bad_words( $data ) { 898 if ( $data['is_whitelisted'] ) return $data; 899 if ( $data['is_spam'] ) return $data; 900 901 $options = $data['options']; 902 if ( intval( $options['check_bad_words'] ) !== 1 || '' === $data['message'] ) return $data; 903 904 $score_bad_string = floatval( $options['score']['_bad_string'] ); 905 $bad_words = $options['bad_words_list'] ?? array(); 906 $message_compressed = $this->cf7a_simplify_text( $data['message'] ); 907 908 foreach ( $bad_words as $bad_word ) { 909 if ( false !== stripos( $message_compressed, $this->cf7a_simplify_text( $bad_word ) ) ) { 910 $data['spam_score'] += $score_bad_string; 911 $data['reasons']['bad_word'][] = $bad_word; 912 } 913 } 914 915 if ( ! empty( $data['reasons']['bad_word'] ) && is_array($data['reasons']['bad_word']) ) { 916 $data['reasons']['bad_word'] = implode( ',', $data['reasons']['bad_word'] ); 917 cf7a_log( "{$data['remote_ip']} has bad word in message " . $data['reasons']['bad_word'], 1 ); 918 } 919 return $data; 920 } 921 922 /** 923 * Checks DNS Blacklist. 924 */ 925 public function filter_dnsbl( $data ) { 926 if ( $data['is_whitelisted'] ) return $data; 927 if ( $data['is_spam'] ) return $data; 928 929 $options = $data['options']; 930 if ( intval( $options['check_dnsbl'] ) !== 1 || ! $data['remote_ip'] ) return $data; 931 932 $score_dnsbl = floatval( $options['score']['_dnsbl'] ); 933 $reverse_ip = ''; 934 935 if ( filter_var( $data['remote_ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ) { 936 $reverse_ip = $this->cf7a_reverse_ipv4( $data['remote_ip'] ); 937 } elseif ( filter_var( $data['remote_ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) { 938 $reverse_ip = $this->cf7a_reverse_ipv6( $data['remote_ip'] ); 939 } 940 941 foreach ( $options['dnsbl_list'] as $dnsbl ) { 942 if ( $this->cf7a_check_dnsbl( $reverse_ip, $dnsbl ) ) { 943 $data['reasons']['dsnbl'][] = $dnsbl; 944 $data['spam_score'] += $score_dnsbl; 945 } 946 } 947 948 if ( isset( $data['reasons']['dsnbl'] ) && is_array( $data['reasons']['dsnbl'] ) ) { 949 $data['reasons']['dsnbl'] = implode( ', ', $data['reasons']['dsnbl'] ); 950 cf7a_log( "{$data['remote_ip']} is listed in DNSBL ({$data['reasons']['dsnbl']})", 1 ); 951 } 952 return $data; 953 } 954 955 /** 956 * Checks visible honeypot fields. 957 */ 958 public function filter_honeypot( $data ) { 959 if ( $data['is_whitelisted'] ) return $data; 960 if ( $data['is_spam'] ) return $data; 961 962 $options = $data['options']; 963 if ( ! $options['check_honeypot'] ) return $data; 964 965 $mail_tag_text = array(); 966 foreach ( $data['mail_tags'] as $mail_tag ) { 967 if ( 'text' === $mail_tag['type'] || 'text*' === $mail_tag['type'] ) { 968 $mail_tag_text[] = $mail_tag['name']; 969 } 970 } 971 972 if ( ! empty( $mail_tag_text ) ) { 973 $input_names = cf7a_get_honeypot_input_names( $options['honeypot_input_names'] ); 974 $mail_tag_count = count( $input_names ); 975 $score_honeypot = floatval( $options['score']['_honeypot'] ); 976 977 for ( $i = 0; $i < $mail_tag_count; $i++ ) { 978 $has_honeypot = ! empty( $_POST[ $input_names[ $i ] ] ); 979 if ( $has_honeypot ) { 980 $data['spam_score'] += $score_honeypot; 981 $data['reasons']['honeypot'][] = $input_names[ $i ]; 982 } 983 } 984 985 if ( ! empty( $data['reasons']['honeypot'] ) && is_array($data['reasons']['honeypot']) ) { 986 $data['reasons']['honeypot'] = implode( ', ', $data['reasons']['honeypot'] ); 987 cf7a_log( "The {$data['remote_ip']} has filled the input honeypot(s) {$data['reasons']['honeypot']}", 1 ); 988 } 989 } 990 return $data; 991 } 992 993 /** 994 * Checks B8 Bayesian Filter. 995 * Now hooks into 'cf7a_check_b8'. 996 */ 997 public function filter_b8_bayesian( $data ) { 998 // Even if requested "at the end", we usually skip B8 if the user is explicitly Whitelisted. 999 if ( $data['is_whitelisted'] ) return $data; 1000 1001 $options = $data['options']; 1002 $text = stripslashes( $data['message'] ); 1003 \assert( \is_string( $text ) ); 1004 1005 // Ensure B8 is enabled and there is a message to check 1006 if ( $options['enable_b8'] && $data['message'] ) { 1007 $b8_threshold = floatval( $options['b8_threshold'] ); 1008 $b8_threshold = $b8_threshold > 0 && $b8_threshold < 1 ? $b8_threshold : 1; 1009 $score_detection = floatval( $options['score']['_detection'] ); 1010 1011 $cf7a_b8 = new CF7_AntiSpam_B8(); 1012 $rating = round( $cf7a_b8->cf7a_b8_classify( $text ), 2 ); 1013 1014 // If the rating is high, add to spam score 1015 if ( $rating >= $b8_threshold ) { 1016 $data['reasons']['b8'] = $rating; 1017 $data['spam_score'] += $score_detection; 1018 $data['is_spam'] = true; 1019 cf7a_log( "B8 rating $rating / 1", 1 ); 1020 } 1021 1022 // LEARNING LOGIC: 1023 // Use the accumulated spam_score from previous filters to decide how to teach B8. 1024 1025 if ( $data['spam_score'] >= 1 || $data['is_spam'] ) { 1026 // If previous filters OR B8 itself marked it as spam -> Learn Spam 1027 cf7a_log( "{$data['remote_ip']} detected as spam (score {$data['spam_score']}), learning as SPAM.", 1 ); 1028 $cf7a_b8->cf7a_b8_learn_spam( $text ); 1029 } elseif ( $rating < $b8_threshold * 0.5 ) { 1030 // If no spam detected and B8 thinks it's safe -> Learn Ham 1031 cf7a_log( "B8 detected spamminess of $rating (below threshold), learning as HAM.", 1 ); 1032 $cf7a_b8->cf7a_b8_learn_ham( $text ); 1033 } 1034 } 1035 return $data; 1036 } 1037 1038 /** 1039 * Sends an email to the admin, warning them to clear the cache. 1040 * @param array $update_data the array of data to be sent to the admin 1041 * @return void 1042 */ 1043 private function send_cache_warning_email( $update_data ): void { 1044 $tools = new CF7_AntiSpam_Admin_Tools(); 1045 $recipient = get_option( 'admin_email' ); 1046 $body = sprintf( 1047 "Hello Admin,\n\nWe detected 5 users trying to submit forms with the old version (%s) instead of the new one (%s).\n\nThis usually means your website cache (or CDN) hasn't been cleared after the last update.\n\nPlease purge your site cache immediately to prevent legitimate users from being flagged as spam.\n\nTime of update: %s", 1048 $update_data['old_version'], 1049 $update_data['new_version'], 1050 gmdate( 'Y-m-d H:i:s', $update_data['time'] ) 1051 ); 1052 $subject = 'CF7 AntiSpam - Cache Warning Alert'; 1053 1054 $tools->send_email_to_admin( $subject, $recipient, $body, $recipient ); 1055 } 1066 1056 } -
cf7-antispam/trunk/core/CF7_AntiSpam_Flamingo.php
r3389259 r3402920 3 3 namespace CF7_AntiSpam\Core; 4 4 5 use CF7_AntiSpam\Admin\CF7_AntiSpam_Admin_Tools; 5 6 use WP_Query; 6 7 use WPCF7_ContactForm; … … 110 111 $rating = ! empty( $flamingo_post->meta['_cf7a_b8_classification'] ) ? $flamingo_post->meta['_cf7a_b8_classification'] : $b8->cf7a_b8_classify( $message ); 111 112 112 $filters = new CF7_AntiSpam_Filters();113 114 113 if ( ! $flamingo_post->spam && 'spam' === $action ) { 115 114 $b8->cf7a_b8_unlearn_ham( $message ); … … 117 116 118 117 if ( $options['autostore_bad_ip'] ) { 119 $filters->cf7a_ban_by_ip( $flamingo_post->meta['remote_ip'], 'flamingo ban' );118 CF7_Antispam_Blacklist::cf7a_ban_by_ip( $flamingo_post->meta['remote_ip'], 'flamingo ban' ); 120 119 } 121 120 } elseif ( $flamingo_post->spam && 'ham' === $action ) { … … 124 123 125 124 if ( $options['autostore_bad_ip'] ) { 126 $filters->cf7a_unban_by_ip( $flamingo_post->meta['remote_ip'] );125 CF7_Antispam_Blacklist::cf7a_unban_by_ip( $flamingo_post->meta['remote_ip'] ); 127 126 } 128 127 } … … 211 210 * @return array { success: boolean, message: string } 212 211 */ 213 public function cf7a_resend_mail( $mail_id ){212 public function cf7a_resend_mail( int $mail_id ): array { 214 213 $flamingo_data = new Flamingo_Inbound_Message( $mail_id ); 215 214 $message = self::cf7a_get_mail_field( $flamingo_data, 'message' ); … … 267 266 } 268 267 269 /** 270 * Filter cf7-antispam before resend an email who was spammed 271 * 272 * @param string $body the mail message content 273 * @param string $sender the mail message sender 274 * @param string $subject the mail message subject 275 * @param string $recipient the mail recipient 276 * 277 * @returns string the mail body content 278 */ 279 $body = apply_filters( 'cf7a_before_resend_email', $body, $sender, $subject, $recipient ); 280 281 // Set up headers correctly 282 $site_name = get_bloginfo( 'name' ); 283 $from_email = get_option( 'admin_email' ); 284 285 $headers = "From: {$site_name} <{$from_email}>\n"; 286 $headers .= "Content-Type: text/html\n"; 287 $headers .= "X-WPCF7-Content-Type: text/html\n"; 288 $headers .= "Reply-To: {$sender}\n"; 289 290 /* send the email */ 291 $result = wp_mail( $recipient, $subject, $body, $headers ); 268 $tools = new CF7_AntiSpam_Admin_Tools(); 269 $result = $tools->send_email_to_admin( $subject, $recipient, $body, $sender ); 270 292 271 if ( $result ) { 293 272 return array( 'success'=> true, 'message' => __( 'Email sent with success', 'cf7-antispam' ) ); … … 298 277 299 278 /** 300 * Parse CF7 mail tags in recipient field279 * Parse CF7 mail tags in the recipient field 301 280 * 302 281 * @param string $recipient The recipient string that may contain CF7 tags -
cf7-antispam/trunk/core/CF7_AntiSpam_Frontend.php
r3389259 r3402920 28 28 * @var string $plugin_name The ID of this plugin. 29 29 */ 30 private $plugin_name;30 private string $plugin_name; 31 31 32 32 /** … … 37 37 * @var string $version The current version of this plugin. 38 38 */ 39 private $version;39 private string $version; 40 40 41 41 /** … … 46 46 * @var array $options options of this plugin. 47 47 */ 48 private $options;48 private array $options; 49 49 50 50 /** … … 62 62 } 63 63 64 /** 65 * Checks if the contact form 7 shortcode exists in the current post 66 * 67 * @return bool 68 */ 69 private function cf7_shortcode_exists() { 70 global $post; 71 return is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'contact-form-7' ); 72 // Register the contact form antispam scripts 73 } 74 75 76 /** 77 * Handles loading scripts 78 * 79 * @return void 80 */ 81 public function load_scripts() { 82 // Register the contact form antispam scripts 83 add_action('wp_enqueue_scripts', array($this, 'register_scripts')); 84 85 // Select the hook to use based on the User's choice 86 $hook = !empty($this->options['optimize_scripts_loading']) ? 'wpcf7_enqueue_scripts' : 'wp_enqueue_scripts'; 87 88 // enqueue CF7 antispam scripts only if contact form 7 wpcf7_enqueue_scripts is called 89 add_action( $hook, array( $this, 'enqueue_scripts' )); 90 } 91 64 92 public function setup() { 65 if ( ! $this->cf7_shortcode_exists() ) {66 return;67 }68 69 93 /* It adds hidden fields to the form */ 70 94 add_filter( 'wpcf7_form_hidden_fields', array( $this, 'cf7a_add_hidden_fields' ), 1 ); 71 95 add_filter( 'wpcf7_config_validator_available_error_codes', array( $this, 'cf7a_remove_cf7_error_message' ), 10, 2 ); 72 96 73 /* adds the javascript script to frontend */74 add_action( 'wp_footer', array( $this, 'enqueue_scripts' ) );75 97 76 98 /* It adds a hidden field to the form with a unique value that is encrypted with a cipher */ … … 120 142 add_action( 'wp_footer', array( $this, 'cf7a_add_honeypot_css' ), 11 ); 121 143 } 122 }123 124 private function cf7_shortcode_exists() {125 global $post;126 return is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'contact-form-7' );127 144 } 128 145 … … 354 371 * 355 372 * @param array $fields the array of hidden fields that will be added to the form. 373 * @return array the array of hidden fields that will be added to the form. 374 * the returned fields are: version, address, referer, protocol 375 * the optional fields are: language, timestamp, hash 376 * the optional fields are added based on the options set in the plugin 377 * the fields are encrypted with the cipher set in the plugin 356 378 */ 357 379 public function cf7a_add_hidden_fields( $fields ) { … … 386 408 $prefix . 'version' => '1.0', 387 409 $prefix . 'address' => cf7a_crypt( cf7a_get_real_ip(), $this->options['cf7a_cipher'] ), 388 $prefix . 'referer' => cf7a_crypt( $referrer ? $referrer : ' no referer', $this->options['cf7a_cipher'] ),389 $prefix . 'protocol' => cf7a_crypt( $protocol ? $protocol : ' protocol missing', $this->options['cf7a_cipher'] ),410 $prefix . 'referer' => cf7a_crypt( $referrer ? $referrer : '', $this->options['cf7a_cipher'] ), 411 $prefix . 'protocol' => cf7a_crypt( $protocol ? $protocol : '', $this->options['cf7a_cipher'] ), 390 412 ) 391 413 ); … … 515 537 * @since 0.1.0 516 538 */ 517 public function enqueue_scripts() { 518 539 public function register_scripts() { 519 540 /** 520 541 * … … 530 551 $asset = include CF7ANTISPAM_PLUGIN_DIR . '/build/script.asset.php'; 531 552 wp_register_script( $this->plugin_name, CF7ANTISPAM_PLUGIN_URL . '/build/script.js', $asset['dependencies'], $asset['version'], true ); 532 wp_enqueue_script( $this->plugin_name );533 553 534 554 wp_localize_script( … … 541 561 ) 542 562 ); 563 } 564 565 /** 566 * Register the JavaScript for the admin area. 567 * 568 * @since 0.1.0 569 */ 570 public function enqueue_scripts() { 571 wp_enqueue_script( $this->plugin_name ); 543 572 } 544 573 -
cf7-antispam/trunk/core/CF7_Antispam_Blacklist.php
r3389259 r3402920 24 24 25 25 /** 26 * It takes an IP address as a parameter, validates it, and then returns the row from the database that matches that IP 27 * address 28 * 29 * @param string $ip - The IP address to check. 30 * 31 * @return array|object|null - the row from the database that matches the IP address. 32 */ 33 public static function cf7a_blacklist_get_ip( $ip ) { 34 $ip = filter_var( $ip, FILTER_VALIDATE_IP ); 35 if ( $ip ) { 36 global $wpdb; 37 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching 38 $r = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM %i WHERE ip = %s", $wpdb->prefix . 'cf7a_blacklist', $ip ) ); 39 if ( $r ) { 40 return $r; 41 } 42 } 43 44 return null; 45 } 46 47 /** 48 * It adds an IP address to the blacklist. 49 * 50 * @param string $ip The IP address to ban. 51 * @param array $reason The reason why the IP is being banned. 52 * @param int $spam_score This is the number of points that will be added to the IP's spam score. 53 * 54 * @return bool true if the given id was banned 55 */ 56 public static function cf7a_ban_by_ip( string $ip, array $reason = array(), $spam_score = 1 ): bool { 57 $ip = filter_var( $ip, FILTER_VALIDATE_IP ); 58 59 if ( $ip ) { 60 global $wpdb; 61 62 $ip_row = CF7_Antispam_Blacklist::cf7a_blacklist_get_ip( $ip ); 63 64 if ( $ip_row ) { 65 // if the ip is in the blacklist, update the status 66 $status = isset( $ip_row->status ) ? floatval( $ip_row->status ) + floatval( $spam_score ) : 1; 67 68 } else { 69 // if the ip is not in the blacklist, add it and initialize the status 70 $status = floatval( $spam_score ); 71 } 72 73 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching 74 $r = $wpdb->replace( $wpdb->prefix . 'cf7a_blacklist', array( 75 'ip' => $ip, 76 'status' => $status, 77 'meta' => serialize( array( 78 'reason' => $reason, 79 'meta' => null, 80 ) ), 81 ), array( '%s', '%d', '%s' ) ); 82 83 if ( $r > - 1 ) { 84 return true; 85 } 86 } 87 88 return false; 89 } 90 91 /** 92 * It deletes the IP address from the database 93 * 94 * @param string $ip The IP address to unban. 95 * 96 * @return int|false The number of rows deleted. 97 */ 98 public static function cf7a_unban_by_ip( $ip ) { 99 $ip = filter_var( $ip, FILTER_VALIDATE_IP ); 100 101 if ( $ip ) { 102 global $wpdb; 103 104 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching 105 $r = $wpdb->delete( $wpdb->prefix . 'cf7a_blacklist', array( 106 'ip' => $ip, 107 ), array( 108 '%s', 109 ) ); 110 111 return ! is_wp_error( $r ) ? $r : $wpdb->last_error; 112 } 113 114 return false; 115 } 116 117 /** 26 118 * Get all blacklist data from database. 27 119 * … … 53 145 * @return object|null The blacklist entry or null if not found 54 146 */ 55 public function cf7a_blacklist_get_id( $id ) {147 public function cf7a_blacklist_get_id( int $id ) { 56 148 global $wpdb; 57 149 … … 108 200 // Add the IP to the permanent banlist 109 201 if ( CF7_AntiSpam::update_plugin_option( 'bad_ip_list', array_merge( $current_bad_ips, array( $ban_ip->ip ) ) ) ) { 110 // Remove from temporary blacklist111 202 $this->cf7a_unban_by_id( $id ); 112 203 } … … 315 406 ); 316 407 } 408 409 /** 410 * It updates the status of all the users in the blacklist table by subtracting 1 from the status column. 411 * 412 * Then it deletes all the users whose status is 0. 413 * The status column is the number of days the user is banned for. 414 * So if the user is banned for 3 days, the status column will be 3. After the first day, the status column will be 2. After the second day, the status column will be 1. After the third day, the status column will be 0. 415 * When the status column is 0, the user is unbanned. 416 * 417 * The function returns true if the user is unbanned. 418 * 419 * @return true. 420 */ 421 public function cf7a_cron_unban() { 422 global $wpdb; 423 424 /* We remove 1 from the status column */ 425 $status_decrement = 1; 426 427 /* Below 0 is not anymore a valid status for a blacklist entry, so we can remove it */ 428 $lower_bound = 0; 429 430 $blacklist_table = $wpdb->prefix . 'cf7a_blacklist'; 431 432 /* removes a status count at each balcklisted ip */ 433 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching 434 $updated = $wpdb->query( $wpdb->prepare( "UPDATE %i SET `status` = `status` - %d", $blacklist_table, $status_decrement ) ); 435 cf7a_log( "Status updated for blacklisted (score -1) - $updated users", 1 ); 436 437 /* when the line has 0 in status, we can remove it from the blacklist */ 438 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching 439 $updated_deletion = $wpdb->delete( 440 $blacklist_table, 441 array( 'status' => $lower_bound ), 442 array( '%d' ) 443 ); 444 cf7a_log( "Removed {$updated_deletion} users from blacklist", 1 ); 445 446 return true; 447 } 317 448 } -
cf7-antispam/trunk/core/functions.php
r3389259 r3402920 251 251 * @return string The decrypted value. 252 252 */ 253 function cf7a_decrypt( $value, $cipher = 'aes-256-cbc' ) { 254 if ( ! extension_loaded( 'openssl' ) ) { 253 function cf7a_decrypt( string $value, string $cipher = 'aes-256-cbc' ): string { 254 try { 255 if ( ! extension_loaded( 'openssl' ) ) { 256 return $value; 257 } 258 259 return openssl_decrypt( $value, $cipher, wp_salt( 'nonce' ), $options = 0, substr( wp_salt( 'nonce' ), 0, 16 ) ); 260 } catch ( Exception $e ) { 255 261 return $value; 256 262 } 257 258 return openssl_decrypt( $value, $cipher, wp_salt( 'nonce' ), $options = 0, substr( wp_salt( 'nonce' ), 0, 16 ) );259 263 } 260 264 … … 360 364 $v = '[]'; 361 365 } else { 362 // Convert e array in formato leggibile366 // Convert array to readable format 363 367 $v = '[' . implode( 364 ', ',365 array_map(366 function ( $item ) {367 return is_array( $item ) ? json_encode( $item ) : (string) $item;368 },369 $v370 )371 ) . ']';368 ', ', 369 array_map( 370 function ( $item ) { 371 return is_array( $item ) ? json_encode( $item ) : (string) $item; 372 }, 373 $v 374 ) 375 ) . ']'; 372 376 } 373 377 } elseif ( is_object( $v ) ) { -
cf7-antispam/trunk/engine/CF7_AntiSpam_Activator.php
r3394913 r3402920 46 46 'cf7a_cipher' => 'aes-128-cbc', 47 47 'cf7a_score_preset' => 'weak', 48 'cf7a_disable_reload' => true, 49 'check_bot_fingerprint' => true, 50 'check_bot_fingerprint_extras' => true, 51 'append_on_submit' => true, 48 'cf7a_disable_reload' => false, 49 'optimize_scripts_loading' => false, 50 'check_bot_fingerprint' => false, 51 'check_bot_fingerprint_extras' => false, 52 'append_on_submit' => false, 52 53 'check_time' => true, 53 54 'check_time_min' => 6, … … 214 215 215 216 /** 217 * Store the update data 218 * 219 * @param array $options - the options array. 220 */ 221 private static function store_update_data( $options ) { 222 /* update the plugin update time field */ 223 $options['last_update_data'] = array( 224 'time' => time(), 225 'old_version' => $options['cf7a_version'] ?? 'unknown', 226 'new_version' => CF7ANTISPAM_VERSION, 227 'errors' => array(), 228 ); 229 return $options; 230 } 231 232 /** 216 233 * Create or Update the CF7 Antispam options 217 234 * … … 236 253 237 254 } else { 238 239 /* update the plugin options but add the new options automatically */ 255 /* if the plugin is already installed, update the plugin options automatically */ 240 256 if ( isset( $options['cf7a_version'] ) ) { 241 unset( $options['cf7a_version'] ); 257 258 /* update the plugin last update time field if the current version is set (so we are updating the plugin and not installing it) */ 259 $options = self::store_update_data( $options ); 260 261 /* remove the version field */ 262 $options['cf7a_version'] = CF7ANTISPAM_VERSION; 242 263 } 243 264 -
cf7-antispam/trunk/languages/cf7-antispam.pot
r3389259 r3402920 3 3 msgid "" 4 4 msgstr "" 5 "Project-Id-Version: AntiSpam for Contact Form 7 0.7. 0\n"5 "Project-Id-Version: AntiSpam for Contact Form 7 0.7.2\n" 6 6 "Report-Msgid-Bugs-To: https://wordpress.org/support/plugins/cf7-antispam\n" 7 7 "MIME-Version: 1.0\n" … … 9 9 "Content-Type: text/plain; charset=iso-8859-1\n" 10 10 "Plural-Forms: nplurals=2; plural=(n!=1);\n" 11 "POT-Creation-Date: 2025-1 0-22T23:23:52.135Z\n"11 "POT-Creation-Date: 2025-11-25T22:42:09.543Z\n" 12 12 "PO-Revision-Date: 2025-MO-DA HO:MI+ZONE\n" 13 13 "Last-Translator: Codekraft <erik@codekraft.it>\n" … … 37 37 msgstr "" 38 38 39 #: engine/CF7_AntiSpam_Activator.php:2 5539 #: engine/CF7_AntiSpam_Activator.php:276 40 40 msgid "" 41 41 "CF7 AntiSpam updated successful! Please flush cache to refresh hidden form " … … 51 51 msgstr "" 52 52 53 #: core/functions.php:29 554 #: core/CF7_AntiSpam_Flamingo.php:4 8253 #: core/functions.php:299 54 #: core/CF7_AntiSpam_Flamingo.php:461 55 55 msgid "none" 56 56 msgstr "" 57 57 58 58 # warn because not yet banned but already listed 59 #: core/functions.php:31860 msgid "??"61 msgstr ""62 63 # champion of spammer (>100 mail)64 59 #: core/functions.php:322 65 60 msgid "??" 66 61 msgstr "" 67 62 63 # champion of spammer (>100 mail) 64 #: core/functions.php:326 65 msgid "??" 66 msgstr "" 67 68 68 #: core/CF7_Antispam_Service.php:78 69 #: admin/CF7_AntiSpam_Admin_Core.php:80 69 70 #: admin/CF7_AntiSpam_Admin_Core.php:81 70 #: admin/CF7_AntiSpam_Admin_Core.php:8271 71 msgid "Antispam" 72 72 msgstr "" … … 112 112 msgstr "" 113 113 114 #: core/CF7_AntiSpam_Rest_Api.php: 98114 #: core/CF7_AntiSpam_Rest_Api.php:101 115 115 msgid "You cannot view the plugin status." 116 116 msgstr "" 117 117 118 #: core/CF7_AntiSpam_Rest_Api.php:134 119 #: core/CF7_AntiSpam_Rest_Api.php:175 120 #: core/CF7_AntiSpam_Rest_Api.php:213 121 #: core/CF7_AntiSpam_Rest_Api.php:251 122 #: core/CF7_AntiSpam_Rest_Api.php:289 118 #: core/CF7_AntiSpam_Rest_Api.php:115 119 #: core/CF7_AntiSpam_Rest_Api.php:172 120 #: core/CF7_AntiSpam_Rest_Api.php:215 121 #: core/CF7_AntiSpam_Rest_Api.php:248 122 #: core/CF7_AntiSpam_Rest_Api.php:286 123 #: core/CF7_AntiSpam_Rest_Api.php:324 124 #: core/CF7_AntiSpam_Rest_Api.php:362 125 #: core/CF7_AntiSpam_Rest_Api.php:400 126 #: core/CF7_AntiSpam_Rest_Api.php:451 127 #: core/CF7_AntiSpam_Rest_Api.php:486 123 128 msgid "Invalid nonce" 124 129 msgstr "" 125 130 126 #: core/CF7_AntiSpam_Rest_Api.php:145 131 #: core/CF7_AntiSpam_Rest_Api.php:127 132 msgid "Error: unable to download GeoIP database" 133 msgstr "" 134 135 #: core/CF7_AntiSpam_Rest_Api.php:135 136 msgid "GeoIP database downloaded successfully" 137 msgstr "" 138 139 #: core/CF7_AntiSpam_Rest_Api.php:185 127 140 msgid "Error: unable to resend email with id %s." 128 141 msgstr "" 129 142 130 143 # %s is the mail id. 131 #: core/CF7_AntiSpam_Rest_Api.php:1 57144 #: core/CF7_AntiSpam_Rest_Api.php:197 132 145 msgid "Ops! something went wrong... unable to resend email with id %s" 133 146 msgstr "" 134 147 135 #: core/CF7_AntiSpam_Rest_Api.php:187 148 #: core/CF7_AntiSpam_Rest_Api.php:229 149 msgid "Nothing to update" 150 msgstr "" 151 152 #: core/CF7_AntiSpam_Rest_Api.php:232 153 msgid "Contact Form 7 Antispam Options and Database updated successfully!" 154 msgstr "" 155 156 #: core/CF7_AntiSpam_Rest_Api.php:260 136 157 msgid "Success: ip blacklist cleaned" 137 158 msgstr "" 138 159 139 #: core/CF7_AntiSpam_Rest_Api.php: 194160 #: core/CF7_AntiSpam_Rest_Api.php:267 140 161 msgid "Error: unable to clean blacklist. Please refresh and try again!" 141 162 msgstr "" 142 163 143 #: core/CF7_AntiSpam_Rest_Api.php:2 25164 #: core/CF7_AntiSpam_Rest_Api.php:298 144 165 msgid "b8 dictionary reset successful" 145 166 msgstr "" 146 167 147 #: core/CF7_AntiSpam_Rest_Api.php: 232168 #: core/CF7_AntiSpam_Rest_Api.php:305 148 169 msgid "" 149 170 "Something goes wrong while deleting b8 dictionary. Please refresh and try " … … 151 172 msgstr "" 152 173 153 #: core/CF7_AntiSpam_Rest_Api.php: 263174 #: core/CF7_AntiSpam_Rest_Api.php:336 154 175 msgid "" 155 176 "CF7 AntiSpam fully reinitialized with success. You need to rebuild B8 " … … 157 178 msgstr "" 158 179 159 #: core/CF7_AntiSpam_Rest_Api.php: 270180 #: core/CF7_AntiSpam_Rest_Api.php:343 160 181 msgid "Ops! something went wrong... Please refresh and try again!" 161 182 msgstr "" 162 183 163 #: core/CF7_AntiSpam_Rest_Api.php:3 00184 #: core/CF7_AntiSpam_Rest_Api.php:373 164 185 msgid "b8 dictionary rebuild successful" 165 186 msgstr "" 166 187 167 #: core/CF7_AntiSpam_Rest_Api.php:3 07188 #: core/CF7_AntiSpam_Rest_Api.php:380 168 189 msgid "" 169 190 "Something goes wrong while rebuilding b8 dictionary. Please refresh and try " … … 171 192 msgstr "" 172 193 173 #: core/CF7_Antispam_Geoip.php:275 174 #: core/CF7_Antispam_Geoip.php:290 175 msgid "" 176 "Unable to download the geo-ip database, please check that the key provided " 177 "is correct! " 178 msgstr "" 179 180 #: core/CF7_Antispam_Geoip.php:310 181 msgid "GEO-IP Database file decompression failed" 182 msgstr "" 183 184 #: core/CF7_Antispam_Geoip.php:330 185 msgid "GEO-IP decompressed database copy failed" 186 msgstr "" 187 188 #: core/CF7_AntiSpam_Frontend.php:571 194 #: core/CF7_AntiSpam_Rest_Api.php:411 195 #: core/CF7_AntiSpam_Rest_Api.php:462 196 msgid "Invalid ID" 197 msgstr "" 198 199 # %s is the ip address. 200 #: core/CF7_AntiSpam_Rest_Api.php:424 201 msgid "Success: ip %s unbanned" 202 msgstr "" 203 204 # %s is the ip address. 205 #: core/CF7_AntiSpam_Rest_Api.php:432 206 msgid "Error: unable to unban %s" 207 msgstr "" 208 209 #: core/CF7_AntiSpam_Rest_Api.php:497 210 msgid "Blacklist exported successfully" 211 msgstr "" 212 213 #: core/CF7_Antispam_Geoip.php:407 214 msgid "" 215 "Unable to download the geo-ip database. Please check that the key is " 216 "correct!" 217 msgstr "" 218 219 #: core/CF7_Antispam_Geoip.php:752 220 msgid "GEO-IP Database extraction failed" 221 msgstr "" 222 223 #: core/CF7_AntiSpam_Frontend.php:600 189 224 msgid "Missing hash." 190 225 msgstr "" 191 226 192 #: core/CF7_AntiSpam_Frontend.php: 576227 #: core/CF7_AntiSpam_Frontend.php:605 193 228 msgid "Something went wrong. Please reload the page." 194 229 msgstr "" 195 230 196 231 # % is the number of seconds to wait 197 #: core/CF7_AntiSpam_Frontend.php: 583232 #: core/CF7_AntiSpam_Frontend.php:612 198 233 msgid "Slow down, please wait %s seconds before resending." 199 234 msgstr "" 200 235 201 #: core/CF7_AntiSpam_Flamingo.php:10 8236 #: core/CF7_AntiSpam_Flamingo.php:109 202 237 msgid "%s has no message text so can't be analyzed" 203 238 msgstr "" 204 239 205 240 # %1$s is the mail "from" field (the sender). %2$s spam/ham. %3$s and %4$s the rating of the processed email (like 0.6/1) 206 #: core/CF7_AntiSpam_Flamingo.php:13 7241 #: core/CF7_AntiSpam_Flamingo.php:136 207 242 msgid "" 208 243 "b8 has learned this e-mail from %1$s was %2$s - score before/after: " … … 210 245 msgstr "" 211 246 212 #: core/CF7_AntiSpam_Flamingo.php:21 8247 #: core/CF7_AntiSpam_Flamingo.php:217 213 248 msgid "Cannot find the original post" 214 249 msgstr "" 215 250 216 #: core/CF7_AntiSpam_Flamingo.php:2 93251 #: core/CF7_AntiSpam_Flamingo.php:272 217 252 msgid "Email sent with success" 218 253 msgstr "" 219 254 220 #: core/CF7_AntiSpam_Flamingo.php:2 96255 #: core/CF7_AntiSpam_Flamingo.php:275 221 256 msgid "Ops! something went wrong... unable to resend email" 222 257 msgstr "" 223 258 224 #: core/CF7_AntiSpam_Flamingo.php:4 64259 #: core/CF7_AntiSpam_Flamingo.php:443 225 260 msgid "D8 classification" 226 261 msgstr "" 227 262 228 #: core/CF7_AntiSpam_Flamingo.php:4 65263 #: core/CF7_AntiSpam_Flamingo.php:444 229 264 msgid "CF7-AntiSpam actions" 230 265 msgstr "" 231 266 232 #: core/CF7_AntiSpam_Flamingo.php: 507267 #: core/CF7_AntiSpam_Flamingo.php:486 233 268 msgid "Do you want to resend this email?" 234 269 msgstr "" 235 270 236 #: core/CF7_AntiSpam_Flamingo.php: 508271 #: core/CF7_AntiSpam_Flamingo.php:487 237 272 msgid "Resend Email" 238 273 msgstr "" 239 274 240 #: core/CF7_AntiSpam.php:271 275 # the %1$s is the user id and %2$s is the ip address. 276 #: core/CF7_Antispam_Blacklist.php:209 277 msgid "Ban forever id %1$s (ip %2$s) successful" 278 msgstr "" 279 280 # the %1$s is the user id and %2$s is the ip address. 281 #: core/CF7_Antispam_Blacklist.php:219 282 msgid "Error: unable to ban forever id %1$s (ip %2$s)" 283 msgstr "" 284 285 #: core/CF7_AntiSpam.php:282 241 286 msgid "CF7 AntiSpam need " 242 287 msgstr "" 243 288 244 #: core/CF7_AntiSpam.php:2 73289 #: core/CF7_AntiSpam.php:284 245 290 msgid "Contact Form 7" 246 291 msgstr "" 247 292 248 #: core/CF7_AntiSpam.php:2 74293 #: core/CF7_AntiSpam.php:285 249 294 msgid " installed and enabled in order to work." 250 295 msgstr "" 251 296 252 297 # %1$s overall spam attempts, %2$s since last report 253 #: core/CF7_AntiSpam.php: 393298 #: core/CF7_AntiSpam.php:406 254 299 msgid "%1$s overall spam attempts, %2$s since last report" 255 msgstr ""256 257 #: admin/CF7_AntiSpam_Admin_Tools.php:80258 msgid "Success: ip %s unbanned"259 msgstr ""260 261 #: admin/CF7_AntiSpam_Admin_Tools.php:83262 msgid "Error: unable to unban %s"263 msgstr ""264 265 # the %1$s is the user id and %2$s is the ip address.266 #: admin/CF7_AntiSpam_Admin_Tools.php:107267 msgid "Ban forever id %1$s (ip %2$s) successful"268 msgstr ""269 270 # the %1$s is the user id and %2$s is the ip address.271 #: admin/CF7_AntiSpam_Admin_Tools.php:116272 msgid "Error: unable to ban forever id %1$s (ip %2$s)"273 300 msgstr "" 274 301 … … 297 324 msgstr "" 298 325 299 #: admin/CF7_AntiSpam_Admin_Display.php:1 47326 #: admin/CF7_AntiSpam_Admin_Display.php:159 300 327 msgid "Dismiss" 301 328 msgstr "" 302 329 303 #: admin/CF7_AntiSpam_Admin_Display.php:1 50330 #: admin/CF7_AntiSpam_Admin_Display.php:162 304 331 msgid "Before you cry over spilt mail…" 305 332 msgstr "" 306 333 307 #: admin/CF7_AntiSpam_Admin_Display.php:1 51334 #: admin/CF7_AntiSpam_Admin_Display.php:163 308 335 msgid "" 309 336 "Contact Form 7 doesn’t store submitted messages anywhere. Therefore, " … … 313 340 314 341 # %s: link labeled 'Flamingo' 315 #: admin/CF7_AntiSpam_Admin_Display.php:1 56342 #: admin/CF7_AntiSpam_Admin_Display.php:168 316 343 msgid "" 317 344 "Install a message storage plugin before this happens to you. %s saves all " … … 320 347 msgstr "" 321 348 322 #: admin/CF7_AntiSpam_Admin_Display.php:1 57349 #: admin/CF7_AntiSpam_Admin_Display.php:169 323 350 msgid "Flamingo" 324 351 msgstr "" 325 352 326 #: admin/CF7_AntiSpam_Admin_Display.php:1 64353 #: admin/CF7_AntiSpam_Admin_Display.php:176 327 354 msgid "PLEASE don't forget to add " 328 355 msgstr "" 329 356 330 #: admin/CF7_AntiSpam_Admin_Display.php:1 65357 #: admin/CF7_AntiSpam_Admin_Display.php:177 331 358 msgid "flamingo_message: \"[your-message]\" " 332 359 msgstr "" 333 360 334 #: admin/CF7_AntiSpam_Admin_Display.php:1 70361 #: admin/CF7_AntiSpam_Admin_Display.php:182 335 362 msgid "Please replace " 336 363 msgstr "" 337 364 338 #: admin/CF7_AntiSpam_Admin_Display.php:1 72365 #: admin/CF7_AntiSpam_Admin_Display.php:184 339 366 msgid "" 340 367 "with the message field used in your form because that is the field scanned " … … 342 369 msgstr "" 343 370 344 #: admin/CF7_AntiSpam_Admin_Display.php:1 73371 #: admin/CF7_AntiSpam_Admin_Display.php:185 345 372 msgid "additional settings section" 346 373 msgstr "" 347 374 348 #: admin/CF7_AntiSpam_Admin_Display.php:1 74375 #: admin/CF7_AntiSpam_Admin_Display.php:186 349 376 msgid "to enable the most advanced protection we can offer! Thank you!" 350 377 msgstr "" 351 378 352 #: admin/CF7_AntiSpam_Admin_Display.php:1 86379 #: admin/CF7_AntiSpam_Admin_Display.php:198 353 380 msgid "Email Statistics" 354 381 msgstr "" 355 382 356 #: admin/CF7_AntiSpam_Admin_Display.php:3 07383 #: admin/CF7_AntiSpam_Admin_Display.php:345 357 384 msgid "Warning Count Ranges" 358 385 msgstr "" 359 386 360 #: admin/CF7_AntiSpam_Admin_Display.php:3 11387 #: admin/CF7_AntiSpam_Admin_Display.php:349 361 388 msgid "Total Blocked IPs" 362 389 msgstr "" 363 390 364 #: admin/CF7_AntiSpam_Admin_Display.php:3 25391 #: admin/CF7_AntiSpam_Admin_Display.php:363 365 392 msgid "No warning data available" 366 393 msgstr "" 367 394 368 #: admin/CF7_AntiSpam_Admin_Display.php:3 32395 #: admin/CF7_AntiSpam_Admin_Display.php:370 369 396 msgid "B8 Wordlist" 370 397 msgstr "" 371 398 372 #: admin/CF7_AntiSpam_Admin_Display.php:3 37399 #: admin/CF7_AntiSpam_Admin_Display.php:375 373 400 msgid "Top Spam Words" 374 401 msgstr "" 375 402 376 #: admin/CF7_AntiSpam_Admin_Display.php:3 48403 #: admin/CF7_AntiSpam_Admin_Display.php:386 377 404 msgid "No spam words available" 378 405 msgstr "" 379 406 380 #: admin/CF7_AntiSpam_Admin_Display.php:3 54407 #: admin/CF7_AntiSpam_Admin_Display.php:392 381 408 msgid "Top Ham Words" 382 409 msgstr "" 383 410 384 #: admin/CF7_AntiSpam_Admin_Display.php: 365411 #: admin/CF7_AntiSpam_Admin_Display.php:403 385 412 msgid "No ham words available" 386 413 msgstr "" 387 414 388 #: admin/CF7_AntiSpam_Admin_Display.php: 374415 #: admin/CF7_AntiSpam_Admin_Display.php:412 389 416 msgid "Top Block Reasons" 390 417 msgstr "" 391 418 392 419 # %d is the number of unique reasons 393 #: admin/CF7_AntiSpam_Admin_Display.php: 394420 #: admin/CF7_AntiSpam_Admin_Display.php:432 394 421 msgid "Total unique reasons: %d" 395 422 msgstr "" 396 423 397 #: admin/CF7_AntiSpam_Admin_Display.php:4 06424 #: admin/CF7_AntiSpam_Admin_Display.php:444 398 425 msgid "No reason data available" 399 426 msgstr "" 400 427 401 #: admin/CF7_AntiSpam_Admin_Display.php:4 51428 #: admin/CF7_AntiSpam_Admin_Display.php:489 402 429 msgid "Do you know,that you can save settings simply using the shortcut [Ctrl + S]." 403 430 msgstr "" 404 431 405 #: admin/CF7_AntiSpam_Admin_Display.php:4 52432 #: admin/CF7_AntiSpam_Admin_Display.php:490 406 433 msgid "" 407 434 "In the CF7-Antispam settings page you can enter values in textarea using " … … 410 437 msgstr "" 411 438 412 #: admin/CF7_AntiSpam_Admin_Display.php:4 56439 #: admin/CF7_AntiSpam_Admin_Display.php:494 413 440 msgid "" 414 441 "It is always a good practice to NOT name \"contact\" the slug of the page " … … 416 443 msgstr "" 417 444 418 #: admin/CF7_AntiSpam_Admin_Display.php:4 57445 #: admin/CF7_AntiSpam_Admin_Display.php:495 419 446 msgid "contacts" 420 447 msgstr "" 421 448 422 #: admin/CF7_AntiSpam_Admin_Display.php:4 58449 #: admin/CF7_AntiSpam_Admin_Display.php:496 423 450 msgid "Give a try" 424 451 msgstr "" 425 452 426 #: admin/CF7_AntiSpam_Admin_Display.php: 463453 #: admin/CF7_AntiSpam_Admin_Display.php:501 427 454 msgid "As Flamingo also CF7-Antispam can handle" 428 455 msgstr "" 429 456 430 #: admin/CF7_AntiSpam_Admin_Display.php: 465457 #: admin/CF7_AntiSpam_Admin_Display.php:503 431 458 msgid "fields with multiple tags" 432 459 msgstr "" 433 460 434 #: admin/CF7_AntiSpam_Admin_Display.php: 466461 #: admin/CF7_AntiSpam_Admin_Display.php:504 435 462 msgid "" 436 463 "In this way, you can scan as a message multiple fields at once (subject " … … 438 465 msgstr "" 439 466 440 #: admin/CF7_AntiSpam_Admin_Display.php: 486467 #: admin/CF7_AntiSpam_Admin_Display.php:524 441 468 msgid "Tip:" 442 469 msgstr "" 443 470 444 #: admin/CF7_AntiSpam_Admin_Display.php:5 00471 #: admin/CF7_AntiSpam_Admin_Display.php:538 445 472 msgid "Plugin Settings" 446 473 msgstr "" 447 474 448 #: admin/CF7_AntiSpam_Admin_Display.php:5 25475 #: admin/CF7_AntiSpam_Admin_Display.php:555 449 476 msgid "Export blacklist" 450 477 msgstr "" 451 478 452 #: admin/CF7_AntiSpam_Admin_Display.php:5 28479 #: admin/CF7_AntiSpam_Admin_Display.php:566 453 480 msgid "Blacklisted IPs" 454 481 msgstr "" 455 482 456 #: admin/CF7_AntiSpam_Admin_Display.php:5 29483 #: admin/CF7_AntiSpam_Admin_Display.php:567 457 484 msgid "Here you can see all the IPs that have been blacklisted by the plugin." 458 485 msgstr "" 459 486 460 #: admin/CF7_AntiSpam_Admin_Display.php:5 41487 #: admin/CF7_AntiSpam_Admin_Display.php:579 461 488 msgid "Export/Import Options" 462 489 msgstr "" 463 490 464 #: admin/CF7_AntiSpam_Admin_Display.php:5 53491 #: admin/CF7_AntiSpam_Admin_Display.php:591 465 492 msgid "Advanced Tools" 466 493 msgstr "" 467 494 468 #: admin/CF7_AntiSpam_Admin_Display.php:5 54495 #: admin/CF7_AntiSpam_Admin_Display.php:592 469 496 msgid "" 470 497 "This section contains features that completely change what is stored in the " … … 472 499 msgstr "" 473 500 474 #: admin/CF7_AntiSpam_Admin_Display.php:568 501 #: admin/CF7_AntiSpam_Admin_Display.php:606 502 #: admin/CF7_AntiSpam_Admin_Display.php:608 503 msgid "Update Database" 504 msgstr "" 505 506 #: admin/CF7_AntiSpam_Admin_Display.php:607 507 msgid "" 508 "If something has gone wrong during updates, you can perform a forced " 509 "database and options update." 510 msgstr "" 511 512 #: admin/CF7_AntiSpam_Admin_Display.php:611 475 513 msgid "Danger Zone" 476 514 msgstr "" 477 515 478 #: admin/CF7_AntiSpam_Admin_Display.php: 569516 #: admin/CF7_AntiSpam_Admin_Display.php:612 479 517 msgid "" 480 518 "These actions are irreversible. Please make sure you know what you are " … … 482 520 msgstr "" 483 521 484 #: admin/CF7_AntiSpam_Admin_Display.php: 571522 #: admin/CF7_AntiSpam_Admin_Display.php:614 485 523 msgid "Blacklist Reset" 486 524 msgstr "" 487 525 488 #: admin/CF7_AntiSpam_Admin_Display.php: 572526 #: admin/CF7_AntiSpam_Admin_Display.php:615 489 527 msgid "Remove all blacklisted IPs from the database." 490 528 msgstr "" 491 529 492 #: admin/CF7_AntiSpam_Admin_Display.php: 573530 #: admin/CF7_AntiSpam_Admin_Display.php:616 493 531 msgid "Remove all blacklisted IP" 494 532 msgstr "" 495 533 496 #: admin/CF7_AntiSpam_Admin_Display.php: 575534 #: admin/CF7_AntiSpam_Admin_Display.php:618 497 535 msgid "Dictionary Reset" 498 536 msgstr "" 499 537 500 #: admin/CF7_AntiSpam_Admin_Display.php: 576538 #: admin/CF7_AntiSpam_Admin_Display.php:619 501 539 msgid "Reset the entire b8 dictionary used for spam detection." 502 540 msgstr "" 503 541 504 #: admin/CF7_AntiSpam_Admin_Display.php: 577542 #: admin/CF7_AntiSpam_Admin_Display.php:620 505 543 msgid "Reset b8 dictionary" 506 544 msgstr "" 507 545 508 #: admin/CF7_AntiSpam_Admin_Display.php: 579546 #: admin/CF7_AntiSpam_Admin_Display.php:622 509 547 msgid "Rebuild Dictionary" 510 548 msgstr "" 511 549 512 #: admin/CF7_AntiSpam_Admin_Display.php: 580550 #: admin/CF7_AntiSpam_Admin_Display.php:623 513 551 msgid "Reanalyze all Flamingo inbound emails to rebuild the dictionary." 514 552 msgstr "" 515 553 516 #: admin/CF7_AntiSpam_Admin_Display.php: 581554 #: admin/CF7_AntiSpam_Admin_Display.php:624 517 555 msgid "Rebuild b8 dictionary" 518 556 msgstr "" 519 557 520 #: admin/CF7_AntiSpam_Admin_Display.php: 583558 #: admin/CF7_AntiSpam_Admin_Display.php:626 521 559 msgid "Full Reset" 522 560 msgstr "" 523 561 524 #: admin/CF7_AntiSpam_Admin_Display.php: 584562 #: admin/CF7_AntiSpam_Admin_Display.php:627 525 563 msgid "Completely reset the plugin to its initial state." 526 564 msgstr "" 527 565 528 #: admin/CF7_AntiSpam_Admin_Display.php: 585566 #: admin/CF7_AntiSpam_Admin_Display.php:628 529 567 msgid "Are you sure? This will reset the plugin to its initial state." 530 568 msgstr "" 531 569 532 #: admin/CF7_AntiSpam_Admin_Display.php: 585570 #: admin/CF7_AntiSpam_Admin_Display.php:628 533 571 msgid "FULL RESET" 534 572 msgstr "" 535 573 536 #: admin/CF7_AntiSpam_Admin_Display.php:6 05574 #: admin/CF7_AntiSpam_Admin_Display.php:648 537 575 msgid "Copy or paste here the settings to import it or export it" 538 576 msgstr "" 539 577 540 #: admin/CF7_AntiSpam_Admin_Display.php:6 22578 #: admin/CF7_AntiSpam_Admin_Display.php:665 541 579 msgid "Debug Information" 542 580 msgstr "" 543 581 544 #: admin/CF7_AntiSpam_Admin_Display.php:6 23582 #: admin/CF7_AntiSpam_Admin_Display.php:666 545 583 msgid "" 546 584 "Debug information is only visible when WP_DEBUG or CF7ANTISPAM_DEBUG are " … … 548 586 msgstr "" 549 587 550 #: admin/CF7_AntiSpam_Admin_Display.php:6 53588 #: admin/CF7_AntiSpam_Admin_Display.php:696 551 589 msgid "[unban ip]" 552 590 msgstr "" 553 591 554 #: admin/CF7_AntiSpam_Admin_Display.php:6 55592 #: admin/CF7_AntiSpam_Admin_Display.php:699 555 593 msgid "[ban forever]" 556 594 msgstr "" 557 595 596 #: admin/CF7_AntiSpam_Admin_Display.php:701 597 msgid "First seen on" 598 msgstr "" 599 558 600 # %d is the number of blacklisted IPs 559 #: admin/CF7_AntiSpam_Admin_Display.php: 679601 #: admin/CF7_AntiSpam_Admin_Display.php:730 560 602 msgid "Showing %d blacklisted IPs" 561 603 msgstr "" 562 604 563 #: admin/CF7_AntiSpam_Admin_Display.php: 684605 #: admin/CF7_AntiSpam_Admin_Display.php:735 564 606 msgid "No blacklisted IPs found." 565 607 msgstr "" 566 608 567 #: admin/CF7_AntiSpam_Admin_Display.php:7 07568 #: admin/CF7_AntiSpam_Admin_Display.php:7 14609 #: admin/CF7_AntiSpam_Admin_Display.php:758 610 #: admin/CF7_AntiSpam_Admin_Display.php:765 569 611 msgid "is enabled" 570 612 msgstr "" 571 613 572 #: admin/CF7_AntiSpam_Admin_Display.php:7 19614 #: admin/CF7_AntiSpam_Admin_Display.php:770 573 615 msgid "Your ip address" 574 616 msgstr "" 575 617 576 #: admin/CF7_AntiSpam_Admin_Display.php:7 25618 #: admin/CF7_AntiSpam_Admin_Display.php:776 577 619 msgid "is disabled, use CF7ANTISPAM_DEBUG_EXTENDED to enable it if needed" 578 620 msgstr "" 579 621 580 #: admin/CF7_AntiSpam_Admin_Display.php:7 41581 #: admin/CF7_AntiSpam_Admin_Display.php: 750622 #: admin/CF7_AntiSpam_Admin_Display.php:792 623 #: admin/CF7_AntiSpam_Admin_Display.php:801 582 624 msgid "is disabled" 583 625 msgstr "" 584 626 585 #: admin/CF7_AntiSpam_Admin_Display.php: 768627 #: admin/CF7_AntiSpam_Admin_Display.php:819 586 628 msgid "Waiting for Rest API Status..." 587 629 msgstr "" 588 630 589 #: admin/CF7_AntiSpam_Admin_Display.php: 778631 #: admin/CF7_AntiSpam_Admin_Display.php:861 590 632 msgid "Options debug" 591 633 msgstr "" 592 634 593 #: admin/CF7_AntiSpam_Admin_Display.php: 781635 #: admin/CF7_AntiSpam_Admin_Display.php:864 594 636 msgid "The plugin options are:" 595 637 msgstr "" 596 638 597 #: admin/CF7_AntiSpam_Admin_Display.php:8 15639 #: admin/CF7_AntiSpam_Admin_Display.php:898 598 640 msgid "spam" 599 641 msgstr "" 600 642 601 #: admin/CF7_AntiSpam_Admin_Display.php:8 15643 #: admin/CF7_AntiSpam_Admin_Display.php:898 602 644 msgid "ham" 603 645 msgstr "" 604 646 605 #: admin/CF7_AntiSpam_Admin_Display.php: 823647 #: admin/CF7_AntiSpam_Admin_Display.php:906 606 648 msgid "DNSBL performance test:" 607 649 msgstr "" 608 650 609 #: admin/CF7_AntiSpam_Admin_Display.php: 824651 #: admin/CF7_AntiSpam_Admin_Display.php:907 610 652 msgid "" 611 653 "Results below 0.01 are fine, OK/Spam indicates the status of your ip on " … … 613 655 msgstr "" 614 656 615 #: admin/CF7_AntiSpam_Admin_Display.php: 825616 #: admin/CF7_AntiSpam_Admin_Display.php: 881617 #: admin/CF7_AntiSpam_Admin_Display.php: 892657 #: admin/CF7_AntiSpam_Admin_Display.php:908 658 #: admin/CF7_AntiSpam_Admin_Display.php:964 659 #: admin/CF7_AntiSpam_Admin_Display.php:975 618 660 msgid "Your IP address" 619 661 msgstr "" 620 662 621 #: admin/CF7_AntiSpam_Admin_Display.php: 848663 #: admin/CF7_AntiSpam_Admin_Display.php:931 622 664 msgid "not set" 623 665 msgstr "" 624 666 625 #: admin/CF7_AntiSpam_Admin_Display.php: 860626 #: admin/CF7_AntiSpam_Admin_Display.php:9 03667 #: admin/CF7_AntiSpam_Admin_Display.php:943 668 #: admin/CF7_AntiSpam_Admin_Display.php:986 627 669 msgid "Geo-IP test" 628 670 msgstr "" 629 671 630 #: admin/CF7_AntiSpam_Admin_Display.php: 868631 #: admin/CF7_AntiSpam_Admin_Display.php: 889672 #: admin/CF7_AntiSpam_Admin_Display.php:951 673 #: admin/CF7_AntiSpam_Admin_Display.php:972 632 674 msgid "Geo-IP" 633 675 msgstr "" 634 676 635 #: admin/CF7_AntiSpam_Admin_Display.php: 869677 #: admin/CF7_AntiSpam_Admin_Display.php:952 636 678 msgid "Enabled" 637 679 msgstr "" 638 680 639 #: admin/CF7_AntiSpam_Admin_Display.php: 869681 #: admin/CF7_AntiSpam_Admin_Display.php:952 640 682 msgid "Geo-ip database next scheduled update: " 641 683 msgstr "" 642 684 643 #: admin/CF7_AntiSpam_Admin_Display.php: 890685 #: admin/CF7_AntiSpam_Admin_Display.php:973 644 686 msgid "is disabled." 645 687 msgstr "" 646 688 647 #: admin/CF7_AntiSpam_Admin_Display.php: 891689 #: admin/CF7_AntiSpam_Admin_Display.php:974 648 690 msgid "" 649 691 "To enable it, please go to the settings page and enable the \"Detect " … … 651 693 msgstr "" 652 694 653 #: admin/CF7_AntiSpam_Admin_Display.php:9 04695 #: admin/CF7_AntiSpam_Admin_Display.php:987 654 696 msgid "Geo-IP Test Error" 655 697 msgstr "" 656 698 657 #: admin/CF7_AntiSpam_Admin_Customizations.php: 46699 #: admin/CF7_AntiSpam_Admin_Customizations.php:55 658 700 msgid "Administrators only" 659 701 msgstr "" 660 702 661 #: admin/CF7_AntiSpam_Admin_Customizations.php: 70703 #: admin/CF7_AntiSpam_Admin_Customizations.php:81 662 704 msgid "Ban automatically spammers" 663 705 msgstr "" 664 706 665 #: admin/CF7_AntiSpam_Admin_Customizations.php: 78707 #: admin/CF7_AntiSpam_Admin_Customizations.php:89 666 708 msgid "Automatic spammer IP Blacklist" 667 709 msgstr "" 668 710 669 #: admin/CF7_AntiSpam_Admin_Customizations.php: 87711 #: admin/CF7_AntiSpam_Admin_Customizations.php:98 670 712 msgid "Mail blocked before Ban" 671 713 msgstr "" 672 714 673 #: admin/CF7_AntiSpam_Admin_Customizations.php: 96715 #: admin/CF7_AntiSpam_Admin_Customizations.php:107 674 716 msgid "Automatic Unban" 675 717 msgstr "" 676 718 677 #: admin/CF7_AntiSpam_Admin_Customizations.php:1 05719 #: admin/CF7_AntiSpam_Admin_Customizations.php:116 678 720 msgid "Bot Fingerprinting" 679 721 msgstr "" 680 722 681 #: admin/CF7_AntiSpam_Admin_Customizations.php:1 13723 #: admin/CF7_AntiSpam_Admin_Customizations.php:124 682 724 msgid "Enable anti-bot checks" 683 725 msgstr "" 684 726 685 #: admin/CF7_AntiSpam_Admin_Customizations.php:1 22727 #: admin/CF7_AntiSpam_Admin_Customizations.php:133 686 728 msgid "Enable anti-bot extra checks" 687 729 msgstr "" 688 730 689 #: admin/CF7_AntiSpam_Admin_Customizations.php:1 31731 #: admin/CF7_AntiSpam_Admin_Customizations.php:142 690 732 msgid "Append hidden fields on submit" 691 733 msgstr "" 692 734 693 #: admin/CF7_AntiSpam_Admin_Customizations.php:1 40735 #: admin/CF7_AntiSpam_Admin_Customizations.php:151 694 736 msgid "GeoIP" 695 737 msgstr "" 696 738 697 #: admin/CF7_AntiSpam_Admin_Customizations.php:1 48739 #: admin/CF7_AntiSpam_Admin_Customizations.php:159 698 740 msgid "Enable automatic download" 699 741 msgstr "" 700 742 701 #: admin/CF7_AntiSpam_Admin_Customizations.php:157 743 #: admin/CF7_AntiSpam_Admin_Customizations.php:171 744 msgid "MaxMind Update Key" 745 msgstr "" 746 747 #: admin/CF7_AntiSpam_Admin_Customizations.php:181 748 msgid "Force database download" 749 msgstr "" 750 751 #: admin/CF7_AntiSpam_Admin_Customizations.php:192 752 msgid "Database manual upload" 753 msgstr "" 754 755 #: admin/CF7_AntiSpam_Admin_Customizations.php:202 702 756 msgid "Database available" 703 757 msgstr "" 704 758 705 #: admin/CF7_AntiSpam_Admin_Customizations.php:169 706 msgid "MaxMind Update Key" 707 msgstr "" 708 709 #: admin/CF7_AntiSpam_Admin_Customizations.php:178 759 #: admin/CF7_AntiSpam_Admin_Customizations.php:211 710 760 msgid "Language Checks" 711 761 msgstr "" 712 762 713 #: admin/CF7_AntiSpam_Admin_Customizations.php: 186763 #: admin/CF7_AntiSpam_Admin_Customizations.php:219 714 764 msgid "Check Browser Language" 715 765 msgstr "" 716 766 717 #: admin/CF7_AntiSpam_Admin_Customizations.php: 195767 #: admin/CF7_AntiSpam_Admin_Customizations.php:228 718 768 msgid "Detect location using GeoIP" 719 769 msgstr "" 720 770 721 #: admin/CF7_AntiSpam_Admin_Customizations.php:2 04771 #: admin/CF7_AntiSpam_Admin_Customizations.php:237 722 772 msgid "Allowed browser Languages" 723 773 msgstr "" 724 774 725 #: admin/CF7_AntiSpam_Admin_Customizations.php:2 13775 #: admin/CF7_AntiSpam_Admin_Customizations.php:246 726 776 msgid "Disallowed browser Languages" 727 777 msgstr "" 728 778 729 #: admin/CF7_AntiSpam_Admin_Customizations.php:2 22779 #: admin/CF7_AntiSpam_Admin_Customizations.php:255 730 780 msgid "Time checks" 731 781 msgstr "" 732 782 733 #: admin/CF7_AntiSpam_Admin_Customizations.php:2 30783 #: admin/CF7_AntiSpam_Admin_Customizations.php:263 734 784 msgid "Check the elapsed time" 735 785 msgstr "" 736 786 737 #: admin/CF7_AntiSpam_Admin_Customizations.php:2 39787 #: admin/CF7_AntiSpam_Admin_Customizations.php:272 738 788 msgid "Minimum elapsed time" 739 789 msgstr "" 740 790 741 #: admin/CF7_AntiSpam_Admin_Customizations.php:2 48791 #: admin/CF7_AntiSpam_Admin_Customizations.php:281 742 792 msgid "Maximum elapsed time" 743 793 msgstr "" 744 794 745 #: admin/CF7_AntiSpam_Admin_Customizations.php:2 57795 #: admin/CF7_AntiSpam_Admin_Customizations.php:290 746 796 msgid "Bad IP Address" 747 797 msgstr "" 748 798 749 #: admin/CF7_AntiSpam_Admin_Customizations.php:2 65799 #: admin/CF7_AntiSpam_Admin_Customizations.php:298 750 800 msgid "Check HTTP referrer" 751 801 msgstr "" 752 802 753 #: admin/CF7_AntiSpam_Admin_Customizations.php: 274803 #: admin/CF7_AntiSpam_Admin_Customizations.php:307 754 804 msgid "Check Bad IP Address" 755 805 msgstr "" 756 806 757 #: admin/CF7_AntiSpam_Admin_Customizations.php: 283807 #: admin/CF7_AntiSpam_Admin_Customizations.php:316 758 808 msgid "Bad IP Address List" 759 809 msgstr "" 760 810 761 #: admin/CF7_AntiSpam_Admin_Customizations.php: 292811 #: admin/CF7_AntiSpam_Admin_Customizations.php:325 762 812 msgid "IP Whitelist" 763 813 msgstr "" 764 814 765 #: admin/CF7_AntiSpam_Admin_Customizations.php:3 01815 #: admin/CF7_AntiSpam_Admin_Customizations.php:334 766 816 msgid "Bad words" 767 817 msgstr "" 768 818 769 #: admin/CF7_AntiSpam_Admin_Customizations.php:3 09819 #: admin/CF7_AntiSpam_Admin_Customizations.php:342 770 820 msgid "Check the message for prohibited words" 771 821 msgstr "" 772 822 773 #: admin/CF7_AntiSpam_Admin_Customizations.php:3 18823 #: admin/CF7_AntiSpam_Admin_Customizations.php:351 774 824 msgid "Bad words List" 775 825 msgstr "" 776 826 777 #: admin/CF7_AntiSpam_Admin_Customizations.php:3 27827 #: admin/CF7_AntiSpam_Admin_Customizations.php:360 778 828 msgid "Bad email strings" 779 829 msgstr "" 780 830 781 #: admin/CF7_AntiSpam_Admin_Customizations.php:3 35831 #: admin/CF7_AntiSpam_Admin_Customizations.php:368 782 832 msgid "Check the email for prohibited words" 783 833 msgstr "" 784 834 785 #: admin/CF7_AntiSpam_Admin_Customizations.php:3 44835 #: admin/CF7_AntiSpam_Admin_Customizations.php:377 786 836 msgid "Email prohibited words" 787 837 msgstr "" 788 838 789 #: admin/CF7_AntiSpam_Admin_Customizations.php:3 53839 #: admin/CF7_AntiSpam_Admin_Customizations.php:386 790 840 msgid "User Agent blacklist" 791 841 msgstr "" 792 842 793 #: admin/CF7_AntiSpam_Admin_Customizations.php:3 61843 #: admin/CF7_AntiSpam_Admin_Customizations.php:394 794 844 msgid "Enable User Agent blacklist" 795 845 msgstr "" 796 846 797 #: admin/CF7_AntiSpam_Admin_Customizations.php: 370847 #: admin/CF7_AntiSpam_Admin_Customizations.php:403 798 848 msgid "Disallowed user agents" 799 849 msgstr "" 800 850 801 #: admin/CF7_AntiSpam_Admin_Customizations.php: 379851 #: admin/CF7_AntiSpam_Admin_Customizations.php:412 802 852 msgid "DNS Blacklists" 803 853 msgstr "" 804 854 805 #: admin/CF7_AntiSpam_Admin_Customizations.php: 387855 #: admin/CF7_AntiSpam_Admin_Customizations.php:420 806 856 msgid "Check IP on DNS blocklist" 807 857 msgstr "" 808 858 809 #: admin/CF7_AntiSpam_Admin_Customizations.php: 396859 #: admin/CF7_AntiSpam_Admin_Customizations.php:429 810 860 msgid "DNS blocklist servers" 811 861 msgstr "" 812 862 813 #: admin/CF7_AntiSpam_Admin_Customizations.php:4 05863 #: admin/CF7_AntiSpam_Admin_Customizations.php:438 814 864 msgid "Honeypot" 815 865 msgstr "" 816 866 817 #: admin/CF7_AntiSpam_Admin_Customizations.php:4 13867 #: admin/CF7_AntiSpam_Admin_Customizations.php:446 818 868 msgid "Add some fake input inside the form" 819 869 msgstr "" 820 870 821 #: admin/CF7_AntiSpam_Admin_Customizations.php:4 22871 #: admin/CF7_AntiSpam_Admin_Customizations.php:455 822 872 msgid "Name for the honeypots inputs[*]" 823 873 msgstr "" 824 874 825 #: admin/CF7_AntiSpam_Admin_Customizations.php:4 31875 #: admin/CF7_AntiSpam_Admin_Customizations.php:464 826 876 msgid "Honeyform <span class=\"label alert monospace\">[experimental]</span>" 827 877 msgstr "" 828 878 829 #: admin/CF7_AntiSpam_Admin_Customizations.php:4 39879 #: admin/CF7_AntiSpam_Admin_Customizations.php:472 830 880 msgid "Add an hidden form inside the page content" 831 881 msgstr "" 832 882 833 #: admin/CF7_AntiSpam_Admin_Customizations.php:4 48883 #: admin/CF7_AntiSpam_Admin_Customizations.php:481 834 884 msgid "Select where the honeyform will be placed" 835 885 msgstr "" 836 886 837 #: admin/CF7_AntiSpam_Admin_Customizations.php:4 57887 #: admin/CF7_AntiSpam_Admin_Customizations.php:490 838 888 msgid "Exclude pages" 839 889 msgstr "" 840 890 841 #: admin/CF7_AntiSpam_Admin_Customizations.php:4 66891 #: admin/CF7_AntiSpam_Admin_Customizations.php:499 842 892 msgid "Mailbox Protection" 843 893 msgstr "" 844 894 845 #: admin/CF7_AntiSpam_Admin_Customizations.php: 474895 #: admin/CF7_AntiSpam_Admin_Customizations.php:507 846 896 msgid "Avoid multiple send" 847 897 msgstr "" 848 898 849 #: admin/CF7_AntiSpam_Admin_Customizations.php: 483899 #: admin/CF7_AntiSpam_Admin_Customizations.php:516 850 900 msgid "Identity Protection" 851 901 msgstr "" 852 902 853 #: admin/CF7_AntiSpam_Admin_Customizations.php: 491903 #: admin/CF7_AntiSpam_Admin_Customizations.php:524 854 904 msgid "Enforce user protection" 855 905 msgstr "" 856 906 857 #: admin/CF7_AntiSpam_Admin_Customizations.php:5 00907 #: admin/CF7_AntiSpam_Admin_Customizations.php:533 858 908 msgid "Enforce WordPress protection" 859 909 msgstr "" 860 910 861 #: admin/CF7_AntiSpam_Admin_Customizations.php:5 09911 #: admin/CF7_AntiSpam_Admin_Customizations.php:542 862 912 msgid "B8 statistical \"Bayesian\" spam filter" 863 913 msgstr "" 864 914 865 #: admin/CF7_AntiSpam_Admin_Customizations.php:5 17915 #: admin/CF7_AntiSpam_Admin_Customizations.php:550 866 916 msgid "Enable B8" 867 917 msgstr "" 868 918 869 #: admin/CF7_AntiSpam_Admin_Customizations.php:5 26919 #: admin/CF7_AntiSpam_Admin_Customizations.php:559 870 920 msgid "B8 spam threshold" 871 921 msgstr "" 872 922 873 #: admin/CF7_AntiSpam_Admin_Customizations.php:5 35923 #: admin/CF7_AntiSpam_Admin_Customizations.php:568 874 924 msgid "Spam filter customizations" 875 925 msgstr "" 876 926 877 #: admin/CF7_AntiSpam_Admin_Customizations.php:543 927 #: admin/CF7_AntiSpam_Admin_Customizations.php:576 928 msgid "Your unique css class" 929 msgstr "" 930 931 #: admin/CF7_AntiSpam_Admin_Customizations.php:585 932 msgid "Your unique fields prefix" 933 msgstr "" 934 935 #: admin/CF7_AntiSpam_Admin_Customizations.php:594 936 msgid "The encryption method" 937 msgstr "" 938 939 #: admin/CF7_AntiSpam_Admin_Customizations.php:603 940 msgid "Optimizations" 941 msgstr "" 942 943 #: admin/CF7_AntiSpam_Admin_Customizations.php:611 944 msgid "Optimize scripts loading" 945 msgstr "" 946 947 #: admin/CF7_AntiSpam_Admin_Customizations.php:620 878 948 msgid "Disable cf7 form reload if the page is cached" 879 949 msgstr "" 880 950 881 #: admin/CF7_AntiSpam_Admin_Customizations.php:552 882 msgid "Your unique css class" 883 msgstr "" 884 885 #: admin/CF7_AntiSpam_Admin_Customizations.php:561 886 msgid "Your unique fields prefix" 887 msgstr "" 888 889 #: admin/CF7_AntiSpam_Admin_Customizations.php:570 890 msgid "The encryption method" 891 msgstr "" 892 893 #: admin/CF7_AntiSpam_Admin_Customizations.php:579 951 #: admin/CF7_AntiSpam_Admin_Customizations.php:629 894 952 msgid "Spam Score Rating" 895 953 msgstr "" 896 954 897 #: admin/CF7_AntiSpam_Admin_Customizations.php: 587955 #: admin/CF7_AntiSpam_Admin_Customizations.php:637 898 956 msgid "Anti-spam control level" 899 957 msgstr "" 900 958 901 #: admin/CF7_AntiSpam_Admin_Customizations.php: 596959 #: admin/CF7_AntiSpam_Admin_Customizations.php:646 902 960 msgid "Enable advanced settings" 903 961 msgstr "" 904 962 905 #: admin/CF7_AntiSpam_Admin_Customizations.php:6 05963 #: admin/CF7_AntiSpam_Admin_Customizations.php:655 906 964 msgid "Scoring Tweaks (1 = Ban)" 907 965 msgstr "" 908 966 909 #: admin/CF7_AntiSpam_Admin_Customizations.php:6 13967 #: admin/CF7_AntiSpam_Admin_Customizations.php:663 910 968 msgid "Bot fingerprinting score <small>(for each failed test)</small>" 911 969 msgstr "" 912 970 913 #: admin/CF7_AntiSpam_Admin_Customizations.php:6 22971 #: admin/CF7_AntiSpam_Admin_Customizations.php:672 914 972 msgid "Time checks score" 915 973 msgstr "" 916 974 917 #: admin/CF7_AntiSpam_Admin_Customizations.php:6 31975 #: admin/CF7_AntiSpam_Admin_Customizations.php:681 918 976 msgid "String found" 919 977 msgstr "" 920 978 921 #: admin/CF7_AntiSpam_Admin_Customizations.php:6 40979 #: admin/CF7_AntiSpam_Admin_Customizations.php:690 922 980 msgid "DNSBL score <small>(for each server)</small>" 923 981 msgstr "" 924 982 925 #: admin/CF7_AntiSpam_Admin_Customizations.php:6 49983 #: admin/CF7_AntiSpam_Admin_Customizations.php:699 926 984 msgid "Honeypot fill score <small>(for each fail)</small>" 927 985 msgstr "" 928 986 929 #: admin/CF7_AntiSpam_Admin_Customizations.php: 658987 #: admin/CF7_AntiSpam_Admin_Customizations.php:708 930 988 msgid "Bot detected" 931 989 msgstr "" 932 990 933 #: admin/CF7_AntiSpam_Admin_Customizations.php: 667991 #: admin/CF7_AntiSpam_Admin_Customizations.php:717 934 992 msgid "Bot warn" 935 993 msgstr "" 936 994 937 #: admin/CF7_AntiSpam_Admin_Customizations.php: 678995 #: admin/CF7_AntiSpam_Admin_Customizations.php:728 938 996 msgid "How many failed attempts before being banned" 939 997 msgstr "" 940 998 941 #: admin/CF7_AntiSpam_Admin_Customizations.php: 682999 #: admin/CF7_AntiSpam_Admin_Customizations.php:733 942 1000 msgid "Next scheduled unban event:" 943 1001 msgstr "" 944 1002 945 #: admin/CF7_AntiSpam_Admin_Customizations.php: 6931003 #: admin/CF7_AntiSpam_Admin_Customizations.php:744 946 1004 msgid "" 947 1005 "Fingerprinting is a method used for exploiting data from browser in order " … … 951 1009 msgstr "" 952 1010 953 #: admin/CF7_AntiSpam_Admin_Customizations.php: 6941011 #: admin/CF7_AntiSpam_Admin_Customizations.php:745 954 1012 msgid "" 955 1013 "The last option, append on submit, causes fingerprinting to take place " … … 958 1016 msgstr "" 959 1017 960 #: admin/CF7_AntiSpam_Admin_Customizations.php:7 021018 #: admin/CF7_AntiSpam_Admin_Customizations.php:753 961 1019 msgid "" 962 1020 "Checks that the form has been submitted within a reasonable timeframe, " … … 964 1022 msgstr "" 965 1023 966 #: admin/CF7_AntiSpam_Admin_Customizations.php:7 031024 #: admin/CF7_AntiSpam_Admin_Customizations.php:754 967 1025 msgid "" 968 1026 "Just set a few seconds as the minimum time (bots usually take 5 seconds at " … … 970 1028 msgstr "" 971 1029 972 #: admin/CF7_AntiSpam_Admin_Customizations.php:7 041030 #: admin/CF7_AntiSpam_Admin_Customizations.php:755 973 1031 msgid "" 974 1032 "* A small note.... If you use a caching system for the contact page make " … … 977 1035 msgstr "" 978 1036 979 #: admin/CF7_AntiSpam_Admin_Customizations.php:7 051037 #: admin/CF7_AntiSpam_Admin_Customizations.php:756 980 1038 msgid "Values in seconds, 0 to disable" 981 1039 msgstr "" 982 1040 983 #: admin/CF7_AntiSpam_Admin_Customizations.php:7 131041 #: admin/CF7_AntiSpam_Admin_Customizations.php:764 984 1042 msgid "Detect user location using MaxMind GeoIP2 database." 985 1043 msgstr "" 986 1044 987 #: admin/CF7_AntiSpam_Admin_Customizations.php:7 141045 #: admin/CF7_AntiSpam_Admin_Customizations.php:765 988 1046 msgid "In order to enable this functionality you need to agree at " 989 1047 msgstr "" 990 1048 991 #: admin/CF7_AntiSpam_Admin_Customizations.php:7 151049 #: admin/CF7_AntiSpam_Admin_Customizations.php:766 992 1050 msgid "GeoLite2 End User License Agreement" 993 1051 msgstr "" 994 1052 995 #: admin/CF7_AntiSpam_Admin_Customizations.php:7 161053 #: admin/CF7_AntiSpam_Admin_Customizations.php:767 996 1054 msgid "and sign up " 997 1055 msgstr "" 998 1056 999 #: admin/CF7_AntiSpam_Admin_Customizations.php:7 171057 #: admin/CF7_AntiSpam_Admin_Customizations.php:768 1000 1058 msgid "GeoLite2 Downloadable Databases" 1001 1059 msgstr "" 1002 1060 1003 #: admin/CF7_AntiSpam_Admin_Customizations.php:7 181061 #: admin/CF7_AntiSpam_Admin_Customizations.php:769 1004 1062 msgid "" 1005 1063 "After registration you will get a key, paste it into the input below and " … … 1008 1066 msgstr "" 1009 1067 1010 #: admin/CF7_AntiSpam_Admin_Customizations.php:7 241068 #: admin/CF7_AntiSpam_Admin_Customizations.php:775 1011 1069 msgid "Recommended - define a key your config.php the key in this way: " 1012 1070 msgstr "" 1013 1071 1014 #: admin/CF7_AntiSpam_Admin_Customizations.php:7 371072 #: admin/CF7_AntiSpam_Admin_Customizations.php:788 1015 1073 msgid "" 1016 1074 "Check the user browser language / user keyboard. Add a country code / " … … 1021 1079 msgstr "" 1022 1080 1023 #: admin/CF7_AntiSpam_Admin_Customizations.php:7 381081 #: admin/CF7_AntiSpam_Admin_Customizations.php:789 1024 1082 msgid "" 1025 1083 "The browser language detection and country detection are separated, you can " … … 1027 1085 msgstr "" 1028 1086 1029 #: admin/CF7_AntiSpam_Admin_Customizations.php:7 391087 #: admin/CF7_AntiSpam_Admin_Customizations.php:790 1030 1088 msgid "" 1031 1089 "The language detection must be lower case, while the country detection " … … 1033 1091 msgstr "" 1034 1092 1035 #: admin/CF7_AntiSpam_Admin_Customizations.php:7 401093 #: admin/CF7_AntiSpam_Admin_Customizations.php:791 1036 1094 msgid "If you are unsure please consult these ISO standards:" 1037 1095 msgstr "" 1038 1096 1039 #: admin/CF7_AntiSpam_Admin_Customizations.php:7 411097 #: admin/CF7_AntiSpam_Admin_Customizations.php:792 1040 1098 msgid "- Language codes (use ctrl+f for search) " 1041 1099 msgstr "" 1042 1100 1043 #: admin/CF7_AntiSpam_Admin_Customizations.php:7 421101 #: admin/CF7_AntiSpam_Admin_Customizations.php:793 1044 1102 msgid "- Country codes (refer to \"Alpha-2 code\"), " 1045 1103 msgstr "" 1046 1104 1047 #: admin/CF7_AntiSpam_Admin_Customizations.php:7 481105 #: admin/CF7_AntiSpam_Admin_Customizations.php:799 1048 1106 msgid "" 1049 1107 "After an ip check via the http headers, it is checked that the ip is not " … … 1051 1109 msgstr "" 1052 1110 1053 #: admin/CF7_AntiSpam_Admin_Customizations.php: 7531111 #: admin/CF7_AntiSpam_Admin_Customizations.php:804 1054 1112 msgid "" 1055 1113 "Check if the mail message contains \"bad\" words, all e-mails containing " … … 1057 1115 msgstr "" 1058 1116 1059 #: admin/CF7_AntiSpam_Admin_Customizations.php: 7581117 #: admin/CF7_AntiSpam_Admin_Customizations.php:809 1060 1118 msgid "" 1061 1119 "Check if the mail content contains a word and in this case flag this mail, " … … 1063 1121 msgstr "" 1064 1122 1065 #: admin/CF7_AntiSpam_Admin_Customizations.php: 7631123 #: admin/CF7_AntiSpam_Admin_Customizations.php:814 1066 1124 msgid "" 1067 1125 "Enter a list of forbidden user agents, one per line. When the string match " … … 1069 1127 msgstr "" 1070 1128 1071 #: admin/CF7_AntiSpam_Admin_Customizations.php: 7681129 #: admin/CF7_AntiSpam_Admin_Customizations.php:819 1072 1130 msgid "" 1073 1131 "Check sender ip on DNS Blacklists, DNSBL are real-time lists of " … … 1080 1138 1081 1139 # %s%s%s - a spam score of xyz will be added 1082 #: admin/CF7_AntiSpam_Admin_Customizations.php: 7701140 #: admin/CF7_AntiSpam_Admin_Customizations.php:821 1083 1141 msgid "" 1084 1142 "?? Use FEW servers, those you tested reliable, and consider that for each " … … 1087 1145 1088 1146 # %s%s%s - a spam score of xyz will be added 1089 #: admin/CF7_AntiSpam_Admin_Customizations.php: 7701147 #: admin/CF7_AntiSpam_Admin_Customizations.php:821 1090 1148 msgid " will be added to the spam rating, 1 equal spam." 1091 1149 msgstr "" 1092 1150 1093 #: admin/CF7_AntiSpam_Admin_Customizations.php: 7731151 #: admin/CF7_AntiSpam_Admin_Customizations.php:824 1094 1152 msgid "Here a you can find a list of servers: " 1095 1153 msgstr "" 1096 1154 1097 #: admin/CF7_AntiSpam_Admin_Customizations.php: 7831155 #: admin/CF7_AntiSpam_Admin_Customizations.php:834 1098 1156 msgid "" 1099 1157 "the honeypot is a \"trap\" field that is hidden with css or js from the " … … 1102 1160 msgstr "" 1103 1161 1104 #: admin/CF7_AntiSpam_Admin_Customizations.php: 7841162 #: admin/CF7_AntiSpam_Admin_Customizations.php:835 1105 1163 msgid "" 1106 1164 "Please check the list below because the name MUST differ from the cf7 tag " … … 1108 1166 msgstr "" 1109 1167 1110 #: admin/CF7_AntiSpam_Admin_Customizations.php: 7901168 #: admin/CF7_AntiSpam_Admin_Customizations.php:841 1111 1169 msgid "" 1112 1170 "Instead of relying on trap fields, we utilize honeyforms, that are forms " … … 1115 1173 msgstr "" 1116 1174 1117 #: admin/CF7_AntiSpam_Admin_Customizations.php: 7961175 #: admin/CF7_AntiSpam_Admin_Customizations.php:847 1118 1176 msgid "" 1119 1177 "When activated, this feature prevents consecutive email deliveries to the " … … 1121 1179 msgstr "" 1122 1180 1123 #: admin/CF7_AntiSpam_Admin_Customizations.php: 7961181 #: admin/CF7_AntiSpam_Admin_Customizations.php:847 1124 1182 msgid "" 1125 1183 " seconds has been set as the resend timeout, check the documentation if you " … … 1127 1185 msgstr "" 1128 1186 1129 #: admin/CF7_AntiSpam_Admin_Customizations.php:8 011187 #: admin/CF7_AntiSpam_Admin_Customizations.php:852 1130 1188 msgid "" 1131 1189 "After monitoring and analysing some bots, I noticed that it is necessary to " … … 1135 1193 msgstr "" 1136 1194 1137 #: admin/CF7_AntiSpam_Admin_Customizations.php:8 061195 #: admin/CF7_AntiSpam_Admin_Customizations.php:857 1138 1196 msgid "" 1139 1197 "Tells you whether a text is spam or not, using statistical text analysis of " … … 1141 1199 msgstr "" 1142 1200 1143 #: admin/CF7_AntiSpam_Admin_Customizations.php:813 1144 msgid "RECOMMENDED: create your own and unique css class and customized fields name" 1145 msgstr "" 1146 1147 #: admin/CF7_AntiSpam_Admin_Customizations.php:814 1148 msgid "" 1149 "You can also choose in encryption method. But, After changing cypher do a " 1150 "couple of tests because a small amount of them aren't compatible with the " 1151 "format of the form data." 1152 msgstr "" 1153 1154 #: admin/CF7_AntiSpam_Admin_Customizations.php:820 1201 #: admin/CF7_AntiSpam_Admin_Customizations.php:858 1202 msgid "" 1203 "The threshold value is the minimum score required for a text to be " 1204 "considered spam. 1 is spam. 0 is not spam. If the threshold value is too " 1205 "low, you may receive false positives, while if it is too high, you may miss " 1206 "some spam." 1207 msgstr "" 1208 1209 #: admin/CF7_AntiSpam_Admin_Customizations.php:865 1210 msgid "RECOMMENDED: Site related configuration" 1211 msgstr "" 1212 1213 #: admin/CF7_AntiSpam_Admin_Customizations.php:866 1214 msgid "" 1215 "create your own and unique css class and customized fields name. " 1216 "Optionally, you can choose in encryption method. But, After changing cypher " 1217 "do a couple of tests because a small amount of them aren't compatible with " 1218 "the format of the form data." 1219 msgstr "" 1220 1221 #: admin/CF7_AntiSpam_Admin_Customizations.php:872 1155 1222 msgid "" 1156 1223 "The calculation system of antispam for contact form 7 works like this: each " … … 1161 1228 msgstr "" 1162 1229 1163 #: admin/CF7_AntiSpam_Admin_Customizations.php:8 251230 #: admin/CF7_AntiSpam_Admin_Customizations.php:877 1164 1231 msgid "In this section you will find some advanced settings to manage the database" 1165 1232 msgstr "" 1166 1233 1167 #: admin/CF7_AntiSpam_Admin_Customizations.php:1350 1234 # %s is the error message 1235 #: admin/CF7_AntiSpam_Admin_Customizations.php:1142 1236 msgid "Error uploading file: %s" 1237 msgstr "" 1238 1239 #: admin/CF7_AntiSpam_Admin_Customizations.php:1153 1240 msgid "GeoIP database uploaded successfully." 1241 msgstr "" 1242 1243 #: admin/CF7_AntiSpam_Admin_Customizations.php:1157 1244 msgid "Error processing the uploaded file." 1245 msgstr "" 1246 1247 #: admin/CF7_AntiSpam_Admin_Customizations.php:1437 1248 msgid "Force Download" 1249 msgstr "" 1250 1251 #: admin/CF7_AntiSpam_Admin_Customizations.php:1446 1252 msgid "Choose DB File..." 1253 msgstr "" 1254 1255 #: admin/CF7_AntiSpam_Admin_Customizations.php:1447 1256 msgid "No file selected" 1257 msgstr "" 1258 1259 #: admin/CF7_AntiSpam_Admin_Customizations.php:1449 1260 msgid "Accepted formats: .mmdb or .tar.gz" 1261 msgstr "" 1262 1263 #: admin/CF7_AntiSpam_Admin_Customizations.php:1468 1168 1264 msgid "KEY provided" 1169 1265 msgstr "" 1170 1266 1171 #: admin/CF7_AntiSpam_Admin_Customizations.php:1 5901267 #: admin/CF7_AntiSpam_Admin_Customizations.php:1708 1172 1268 msgid "Add" 1173 1269 msgstr "" 1174 1270 1175 #: admin/CF7_AntiSpam_Admin_Customizations.php:1 5921271 #: admin/CF7_AntiSpam_Admin_Customizations.php:1710 1176 1272 msgid "Remove" 1177 1273 msgstr "" 1178 1274 1179 #: admin/CF7_AntiSpam_Admin_Core.php:100 1275 #: admin/CF7_AntiSpam_Admin_Customizations.php:1794 1276 msgid "" 1277 "You can optimize the loading performance of the antispam scripts. Since " 1278 "optimization is a risky business, we do not recommend enabling this option " 1279 "without trying it first." 1280 msgstr "" 1281 1282 #: admin/CF7_AntiSpam_Admin_Core.php:99 1180 1283 msgid "Antispam Settings" 1181 1284 msgstr "" 1182 1285 1183 #: admin/CF7_AntiSpam_Admin_Core.php:10 21286 #: admin/CF7_AntiSpam_Admin_Core.php:101 1184 1287 msgid "Activate Contact Form 7 integration" 1185 1288 msgstr "" 1186 1289 1187 #: admin/CF7_AntiSpam_Admin_Core.php:13 51290 #: admin/CF7_AntiSpam_Admin_Core.php:134 1188 1291 msgid "Antispam setting updated with success" 1189 1292 msgstr "" 1190 1293 1191 #: admin/CF7_AntiSpam_Admin_Core.php: 2001294 #: admin/CF7_AntiSpam_Admin_Core.php:199 1192 1295 msgid "Are you sure?" 1193 1296 msgstr "" 1194 1297 1195 #: admin/CF7_AntiSpam_Admin_Core.php:22 71298 #: admin/CF7_AntiSpam_Admin_Core.php:226 1196 1299 msgid "Stats for CF7 Antispam" 1197 1300 msgstr "" … … 1213 1316 msgstr "" 1214 1317 1215 #: src/settings/settings.ts: 2261318 #: src/settings/settings.ts:150 1216 1319 msgid "Status" 1217 1320 msgstr "" 1218 1321 1219 #: src/settings/settings.ts: 2261322 #: src/settings/settings.ts:150 1220 1323 msgid "CF7 Antispam plugin version is" 1221 1324 msgstr "" 1222 1325 1223 #: src/settings/settings.ts: 2261326 #: src/settings/settings.ts:150 1224 1327 msgid "Request timestamp" 1225 1328 msgstr "" -
cf7-antispam/trunk/readme.txt
r3392568 r3402920 5 5 Tested up to: 6.8 6 6 Requires PHP: 7.4 7 Stable tag: 0.7. 17 Stable tag: 0.7.2 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 172 172 173 173 == Changelog == 174 175 = 0.7.2 = 176 * Update fallback (thanks for the idea to @lemurnick) 177 * Fix for missing enqueue in some cases (thanks to @ohhcee, @o2xav, @WORX Developer for the feedbacks) 178 * Blacklist filters cleanup 179 * Registers the spam checks individually 180 * Updated encrypt/decrypt function 174 181 175 182 = 0.7.1 = -
cf7-antispam/trunk/vendor/composer/installed.json
r3392568 r3402920 82 82 "source": { 83 83 "type": "git", 84 "url": " git@github.com:maxmind/GeoIP2-php.git",84 "url": "https://github.com/maxmind/GeoIP2-php.git", 85 85 "reference": "6a41d8fbd6b90052bc34dff3b4252d0f88067b23" 86 86 }, … … 131 131 "maxmind" 132 132 ], 133 "support": { 134 "issues": "https://github.com/maxmind/GeoIP2-php/issues", 135 "source": "https://github.com/maxmind/GeoIP2-php/tree/v2.13.0" 136 }, 133 137 "install-path": "../geoip2/geoip2" 134 138 }, 135 139 { 136 140 "name": "maxmind-db/reader", 137 "version": "v1.1 2.1",138 "version_normalized": "1.1 2.1.0",141 "version": "v1.13.1", 142 "version_normalized": "1.13.1.0", 139 143 "source": { 140 144 "type": "git", 141 145 "url": "https://github.com/maxmind/MaxMind-DB-Reader-php.git", 142 "reference": " 815939e006b7e68062b540ec9e86aaa8be2b6ce4"143 }, 144 "dist": { 145 "type": "zip", 146 "url": "https://api.github.com/repos/maxmind/MaxMind-DB-Reader-php/zipball/ 815939e006b7e68062b540ec9e86aaa8be2b6ce4",147 "reference": " 815939e006b7e68062b540ec9e86aaa8be2b6ce4",146 "reference": "2194f58d0f024ce923e685cdf92af3daf9951908" 147 }, 148 "dist": { 149 "type": "zip", 150 "url": "https://api.github.com/repos/maxmind/MaxMind-DB-Reader-php/zipball/2194f58d0f024ce923e685cdf92af3daf9951908", 151 "reference": "2194f58d0f024ce923e685cdf92af3daf9951908", 148 152 "shasum": "" 149 153 }, … … 158 162 "phpstan/phpstan": "*", 159 163 "phpunit/phpunit": ">=8.0.0,<10.0.0", 160 "squizlabs/php_codesniffer": " 3.*"164 "squizlabs/php_codesniffer": "4.*" 161 165 }, 162 166 "suggest": { 163 167 "ext-bcmath": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder", 164 168 "ext-gmp": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder", 165 "ext-maxminddb": "A C-based database decoder that provides significantly faster lookups" 166 }, 167 "time": "2025-05-05T20:56:32+00:00", 169 "ext-maxminddb": "A C-based database decoder that provides significantly faster lookups", 170 "maxmind-db/reader-ext": "C extension for significantly faster IP lookups (install via PIE: pie install maxmind-db/reader-ext)" 171 }, 172 "time": "2025-11-21T22:24:26+00:00", 168 173 "type": "library", 169 174 "installation-source": "dist", … … 195 200 "support": { 196 201 "issues": "https://github.com/maxmind/MaxMind-DB-Reader-php/issues", 197 "source": "https://github.com/maxmind/MaxMind-DB-Reader-php/tree/v1.1 2.1"202 "source": "https://github.com/maxmind/MaxMind-DB-Reader-php/tree/v1.13.1" 198 203 }, 199 204 "install-path": "../maxmind-db/reader" … … 201 206 { 202 207 "name": "maxmind/web-service-common", 203 "version": "v0.1 0.0",204 "version_normalized": "0.1 0.0.0",208 "version": "v0.11.0", 209 "version_normalized": "0.11.0.0", 205 210 "source": { 206 211 "type": "git", 207 212 "url": "https://github.com/maxmind/web-service-common-php.git", 208 "reference": " d7c7c42fc31bff26e0ded73a6e187bcfb193f9c4"209 }, 210 "dist": { 211 "type": "zip", 212 "url": "https://api.github.com/repos/maxmind/web-service-common-php/zipball/ d7c7c42fc31bff26e0ded73a6e187bcfb193f9c4",213 "reference": " d7c7c42fc31bff26e0ded73a6e187bcfb193f9c4",213 "reference": "5b9e3d3472213361eebdb3ab8879e91b8952091b" 214 }, 215 "dist": { 216 "type": "zip", 217 "url": "https://api.github.com/repos/maxmind/web-service-common-php/zipball/5b9e3d3472213361eebdb3ab8879e91b8952091b", 218 "reference": "5b9e3d3472213361eebdb3ab8879e91b8952091b", 214 219 "shasum": "" 215 220 }, … … 224 229 "phpstan/phpstan": "*", 225 230 "phpunit/phpunit": "^8.0 || ^9.0", 226 "squizlabs/php_codesniffer": " 3.*"227 }, 228 "time": "202 4-11-14T23:14:52+00:00",231 "squizlabs/php_codesniffer": "4.*" 232 }, 233 "time": "2025-11-20T18:33:17+00:00", 229 234 "type": "library", 230 235 "installation-source": "dist", … … 249 254 "support": { 250 255 "issues": "https://github.com/maxmind/web-service-common-php/issues", 251 "source": "https://github.com/maxmind/web-service-common-php/tree/v0.1 0.0"256 "source": "https://github.com/maxmind/web-service-common-php/tree/v0.11.0" 252 257 }, 253 258 "install-path": "../maxmind/web-service-common" -
cf7-antispam/trunk/vendor/composer/installed.php
r3392568 r3402920 2 2 'root' => array( 3 3 'name' => 'codekraft/contactform7-antispam', 4 'pretty_version' => ' dev-main',5 'version' => ' dev-main',6 'reference' => 'b64f90abe05a7345358c22c91e8c3f2fb5e90656',4 'pretty_version' => '0.7.2', 5 'version' => '0.7.2.0', 6 'reference' => null, 7 7 'type' => 'wordpress-plugin', 8 8 'install_path' => __DIR__ . '/../../', … … 12 12 'versions' => array( 13 13 'codekraft/contactform7-antispam' => array( 14 'pretty_version' => ' dev-main',15 'version' => ' dev-main',16 'reference' => 'b64f90abe05a7345358c22c91e8c3f2fb5e90656',14 'pretty_version' => '0.7.2', 15 'version' => '0.7.2.0', 16 'reference' => null, 17 17 'type' => 'wordpress-plugin', 18 18 'install_path' => __DIR__ . '/../../', … … 39 39 ), 40 40 'maxmind-db/reader' => array( 41 'pretty_version' => 'v1.1 2.1',42 'version' => '1.1 2.1.0',43 'reference' => ' 815939e006b7e68062b540ec9e86aaa8be2b6ce4',41 'pretty_version' => 'v1.13.1', 42 'version' => '1.13.1.0', 43 'reference' => '2194f58d0f024ce923e685cdf92af3daf9951908', 44 44 'type' => 'library', 45 45 'install_path' => __DIR__ . '/../maxmind-db/reader', … … 48 48 ), 49 49 'maxmind/web-service-common' => array( 50 'pretty_version' => 'v0.1 0.0',51 'version' => '0.1 0.0.0',52 'reference' => ' d7c7c42fc31bff26e0ded73a6e187bcfb193f9c4',50 'pretty_version' => 'v0.11.0', 51 'version' => '0.11.0.0', 52 'reference' => '5b9e3d3472213361eebdb3ab8879e91b8952091b', 53 53 'type' => 'library', 54 54 'install_path' => __DIR__ . '/../maxmind/web-service-common', -
cf7-antispam/trunk/vendor/maxmind-db/reader/CHANGELOG.md
r3325969 r3402920 1 1 CHANGELOG 2 2 ========= 3 4 1.13.1 (2025-11-21) 5 ------------------- 6 7 * First PIE release. No other changes. 8 9 1.13.0 (2025-11-20) 10 ------------------- 11 12 * A redundant `filesize()` call in the reader's constructor was removed. 13 Pull request by Pavel Djundik. GitHub #189. 3 14 4 15 1.12.1 (2025-05-05) -
cf7-antispam/trunk/vendor/maxmind-db/reader/README.md
r3325969 r3402920 6 6 format that stores data indexed by IP address subnets (IPv4 or IPv6). 7 7 8 ## Installation (Composer) ## 9 10 We recommend installing this package with [Composer](https://getcomposer.org/). 8 ## Installation ## 9 10 ### C Extension (Recommended for Performance) ### 11 12 For significantly faster IP lookups, we recommend installing the C extension via 13 [PIE](https://github.com/php/pie): 14 15 ```bash 16 pie install maxmind-db/reader-ext 17 ``` 18 19 The C extension requires the [libmaxminddb](https://github.com/maxmind/libmaxminddb) 20 C library. See the [installation instructions](https://github.com/maxmind/MaxMind-DB-Reader-php-ext#prerequisites) 21 for your platform. 22 23 ### Pure PHP (No Compilation Required) ### 24 25 If you prefer not to compile a C extension or need maximum portability, you can 26 install the pure PHP implementation with [Composer](https://getcomposer.org/). 11 27 12 28 ### Download Composer ### … … 25 41 26 42 ``` 27 php composer.phar require maxmind-db/reader: ~1.043 php composer.phar require maxmind-db/reader:^1.13.1 28 44 ``` 29 45 … … 109 125 you are using an autoloader, no changes to your code should be necessary. 110 126 111 ### Installing Extension ### 127 ### Installing Extension via PIE (Recommended) ### 128 129 We recommend installing the extension via [PIE](https://github.com/php/pie): 130 131 ```bash 132 pie install maxmind-db/reader-ext 133 ``` 134 135 See the [extension repository](https://github.com/maxmind/MaxMind-DB-Reader-php-ext#prerequisites) 136 for prerequisites including libmaxminddb installation instructions. 137 138 ### Installing Extension via PECL (Legacy) ### 112 139 113 140 First install [libmaxminddb](https://github.com/maxmind/libmaxminddb) as … … 115 142 file](https://github.com/maxmind/libmaxminddb/blob/main/README.md#installing-from-a-tarball). 116 143 After successfully installing libmaxmindb, you may install the extension 117 from [ pecl](https://pecl.php.net/package/maxminddb):144 from [PECL](https://pecl.php.net/package/maxminddb): 118 145 119 146 ``` 120 147 pecl install maxminddb 121 148 ``` 149 150 ### Installing Extension from Source ### 122 151 123 152 Alternatively, you may install it from the source. To do so, run the following -
cf7-antispam/trunk/vendor/maxmind-db/reader/composer.json
r3325969 r3402920 19 19 "ext-bcmath": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder", 20 20 "ext-gmp": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder", 21 "ext-maxminddb": "A C-based database decoder that provides significantly faster lookups" 21 "ext-maxminddb": "A C-based database decoder that provides significantly faster lookups", 22 "maxmind-db/reader-ext": "C extension for significantly faster IP lookups (install via PIE: pie install maxmind-db/reader-ext)" 22 23 }, 23 24 "conflict": { … … 27 28 "friendsofphp/php-cs-fixer": "3.*", 28 29 "phpunit/phpunit": ">=8.0.0,<10.0.0", 29 "squizlabs/php_codesniffer": " 3.*",30 "squizlabs/php_codesniffer": "4.*", 30 31 "phpstan/phpstan": "*" 31 32 }, -
cf7-antispam/trunk/vendor/maxmind-db/reader/ext/php_maxminddb.h
r3325969 r3402920 16 16 #ifndef PHP_MAXMINDDB_H 17 17 #define PHP_MAXMINDDB_H 1 18 #define PHP_MAXMINDDB_VERSION "1.1 2.1"18 #define PHP_MAXMINDDB_VERSION "1.13.1" 19 19 #define PHP_MAXMINDDB_EXTNAME "maxminddb" 20 20 -
cf7-antispam/trunk/vendor/maxmind-db/reader/package.xml
r3325969 r3402920 15 15 <active>yes</active> 16 16 </lead> 17 <date>2025- 05-05</date>17 <date>2025-11-21</date> 18 18 <version> 19 <release>1.1 2.1</release>20 <api>1.1 2.1</api>19 <release>1.13.1</release> 20 <api>1.13.1</api> 21 21 </version> 22 22 <stability> … … 25 25 </stability> 26 26 <license uri="https://github.com/maxmind/MaxMind-DB-Reader-php/blob/main/LICENSE">Apache License 2.0</license> 27 <notes>* The C extension now checks that the database metadata lookup was 28 successful.</notes> 27 <notes>* First PIE release. No other changes.</notes> 29 28 <contents> 30 29 <dir name="/"> -
cf7-antispam/trunk/vendor/maxmind-db/reader/src/MaxMind/Db/Reader.php
r3325969 r3402920 95 95 $this->fileHandle = $fileHandle; 96 96 97 $f ileSize = @filesize($database);98 if ($f ileSize=== false) {97 $fstat = fstat($fileHandle); 98 if ($fstat === false) { 99 99 throw new \UnexpectedValueException( 100 100 "Error determining the size of \"$database\"." 101 101 ); 102 102 } 103 $this->fileSize = $f ileSize;103 $this->fileSize = $fstat['size']; 104 104 105 105 $start = $this->findMetadataStart($database); … … 333 333 { 334 334 $handle = $this->fileHandle; 335 $fstat = fstat($handle); 336 if ($fstat === false) { 337 throw new InvalidDatabaseException( 338 "Error getting file information ($filename)." 339 ); 340 } 341 $fileSize = $fstat['size']; 335 $fileSize = $this->fileSize; 342 336 $marker = self::$METADATA_START_MARKER; 343 337 $markerLength = self::$METADATA_START_MARKER_LENGTH; -
cf7-antispam/trunk/vendor/maxmind/web-service-common/CHANGELOG.md
r3325969 r3402920 1 1 CHANGELOG 2 2 ========= 3 4 0.11.0 (2025-11-20) 5 ------------------- 6 7 * Type hints have been improved. 3 8 4 9 0.10.0 (2024-11-14) -
cf7-antispam/trunk/vendor/maxmind/web-service-common/README.md
r3325969 r3402920 21 21 ## Copyright and License ## 22 22 23 This software is Copyright (c) 2015-202 4by MaxMind, Inc.23 This software is Copyright (c) 2015-2025 by MaxMind, Inc. 24 24 25 25 This is free software, licensed under the Apache License, Version 2.0. -
cf7-antispam/trunk/vendor/maxmind/web-service-common/composer.json
r3325969 r3402920 21 21 "friendsofphp/php-cs-fixer": "3.*", 22 22 "phpunit/phpunit": "^8.0 || ^9.0", 23 "squizlabs/php_codesniffer": " 3.*",23 "squizlabs/php_codesniffer": "4.*", 24 24 "phpstan/phpstan": "*" 25 25 }, -
cf7-antispam/trunk/vendor/maxmind/web-service-common/src/WebService/Client.php
r3325969 r3402920 112 112 } 113 113 114 $this->caBundle = isset($options['caBundle']) ?115 $this->caBundle = $options['caBundle'] : $this->getCaBundle();114 $this->caBundle = isset($options['caBundle']) 115 ? $this->caBundle = $options['caBundle'] : $this->getCaBundle(); 116 116 117 117 if (isset($options['connectTimeout'])) { … … 195 195 $curlVersion = curl_version(); 196 196 197 return $this->userAgentPrefix . 'MaxMind-WS-API/' . self::VERSION . ' PHP/' . \PHP_VERSION .198 ' curl/' . $curlVersion['version'];197 return $this->userAgentPrefix . 'MaxMind-WS-API/' . self::VERSION . ' PHP/' . \PHP_VERSION 198 . ' curl/' . $curlVersion['version']; 199 199 } 200 200 … … 326 326 if ($contentType === null || !strstr($contentType, 'json')) { 327 327 throw new HttpException( 328 "Received a $statusCode error for $service with " .329 'the following body: ' . $body,328 "Received a $statusCode error for $service with " 329 . 'the following body: ' . $body, 330 330 $statusCode, 331 331 $this->urlFor($path) … … 336 336 if ($message === null) { 337 337 throw new HttpException( 338 "Received a $statusCode error for $service but could " .339 'not decode the response as JSON: '338 "Received a $statusCode error for $service but could " 339 . 'not decode the response as JSON: ' 340 340 . $this->jsonErrorDescription() . ' Body: ' . $body, 341 341 $statusCode, … … 346 346 if (!isset($message['code']) || !isset($message['error'])) { 347 347 throw new HttpException( 348 'Error response contains JSON but it does not ' .349 'specify code or error keys: ' . $body,348 'Error response contains JSON but it does not ' 349 . 'specify code or error keys: ' . $body, 350 350 $statusCode, 351 351 $this->urlFor($path) … … 453 453 { 454 454 throw new HttpException( 455 'Received an unexpected HTTP status ' .456 "($statusCode) for $service",455 'Received an unexpected HTTP status ' 456 . "($statusCode) for $service", 457 457 $statusCode, 458 458 $this->urlFor($path) … … 478 478 if ($body !== null && $body !== '') { 479 479 throw new WebServiceException( 480 "Received a 204 response for $service along with an " .481 "unexpected HTTP body: $body"480 "Received a 204 response for $service along with an " 481 . "unexpected HTTP body: $body" 482 482 ); 483 483 } … … 489 489 if ($body === null || $body === '') { 490 490 throw new WebServiceException( 491 "Received a 200 response for $service but did not " .492 'receive a HTTP body.'491 "Received a 200 response for $service but did not " 492 . 'receive a HTTP body.' 493 493 ); 494 494 } … … 497 497 if ($decodedContent === null) { 498 498 throw new WebServiceException( 499 "Received a 200 response for $service but could " .500 'not decode the response as JSON: '499 "Received a 200 response for $service but could " 500 . 'not decode the response as JSON: ' 501 501 . $this->jsonErrorDescription() . ' Body: ' . $body 502 502 ); -
cf7-antispam/trunk/vendor/maxmind/web-service-common/src/WebService/Http/CurlRequest.php
r3325969 r3402920 25 25 26 26 /** 27 * @var array<string, mixed> 27 * @var array{ 28 * caBundle?: string, 29 * connectTimeout: float|int, 30 * curlHandle: \CurlHandle, 31 * headers: array<int, string>, 32 * proxy: string|null, 33 * timeout: float|int, 34 * userAgent: string 35 * } 28 36 */ 29 37 private $options; 30 38 31 39 /** 32 * @param array<string, mixed> $options 40 * @param array{ 41 * caBundle?: string, 42 * connectTimeout: float|int, 43 * curlHandle: \CurlHandle, 44 * headers: array<int, string>, 45 * proxy: string|null, 46 * timeout: float|int, 47 * userAgent: string 48 * } $options 33 49 */ 34 50 public function __construct(string $url, array $options) … … 90 106 $opts[\CURLOPT_PROXY] = $this->options['proxy']; 91 107 92 // The defined()s are here as the *_MS opts are not available on older93 // cURL versions94 108 $connectTimeout = $this->options['connectTimeout']; 95 if (\defined('CURLOPT_CONNECTTIMEOUT_MS')) { 96 $opts[\CURLOPT_CONNECTTIMEOUT_MS] = ceil($connectTimeout * 1000); 97 } else { 98 $opts[\CURLOPT_CONNECTTIMEOUT] = ceil($connectTimeout); 99 } 109 $opts[\CURLOPT_CONNECTTIMEOUT_MS] = (int) ceil($connectTimeout * 1000); 100 110 101 111 $timeout = $this->options['timeout']; 102 if (\defined('CURLOPT_TIMEOUT_MS')) { 103 $opts[\CURLOPT_TIMEOUT_MS] = ceil($timeout * 1000); 104 } else { 105 $opts[\CURLOPT_TIMEOUT] = ceil($timeout); 106 } 112 $opts[\CURLOPT_TIMEOUT_MS] = (int) ceil($timeout * 1000); 107 113 108 114 curl_setopt_array($this->ch, $opts);
Note: See TracChangeset
for help on using the changeset viewer.