@anonympins/fingerprint 0.7.2 → 0.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -9
- package/README.md +1 -1
- package/package.json +109 -107
- package/public/fingerprint-anti-bot.zip +0 -0
- package/src/js/fingerprint.client.js +252 -45
- package/src/js/fingerprint.client.obfuscated.js +1 -1
- package/src/js/fingerprint.js +265 -185
- package/src/js/fingerprint.utils.js +32 -5
- package/src/js/fingerprint.worker.js +81 -0
- package/src/js/library.js +6 -2
- package/src/js/pow.solver.js +2 -3
- package/src/js/problem-manager.js +113 -113
- package/src/js/tests/fingerprint.client.init.test.js +30 -0
- package/src/js/tests/fingerprint.test.js +136 -4
- package/src/js/tests/threatIntel.test.js +76 -0
- package/src/php/AutoTuner.php +36 -18
- package/src/php/Challenge/ChallengeUtils.php +121 -240
- package/src/php/DirectFingerprint.php +16 -4
- package/src/php/FingerprintClient.php +17 -19
- package/src/php/FingerprintEngine.php +77 -39
- package/src/php/Ja3AnomalyDetector.php +20 -12
- package/src/php/Optimization/Optimization.php +5 -1
- package/src/php/Optimization/OptimizationOperators.php +5 -1
- package/src/php/Optimization/ProblemInitializers.php +16 -4
- package/src/php/ProblemManager.php +20 -14
- package/src/php/Tests/ChallengeUtilsTest.php +469 -453
- package/src/php/Tests/FingerprintEngineTest.php +6 -1
- package/src/php/Tests/RequestUtilsTest.php +1 -1
- package/src/php/Tests/ThreatIntelTest.php +64 -0
- package/src/php/Utils/Env.php +51 -49
- package/src/php/Utils/MaliciousPatterns.php +74 -74
- package/src/php/Utils/RequestUtils.php +231 -132
- package/src/php/WordPress/WpDbStore.php +4 -0
- package/src/php/WordPress/{fingerprint-wordpress.php → fingerprint-anti-bot.php} +131 -126
- package/src/php/WordPress/languages/fingerprint-wordpress-de_DE.mo +0 -0
- package/src/php/WordPress/languages/fingerprint-wordpress-de_DE.po +1 -1
- package/src/php/WordPress/languages/fingerprint-wordpress-fr_FR.mo +0 -0
- package/src/php/WordPress/languages/fingerprint-wordpress-fr_FR.po +1 -1
- package/src/php/WordPress/package.php +6 -3
- package/src/php/WordPress/readme.txt +36 -0
- package/public/fingerprint-wordpress.zip +0 -0
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
* Plugin Name: Fingerprint Anti-Bot & Proof-of-Work
|
|
4
4
|
* Plugin URI: https://github.com/anonympins/fingerprint
|
|
5
5
|
* Description: High-performance client-side anti-bot protection and Proof-of-Work challenge verification for WordPress.
|
|
6
|
-
* Version: 0.7.
|
|
7
|
-
* Author:
|
|
6
|
+
* Version: 0.7.4
|
|
7
|
+
* Author: anonympins
|
|
8
|
+
* Requires at least: 5.9
|
|
9
|
+
* Requires PHP: 8.0
|
|
8
10
|
* License: MIT
|
|
9
|
-
* Text Domain: fingerprint-
|
|
11
|
+
* Text Domain: fingerprint-anti-bot
|
|
10
12
|
* Domain Path: /languages
|
|
11
13
|
*/
|
|
12
14
|
|
|
@@ -27,7 +29,7 @@ if (!defined('ABSPATH')) {
|
|
|
27
29
|
// Détecte et bloque instantanément les scans de vulnérabilités ciblant
|
|
28
30
|
// Laravel, Symfony, Spring Boot, Django, ASP.NET, phpMyAdmin, Git, Cloud, etc.
|
|
29
31
|
// =============================================================================
|
|
30
|
-
$
|
|
32
|
+
$fingerprint_foreign_env_trap_urls = [
|
|
31
33
|
// Outils d'administration BDD & scripts de debug
|
|
32
34
|
'/phpmyadmin', '/pma', '/adminer', '/mysql', '/dbadmin', '/phpinfo',
|
|
33
35
|
// Frameworks PHP (Laravel, Symfony) & fichiers d'environnement
|
|
@@ -44,7 +46,7 @@ $foreignEnvTrapUrls = [
|
|
|
44
46
|
'/.git', '/.svn', '/.aws', '/.kube', '/docker-compose', '/serverless'
|
|
45
47
|
];
|
|
46
48
|
|
|
47
|
-
$
|
|
49
|
+
$fingerprint_foreign_env_honeypot_fields = [
|
|
48
50
|
// Tokens CSRF et formulaires spécifiques à d'autres frameworks
|
|
49
51
|
'_token', // Laravel
|
|
50
52
|
'csrfmiddlewaretoken', // Django
|
|
@@ -60,15 +62,15 @@ $foreignEnvHoneypotFields = [
|
|
|
60
62
|
// =============================================================================
|
|
61
63
|
// CONFIGURATION PAR DÉFAUT DES PROFILS DE SÉCURITÉ PAR CONTEXTE
|
|
62
64
|
// =============================================================================
|
|
63
|
-
$
|
|
65
|
+
$fingerprint_security_profiles = [
|
|
64
66
|
'api' => [
|
|
65
67
|
'profile' => 'api',
|
|
66
68
|
'overrides' => [
|
|
67
69
|
'verbose' => false,
|
|
68
70
|
'challengeNewDevices' => false,
|
|
69
71
|
'honeypot' => [
|
|
70
|
-
'fields' => $
|
|
71
|
-
'trapUrls' => $
|
|
72
|
+
'fields' => $fingerprint_foreign_env_honeypot_fields,
|
|
73
|
+
'trapUrls' => $fingerprint_foreign_env_trap_urls,
|
|
72
74
|
'detectInjections' => true,
|
|
73
75
|
],
|
|
74
76
|
],
|
|
@@ -79,8 +81,8 @@ $fingerprintSecurityProfiles = [
|
|
|
79
81
|
'verbose' => true,
|
|
80
82
|
'challengeNewDevices' => true,
|
|
81
83
|
'honeypot' => [
|
|
82
|
-
'fields' => $
|
|
83
|
-
'trapUrls' => $
|
|
84
|
+
'fields' => $fingerprint_foreign_env_honeypot_fields,
|
|
85
|
+
'trapUrls' => $fingerprint_foreign_env_trap_urls,
|
|
84
86
|
'detectInjections' => true,
|
|
85
87
|
],
|
|
86
88
|
],
|
|
@@ -91,8 +93,8 @@ $fingerprintSecurityProfiles = [
|
|
|
91
93
|
'verbose' => false,
|
|
92
94
|
'challengeNewDevices' => false,
|
|
93
95
|
'honeypot' => [
|
|
94
|
-
'fields' => $
|
|
95
|
-
'trapUrls' => $
|
|
96
|
+
'fields' => $fingerprint_foreign_env_honeypot_fields,
|
|
97
|
+
'trapUrls' => $fingerprint_foreign_env_trap_urls,
|
|
96
98
|
'detectInjections' => true,
|
|
97
99
|
],
|
|
98
100
|
],
|
|
@@ -114,22 +116,17 @@ function fingerprint_get_effective_profiles(array $defaultProfiles): array {
|
|
|
114
116
|
];
|
|
115
117
|
}
|
|
116
118
|
|
|
117
|
-
// Chargement du domaine de traduction i18n (FR / EN / DE)
|
|
118
|
-
add_action('init', function (): void {
|
|
119
|
-
load_plugin_textdomain('fingerprint-wordpress', false, dirname(plugin_basename(__FILE__)) . '/languages');
|
|
120
|
-
});
|
|
121
|
-
|
|
122
119
|
// 1. Autoloader PSR-4 pour le moteur Fingerprint
|
|
123
120
|
if (!class_exists(DirectFingerprint::class)) {
|
|
124
|
-
$
|
|
121
|
+
$fingerprint_composer_paths = [
|
|
125
122
|
__DIR__ . '/vendor/autoload.php',
|
|
126
123
|
dirname(__DIR__, 2) . '/vendor/autoload.php',
|
|
127
124
|
dirname(__DIR__, 3) . '/vendor/autoload.php',
|
|
128
125
|
(defined('ABSPATH') ? ABSPATH . 'vendor/autoload.php' : ''),
|
|
129
126
|
];
|
|
130
|
-
foreach ($
|
|
131
|
-
if (!empty($
|
|
132
|
-
require_once $
|
|
127
|
+
foreach ($fingerprint_composer_paths as $fingerprint_composer_path) {
|
|
128
|
+
if (!empty($fingerprint_composer_path) && file_exists($fingerprint_composer_path)) {
|
|
129
|
+
require_once $fingerprint_composer_path;
|
|
133
130
|
break;
|
|
134
131
|
}
|
|
135
132
|
}
|
|
@@ -197,15 +194,15 @@ add_action('fingerprint_prune_expired_entries', function () {
|
|
|
197
194
|
add_action('admin_notices', function () {
|
|
198
195
|
if (!is_ssl()) {
|
|
199
196
|
echo '<div class="notice notice-warning is-dismissible">';
|
|
200
|
-
echo '<p><strong>' . esc_html__('[Fingerprint Anti-Bot Security Warning]', 'fingerprint-
|
|
201
|
-
esc_html__('Your website is currently running on unencrypted HTTP. In this mode, modern web browsers disable the native Web Cryptography API (crypto.subtle) for security reasons, forcing a JavaScript fallback simulation that is slower and vulnerable to Man-in-the-Middle (MitM) attacks. We strongly recommend deploying a TLS/SSL certificate and enforcing HTTPS to ensure the cryptographic integrity of Proof-of-Work computations and identity protection.', 'fingerprint-
|
|
197
|
+
echo '<p><strong>' . esc_html__('[Fingerprint Anti-Bot Security Warning]', 'fingerprint-anti-bot') . '</strong> : ' .
|
|
198
|
+
esc_html__('Your website is currently running on unencrypted HTTP. In this mode, modern web browsers disable the native Web Cryptography API (crypto.subtle) for security reasons, forcing a JavaScript fallback simulation that is slower and vulnerable to Man-in-the-Middle (MitM) attacks. We strongly recommend deploying a TLS/SSL certificate and enforcing HTTPS to ensure the cryptographic integrity of Proof-of-Work computations and identity protection.', 'fingerprint-anti-bot') .
|
|
202
199
|
'</p>';
|
|
203
200
|
echo '</div>';
|
|
204
201
|
}
|
|
205
202
|
});
|
|
206
203
|
|
|
207
204
|
// 6. Interception de sécurité au plus tôt du cycle de vie WordPress
|
|
208
|
-
add_action('plugins_loaded', function () use ($
|
|
205
|
+
add_action('plugins_loaded', function () use ($fingerprint_security_profiles) {
|
|
209
206
|
// Ignore WP-CLI et les exécutions internes de cron
|
|
210
207
|
if ((defined('WP_CLI') && WP_CLI) || (defined('DOING_CRON') && DOING_CRON)) {
|
|
211
208
|
return;
|
|
@@ -215,23 +212,26 @@ add_action('plugins_loaded', function () use ($fingerprintSecurityProfiles) {
|
|
|
215
212
|
$store = new WpDbStore();
|
|
216
213
|
StoreManager::configureStore($store);
|
|
217
214
|
|
|
218
|
-
|
|
215
|
+
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Sanitized with sanitize_text_field
|
|
216
|
+
$rawUri = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : '/';
|
|
217
|
+
$requestUri = !empty($rawUri) ? $rawUri : '/';
|
|
219
218
|
$isRestApi = defined('REST_REQUEST') && REST_REQUEST;
|
|
220
|
-
|
|
219
|
+
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
|
220
|
+
$isAdmin = is_admin() || (isset($_SERVER['PHP_SELF']) && str_contains(sanitize_text_field(wp_unslash($_SERVER['PHP_SELF'])), 'wp-login.php')) || str_contains($requestUri, 'wp-login.php');
|
|
221
221
|
|
|
222
222
|
// Fusion avec les options enregistrées via l'admin WP
|
|
223
|
-
$effectiveProfiles = fingerprint_get_effective_profiles($
|
|
223
|
+
$effectiveProfiles = fingerprint_get_effective_profiles($fingerprint_security_profiles);
|
|
224
224
|
|
|
225
225
|
// Possibilité de filtrer la configuration via functions.php ou un thème
|
|
226
226
|
$configs = apply_filters('fingerprint_security_profiles', $effectiveProfiles);
|
|
227
227
|
|
|
228
228
|
// Sélection adaptative du profil selon la cible de la requête
|
|
229
229
|
if ($isRestApi || str_starts_with($requestUri, '/wp-json/')) {
|
|
230
|
-
$contextConfig = $configs['api'] ?? $
|
|
230
|
+
$contextConfig = $configs['api'] ?? $fingerprint_security_profiles['api'];
|
|
231
231
|
} elseif ($isAdmin) {
|
|
232
|
-
$contextConfig = $configs['admin'] ?? $
|
|
232
|
+
$contextConfig = $configs['admin'] ?? $fingerprint_security_profiles['admin'];
|
|
233
233
|
} else {
|
|
234
|
-
$contextConfig = $configs['frontend'] ?? $
|
|
234
|
+
$contextConfig = $configs['frontend'] ?? $fingerprint_security_profiles['frontend'];
|
|
235
235
|
}
|
|
236
236
|
|
|
237
237
|
$securityConfig = SecurityProfiles::createSecurityProfile($contextConfig['profile'], $contextConfig['overrides'] ?? []);
|
|
@@ -247,8 +247,8 @@ add_action('plugins_loaded', function () use ($fingerprintSecurityProfiles) {
|
|
|
247
247
|
|
|
248
248
|
add_action('admin_menu', function () {
|
|
249
249
|
add_options_page(
|
|
250
|
-
__('Fingerprint Anti-Bot', 'fingerprint-
|
|
251
|
-
__('Fingerprint Anti-Bot', 'fingerprint-
|
|
250
|
+
__('Fingerprint Anti-Bot', 'fingerprint-anti-bot'),
|
|
251
|
+
__('Fingerprint Anti-Bot', 'fingerprint-anti-bot'),
|
|
252
252
|
'manage_options',
|
|
253
253
|
'fingerprint-settings',
|
|
254
254
|
'fingerprint_render_admin_page'
|
|
@@ -260,10 +260,10 @@ add_action('admin_menu', function () {
|
|
|
260
260
|
*/
|
|
261
261
|
function fingerprint_render_admin_page(): void {
|
|
262
262
|
if (!current_user_can('manage_options')) {
|
|
263
|
-
wp_die(esc_html__('You do not have sufficient permissions to access this page.', 'fingerprint-
|
|
263
|
+
wp_die(esc_html__('You do not have sufficient permissions to access this page.', 'fingerprint-anti-bot'));
|
|
264
264
|
}
|
|
265
265
|
|
|
266
|
-
global $
|
|
266
|
+
global $fingerprint_security_profiles, $wpdb;
|
|
267
267
|
|
|
268
268
|
// Sauvegarde des réglages
|
|
269
269
|
if (isset($_POST['fingerprint_save_settings']) && check_admin_referer('fingerprint_settings_nonce', 'fingerprint_nonce')) {
|
|
@@ -273,16 +273,16 @@ function fingerprint_render_admin_page(): void {
|
|
|
273
273
|
}
|
|
274
274
|
|
|
275
275
|
// Profils sélectionnés
|
|
276
|
-
$saved['frontend']['profile'] = sanitize_text_field($_POST['frontend_profile']
|
|
277
|
-
$saved['admin']['profile'] = sanitize_text_field($_POST['admin_profile']
|
|
278
|
-
$saved['api']['profile'] = sanitize_text_field($_POST['api_profile']
|
|
276
|
+
$saved['frontend']['profile'] = isset($_POST['frontend_profile']) ? sanitize_text_field(wp_unslash($_POST['frontend_profile'])) : 'blog';
|
|
277
|
+
$saved['admin']['profile'] = isset($_POST['admin_profile']) ? sanitize_text_field(wp_unslash($_POST['admin_profile'])) : 'strict';
|
|
278
|
+
$saved['api']['profile'] = isset($_POST['api_profile']) ? sanitize_text_field(wp_unslash($_POST['api_profile'])) : 'api';
|
|
279
279
|
|
|
280
280
|
// Seuils Frontend
|
|
281
281
|
$saved['frontend']['overrides']['thresholds'] = [
|
|
282
|
-
'low' => max(1, (int)($_POST['frontend_threshold_low']
|
|
283
|
-
'medium' => max(5, (int)($_POST['frontend_threshold_medium']
|
|
284
|
-
'high' => max(10, (int)($_POST['frontend_threshold_high']
|
|
285
|
-
'block' => max(20, (int)($_POST['frontend_threshold_block']
|
|
282
|
+
'low' => max(1, isset($_POST['frontend_threshold_low']) ? (int)sanitize_text_field(wp_unslash($_POST['frontend_threshold_low'])) : 20),
|
|
283
|
+
'medium' => max(5, isset($_POST['frontend_threshold_medium']) ? (int)sanitize_text_field(wp_unslash($_POST['frontend_threshold_medium'])) : 45),
|
|
284
|
+
'high' => max(10, isset($_POST['frontend_threshold_high']) ? (int)sanitize_text_field(wp_unslash($_POST['frontend_threshold_high'])) : 75),
|
|
285
|
+
'block' => max(20, isset($_POST['frontend_threshold_block']) ? (int)sanitize_text_field(wp_unslash($_POST['frontend_threshold_block'])) : 95),
|
|
286
286
|
];
|
|
287
287
|
|
|
288
288
|
// Options booléennes
|
|
@@ -292,49 +292,51 @@ function fingerprint_render_admin_page(): void {
|
|
|
292
292
|
|
|
293
293
|
// Surcharges de l'ensemble des poids de métriques
|
|
294
294
|
foreach ($_POST as $postKey => $postVal) {
|
|
295
|
-
if (str_starts_with($postKey, 'weight_')) {
|
|
296
|
-
$wKey = substr($postKey, 7);
|
|
297
|
-
$val = (float)$postVal;
|
|
295
|
+
if (str_starts_with((string)$postKey, 'weight_')) {
|
|
296
|
+
$wKey = sanitize_key(substr((string)$postKey, 7));
|
|
297
|
+
$val = (float)sanitize_text_field(wp_unslash($postVal));
|
|
298
298
|
$saved['frontend']['overrides']['weights'][$wKey] = max(0.0, min(2.0, $val));
|
|
299
299
|
}
|
|
300
300
|
}
|
|
301
301
|
|
|
302
302
|
update_option('fingerprint_security_options', $saved);
|
|
303
|
-
echo '<div class="notice notice-success is-dismissible"><p><strong>' . esc_html__('Fingerprint settings updated successfully.', 'fingerprint-
|
|
303
|
+
echo '<div class="notice notice-success is-dismissible"><p><strong>' . esc_html__('Fingerprint settings updated successfully.', 'fingerprint-anti-bot') . '</strong></p></div>';
|
|
304
304
|
}
|
|
305
305
|
|
|
306
306
|
// Action pour vider le cache SQL manuellement
|
|
307
307
|
if (isset($_POST['fingerprint_clear_store']) && check_admin_referer('fingerprint_clear_nonce', 'fingerprint_nonce_clear')) {
|
|
308
308
|
$store = new WpDbStore();
|
|
309
309
|
$store->clear();
|
|
310
|
-
echo '<div class="notice notice-info is-dismissible"><p>' . esc_html__('SQL cache table ($wpdb) cleared successfully.', 'fingerprint-
|
|
310
|
+
echo '<div class="notice notice-info is-dismissible"><p>' . esc_html__('SQL cache table ($wpdb) cleared successfully.', 'fingerprint-anti-bot') . '</p></div>';
|
|
311
311
|
}
|
|
312
312
|
|
|
313
313
|
// Récupération des profils effectifs
|
|
314
|
-
$effective = fingerprint_get_effective_profiles($
|
|
314
|
+
$effective = fingerprint_get_effective_profiles($fingerprint_security_profiles);
|
|
315
315
|
$frontendConfig = SecurityProfiles::createSecurityProfile($effective['frontend']['profile'], $effective['frontend']['overrides'] ?? []);
|
|
316
316
|
|
|
317
317
|
// Statistiques de la table de cache SQL
|
|
318
|
-
$tableName = $wpdb->prefix . 'fingerprint_store';
|
|
319
|
-
|
|
318
|
+
$tableName = esc_sql($wpdb->prefix . 'fingerprint_store');
|
|
319
|
+
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared,PluginCheck.Security.DirectDB.UnescapedDBParameter -- Administrative stats on custom high-velocity table.
|
|
320
|
+
$totalRows = (int)$wpdb->get_var("SELECT COUNT(*) FROM `{$tableName}`");
|
|
320
321
|
$now = time();
|
|
321
|
-
|
|
322
|
+
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared,PluginCheck.Security.DirectDB.UnescapedDBParameter -- Administrative stats on custom high-velocity table.
|
|
323
|
+
$expiredRows = (int)$wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM `{$tableName}` WHERE expires_at IS NOT NULL AND expires_at < %d", $now));
|
|
322
324
|
|
|
323
325
|
// Métriques Prometheus au format texte
|
|
324
326
|
$prometheusRaw = MetricsManager::getPrometheusMetrics($frontendConfig);
|
|
325
327
|
?>
|
|
326
328
|
<div class="wrap">
|
|
327
329
|
<h1><span class="dashicons dashicons-shield-alt" style="font-size:32px;vertical-align:middle;margin-right:8px;"></span> Fingerprint Anti-Bot & Proof-of-Work</h1>
|
|
328
|
-
<p class="description"><?php esc_html_e('Client-side behavioral and cryptographic anti-bot protection without third-party CAPTCHA for WordPress.', 'fingerprint-
|
|
330
|
+
<p class="description"><?php esc_html_e('Client-side behavioral and cryptographic anti-bot protection without third-party CAPTCHA for WordPress.', 'fingerprint-anti-bot'); ?></p>
|
|
329
331
|
|
|
330
332
|
<div style="background:#fff;border-left:4px solid #2271b1;padding:12px 18px;margin:18px 0;box-shadow:0 1px 1px rgba(0,0,0,.04);">
|
|
331
333
|
<p style="margin:4px 0;">
|
|
332
|
-
<strong><?php esc_html_e('Official documentation reference:', 'fingerprint-
|
|
334
|
+
<strong><?php esc_html_e('Official documentation reference:', 'fingerprint-anti-bot'); ?></strong>
|
|
333
335
|
<a href="https://github.com/anonympins/fingerprint/blob/main/doc/full_options.md" target="_blank" rel="noopener noreferrer" class="button button-secondary" style="margin-left:8px;">
|
|
334
|
-
<span class="dashicons dashicons-external" style="vertical-align:middle;"></span> <?php esc_html_e('View Full Configuration Options on GitHub', 'fingerprint-
|
|
336
|
+
<span class="dashicons dashicons-external" style="vertical-align:middle;"></span> <?php esc_html_e('View Full Configuration Options on GitHub', 'fingerprint-anti-bot'); ?>
|
|
335
337
|
</a>
|
|
336
338
|
<a href="https://github.com/anonympins/fingerprint" target="_blank" rel="noopener noreferrer" class="button button-secondary" style="margin-left:4px;">
|
|
337
|
-
<span class="dashicons dashicons-admin-plugins" style="vertical-align:middle;"></span> <?php esc_html_e('GitHub Repository', 'fingerprint-
|
|
339
|
+
<span class="dashicons dashicons-admin-plugins" style="vertical-align:middle;"></span> <?php esc_html_e('GitHub Repository', 'fingerprint-anti-bot'); ?>
|
|
338
340
|
</a>
|
|
339
341
|
</p>
|
|
340
342
|
</div>
|
|
@@ -342,37 +344,40 @@ function fingerprint_render_admin_page(): void {
|
|
|
342
344
|
<!-- TABLEAU DE BORD STATISTIQUES & ÉTAT -->
|
|
343
345
|
<div style="display:grid;grid-template-columns:repeat(auto-fit, minmax(240px, 1fr));gap:16px;margin-bottom:24px;">
|
|
344
346
|
<div style="background:#fff;padding:16px;border-radius:4px;border:1px solid #ccd0d4;">
|
|
345
|
-
<h3 style="margin-top:0;"><?php esc_html_e('HTTPS Status', 'fingerprint-
|
|
347
|
+
<h3 style="margin-top:0;"><?php esc_html_e('HTTPS Status', 'fingerprint-anti-bot'); ?></h3>
|
|
346
348
|
<?php if (is_ssl()): ?>
|
|
347
349
|
<p style="color:#007017;font-weight:bold;font-size:16px;">
|
|
348
|
-
<span class="dashicons dashicons-yes-alt"></span> <?php esc_html_e('Active (WebCrypto Subtle available)', 'fingerprint-
|
|
350
|
+
<span class="dashicons dashicons-yes-alt"></span> <?php esc_html_e('Active (WebCrypto Subtle available)', 'fingerprint-anti-bot'); ?>
|
|
349
351
|
</p>
|
|
350
352
|
<?php else: ?>
|
|
351
353
|
<p style="color:#d63638;font-weight:bold;font-size:16px;">
|
|
352
|
-
<span class="dashicons dashicons-warning"></span> <?php esc_html_e('Insecure (Unencrypted HTTP)', 'fingerprint-
|
|
354
|
+
<span class="dashicons dashicons-warning"></span> <?php esc_html_e('Insecure (Unencrypted HTTP)', 'fingerprint-anti-bot'); ?>
|
|
353
355
|
</p>
|
|
354
356
|
<?php endif; ?>
|
|
355
357
|
</div>
|
|
356
358
|
<div style="background:#fff;padding:16px;border-radius:4px;border:1px solid #ccd0d4;">
|
|
357
|
-
<h3 style="margin-top:0;"><?php esc_html_e('SQL Cache ($wpdb)', 'fingerprint-
|
|
358
|
-
<p style="font-size:22px;margin:0;font-weight:600;"><?php echo esc_html((string)$totalRows); ?> <span style="font-size:14px;color:#646970;font-weight:normal;"><?php esc_html_e('keys in database', 'fingerprint-
|
|
359
|
-
<small style="color:#8c8f94;"><?php
|
|
359
|
+
<h3 style="margin-top:0;"><?php esc_html_e('SQL Cache ($wpdb)', 'fingerprint-anti-bot'); ?></h3>
|
|
360
|
+
<p style="font-size:22px;margin:0;font-weight:600;"><?php echo esc_html((string)$totalRows); ?> <span style="font-size:14px;color:#646970;font-weight:normal;"><?php esc_html_e('keys in database', 'fingerprint-anti-bot'); ?></span></p>
|
|
361
|
+
<small style="color:#8c8f94;"><?php
|
|
362
|
+
/* translators: %d: number of expired keys awaiting cron purge */
|
|
363
|
+
echo esc_html(sprintf(__(' %d expired keys awaiting cron purge', 'fingerprint-anti-bot'), $expiredRows));
|
|
364
|
+
?></small>
|
|
360
365
|
</div>
|
|
361
366
|
<div style="background:#fff;padding:16px;border-radius:4px;border:1px solid #ccd0d4;">
|
|
362
|
-
<h3 style="margin-top:0;"><?php esc_html_e('Active Profiles', 'fingerprint-
|
|
367
|
+
<h3 style="margin-top:0;"><?php esc_html_e('Active Profiles', 'fingerprint-anti-bot'); ?></h3>
|
|
363
368
|
<p style="margin:0;">
|
|
364
|
-
<?php esc_html_e('Frontend:', 'fingerprint-
|
|
365
|
-
<?php esc_html_e('Admin:', 'fingerprint-
|
|
366
|
-
<?php esc_html_e('REST API:', 'fingerprint-
|
|
369
|
+
<?php esc_html_e('Frontend:', 'fingerprint-anti-bot'); ?> <strong><?php echo esc_html($effective['frontend']['profile']); ?></strong><br>
|
|
370
|
+
<?php esc_html_e('Admin:', 'fingerprint-anti-bot'); ?> <strong><?php echo esc_html($effective['admin']['profile']); ?></strong><br>
|
|
371
|
+
<?php esc_html_e('REST API:', 'fingerprint-anti-bot'); ?> <strong><?php echo esc_html($effective['api']['profile']); ?></strong>
|
|
367
372
|
</p>
|
|
368
373
|
</div>
|
|
369
374
|
</div>
|
|
370
375
|
|
|
371
376
|
<!-- ONGLETS DE NAVIGATION -->
|
|
372
377
|
<h2 class="nav-tab-wrapper">
|
|
373
|
-
<a href="#tab-settings" class="nav-tab nav-tab-active" onclick="fingerprintSwitchTab(event, 'tab-settings')"><?php esc_html_e('Settings & Profiles', 'fingerprint-
|
|
374
|
-
<a href="#tab-metrics" class="nav-tab" onclick="fingerprintSwitchTab(event, 'tab-metrics')"><?php esc_html_e('Metrics & Weights View', 'fingerprint-
|
|
375
|
-
<a href="#tab-prometheus" class="nav-tab" onclick="fingerprintSwitchTab(event, 'tab-prometheus')"><?php esc_html_e('Prometheus Stream', 'fingerprint-
|
|
378
|
+
<a href="#tab-settings" class="nav-tab nav-tab-active" onclick="fingerprintSwitchTab(event, 'tab-settings')"><?php esc_html_e('Settings & Profiles', 'fingerprint-anti-bot'); ?></a>
|
|
379
|
+
<a href="#tab-metrics" class="nav-tab" onclick="fingerprintSwitchTab(event, 'tab-metrics')"><?php esc_html_e('Metrics & Weights View', 'fingerprint-anti-bot'); ?></a>
|
|
380
|
+
<a href="#tab-prometheus" class="nav-tab" onclick="fingerprintSwitchTab(event, 'tab-prometheus')"><?php esc_html_e('Prometheus Stream', 'fingerprint-anti-bot'); ?></a>
|
|
376
381
|
</h2>
|
|
377
382
|
|
|
378
383
|
<!-- TAB 1 : RÉGLAGES -->
|
|
@@ -380,35 +385,35 @@ function fingerprint_render_admin_page(): void {
|
|
|
380
385
|
<form method="post" action="">
|
|
381
386
|
<?php wp_nonce_field('fingerprint_settings_nonce', 'fingerprint_nonce'); ?>
|
|
382
387
|
|
|
383
|
-
<h3><?php esc_html_e('1. Target Security Profiles', 'fingerprint-
|
|
388
|
+
<h3><?php esc_html_e('1. Target Security Profiles', 'fingerprint-anti-bot'); ?></h3>
|
|
384
389
|
<table class="form-table">
|
|
385
390
|
<tr>
|
|
386
|
-
<th scope="row"><label for="frontend_profile"><?php esc_html_e('Visitors & Frontend', 'fingerprint-
|
|
391
|
+
<th scope="row"><label for="frontend_profile"><?php esc_html_e('Visitors & Frontend', 'fingerprint-anti-bot'); ?></label></th>
|
|
387
392
|
<td>
|
|
388
393
|
<select name="frontend_profile" id="frontend_profile">
|
|
389
|
-
<option value="blog" <?php selected($effective['frontend']['profile'], 'blog'); ?>><?php esc_html_e('Blog (Optimal for content, smooth UX)', 'fingerprint-
|
|
390
|
-
<option value="balanced" <?php selected($effective['frontend']['profile'], 'balanced'); ?>><?php esc_html_e('Balanced (General purpose)', 'fingerprint-
|
|
391
|
-
<option value="strict" <?php selected($effective['frontend']['profile'], 'strict'); ?>><?php esc_html_e('Strict (Maximum protection)', 'fingerprint-
|
|
392
|
-
<option value="ecommerce" <?php selected($effective['frontend']['profile'], 'ecommerce'); ?>><?php esc_html_e('E-commerce (Anti-scraping / scalping)', 'fingerprint-
|
|
394
|
+
<option value="blog" <?php selected($effective['frontend']['profile'], 'blog'); ?>><?php esc_html_e('Blog (Optimal for content, smooth UX)', 'fingerprint-anti-bot'); ?></option>
|
|
395
|
+
<option value="balanced" <?php selected($effective['frontend']['profile'], 'balanced'); ?>><?php esc_html_e('Balanced (General purpose)', 'fingerprint-anti-bot'); ?></option>
|
|
396
|
+
<option value="strict" <?php selected($effective['frontend']['profile'], 'strict'); ?>><?php esc_html_e('Strict (Maximum protection)', 'fingerprint-anti-bot'); ?></option>
|
|
397
|
+
<option value="ecommerce" <?php selected($effective['frontend']['profile'], 'ecommerce'); ?>><?php esc_html_e('E-commerce (Anti-scraping / scalping)', 'fingerprint-anti-bot'); ?></option>
|
|
393
398
|
</select>
|
|
394
|
-
<p class="description"><?php esc_html_e('Profile applied to all public pages of the WordPress site.', 'fingerprint-
|
|
399
|
+
<p class="description"><?php esc_html_e('Profile applied to all public pages of the WordPress site.', 'fingerprint-anti-bot'); ?></p>
|
|
395
400
|
</td>
|
|
396
401
|
</tr>
|
|
397
402
|
<tr>
|
|
398
|
-
<th scope="row"><label for="admin_profile"><?php esc_html_e('Administration Area (wp-login / wp-admin)', 'fingerprint-
|
|
403
|
+
<th scope="row"><label for="admin_profile"><?php esc_html_e('Administration Area (wp-login / wp-admin)', 'fingerprint-anti-bot'); ?></label></th>
|
|
399
404
|
<td>
|
|
400
405
|
<select name="admin_profile" id="admin_profile">
|
|
401
|
-
<option value="strict" <?php selected($effective['admin']['profile'], 'strict'); ?>><?php esc_html_e('Strict (Recommended to secure logins)', 'fingerprint-
|
|
402
|
-
<option value="balanced" <?php selected($effective['admin']['profile'], 'balanced'); ?>><?php esc_html_e('Balanced', 'fingerprint-
|
|
406
|
+
<option value="strict" <?php selected($effective['admin']['profile'], 'strict'); ?>><?php esc_html_e('Strict (Recommended to secure logins)', 'fingerprint-anti-bot'); ?></option>
|
|
407
|
+
<option value="balanced" <?php selected($effective['admin']['profile'], 'balanced'); ?>><?php esc_html_e('Balanced', 'fingerprint-anti-bot'); ?></option>
|
|
403
408
|
</select>
|
|
404
409
|
</td>
|
|
405
410
|
</tr>
|
|
406
411
|
<tr>
|
|
407
|
-
<th scope="row"><label for="api_profile"><?php esc_html_e('REST API (/wp-json/)', 'fingerprint-
|
|
412
|
+
<th scope="row"><label for="api_profile"><?php esc_html_e('REST API (/wp-json/)', 'fingerprint-anti-bot'); ?></label></th>
|
|
408
413
|
<td>
|
|
409
414
|
<select name="api_profile" id="api_profile">
|
|
410
|
-
<option value="api" <?php selected($effective['api']['profile'], 'api'); ?>><?php esc_html_e('API (JSON challenges & machine PoW)', 'fingerprint-
|
|
411
|
-
<option value="strict" <?php selected($effective['api']['profile'], 'strict'); ?>><?php esc_html_e('Strict', 'fingerprint-
|
|
415
|
+
<option value="api" <?php selected($effective['api']['profile'], 'api'); ?>><?php esc_html_e('API (JSON challenges & machine PoW)', 'fingerprint-anti-bot'); ?></option>
|
|
416
|
+
<option value="strict" <?php selected($effective['api']['profile'], 'strict'); ?>><?php esc_html_e('Strict', 'fingerprint-anti-bot'); ?></option>
|
|
412
417
|
</select>
|
|
413
418
|
</td>
|
|
414
419
|
</tr>
|
|
@@ -416,54 +421,54 @@ function fingerprint_render_admin_page(): void {
|
|
|
416
421
|
|
|
417
422
|
<hr>
|
|
418
423
|
|
|
419
|
-
<h3><?php esc_html_e('2. Action Thresholds (Frontend)', 'fingerprint-
|
|
424
|
+
<h3><?php esc_html_e('2. Action Thresholds (Frontend)', 'fingerprint-anti-bot'); ?></h3>
|
|
420
425
|
<table class="form-table">
|
|
421
426
|
<tr>
|
|
422
|
-
<th scope="row"><?php esc_html_e('Suspicion Score Thresholds (0 - 100)', 'fingerprint-
|
|
427
|
+
<th scope="row"><?php esc_html_e('Suspicion Score Thresholds (0 - 100)', 'fingerprint-anti-bot'); ?></th>
|
|
423
428
|
<td>
|
|
424
|
-
<label><?php esc_html_e('Low (Initial challenge):', 'fingerprint-
|
|
429
|
+
<label><?php esc_html_e('Low (Initial challenge):', 'fingerprint-anti-bot'); ?>
|
|
425
430
|
<input type="number" name="frontend_threshold_low" value="<?php echo esc_attr((string)($frontendConfig['thresholds']['low'] ?? 20)); ?>" min="1" max="50" style="width:80px;">
|
|
426
431
|
</label><br><br>
|
|
427
|
-
<label><?php esc_html_e('Medium (Hardened challenge):', 'fingerprint-
|
|
432
|
+
<label><?php esc_html_e('Medium (Hardened challenge):', 'fingerprint-anti-bot'); ?>
|
|
428
433
|
<input type="number" name="frontend_threshold_medium" value="<?php echo esc_attr((string)($frontendConfig['thresholds']['medium'] ?? 45)); ?>" min="10" max="75" style="width:80px;">
|
|
429
434
|
</label><br><br>
|
|
430
|
-
<label><?php esc_html_e('High (Heavy Proof-of-Work):', 'fingerprint-
|
|
435
|
+
<label><?php esc_html_e('High (Heavy Proof-of-Work):', 'fingerprint-anti-bot'); ?>
|
|
431
436
|
<input type="number" name="frontend_threshold_high" value="<?php echo esc_attr((string)($frontendConfig['thresholds']['high'] ?? 75)); ?>" min="30" max="95" style="width:80px;">
|
|
432
437
|
</label><br><br>
|
|
433
|
-
<label><?php esc_html_e('Block (Immediate 403 Forbidden):', 'fingerprint-
|
|
438
|
+
<label><?php esc_html_e('Block (Immediate 403 Forbidden):', 'fingerprint-anti-bot'); ?>
|
|
434
439
|
<input type="number" name="frontend_threshold_block" value="<?php echo esc_attr((string)($frontendConfig['thresholds']['block'] ?? 95)); ?>" min="50" max="100" style="width:80px;">
|
|
435
440
|
</label>
|
|
436
441
|
</td>
|
|
437
442
|
</tr>
|
|
438
443
|
<tr>
|
|
439
|
-
<th scope="row"><?php esc_html_e('Advanced Behaviors', 'fingerprint-
|
|
444
|
+
<th scope="row"><?php esc_html_e('Advanced Behaviors', 'fingerprint-anti-bot'); ?></th>
|
|
440
445
|
<td>
|
|
441
446
|
<label>
|
|
442
447
|
<input type="checkbox" name="frontend_challenge_new" value="1" <?php checked(!empty($frontendConfig['challengeNewDevices'])); ?>>
|
|
443
|
-
<?php esc_html_e('Automatically challenge unknown new devices (without device_id cookie)', 'fingerprint-
|
|
448
|
+
<?php esc_html_e('Automatically challenge unknown new devices (without device_id cookie)', 'fingerprint-anti-bot'); ?>
|
|
444
449
|
</label><br>
|
|
445
450
|
<label>
|
|
446
451
|
<input type="checkbox" name="detect_injections" value="1" <?php checked(!empty($frontendConfig['honeypot']['detectInjections'])); ?>>
|
|
447
|
-
<?php esc_html_e('Enable recursive WAF inspection (SQL, NoSQL, Log4j, Traversal in GET/POST)', 'fingerprint-
|
|
452
|
+
<?php esc_html_e('Enable recursive WAF inspection (SQL, NoSQL, Log4j, Traversal in GET/POST)', 'fingerprint-anti-bot'); ?>
|
|
448
453
|
</label><br>
|
|
449
454
|
<label>
|
|
450
455
|
<input type="checkbox" name="frontend_verbose" value="1" <?php checked(!empty($frontendConfig['verbose'])); ?>>
|
|
451
|
-
<?php esc_html_e('Verbose mode in PHP logs (Debugging)', 'fingerprint-
|
|
456
|
+
<?php esc_html_e('Verbose mode in PHP logs (Debugging)', 'fingerprint-anti-bot'); ?>
|
|
452
457
|
</label>
|
|
453
458
|
</td>
|
|
454
459
|
</tr>
|
|
455
460
|
</table>
|
|
456
461
|
|
|
457
|
-
<?php submit_button(esc_html__('Save Changes', 'fingerprint-
|
|
462
|
+
<?php submit_button(esc_html__('Save Changes', 'fingerprint-anti-bot'), 'primary', 'fingerprint_save_settings'); ?>
|
|
458
463
|
</form>
|
|
459
464
|
|
|
460
465
|
<hr>
|
|
461
466
|
<form method="post" action="" style="margin-top:16px;">
|
|
462
467
|
<?php wp_nonce_field('fingerprint_clear_nonce', 'fingerprint_nonce_clear'); ?>
|
|
463
468
|
<p>
|
|
464
|
-
<strong><?php esc_html_e('Store Maintenance:', 'fingerprint-
|
|
465
|
-
<button type="submit" name="fingerprint_clear_store" class="button button-secondary" onclick="return confirm('<?php echo esc_js(__('Purge all stored sessions and nonces?', 'fingerprint-
|
|
466
|
-
<?php esc_html_e('Clear SQL cache table ($wpdb)', 'fingerprint-
|
|
469
|
+
<strong><?php esc_html_e('Store Maintenance:', 'fingerprint-anti-bot'); ?></strong>
|
|
470
|
+
<button type="submit" name="fingerprint_clear_store" class="button button-secondary" onclick="return confirm('<?php echo esc_js(__('Purge all stored sessions and nonces?', 'fingerprint-anti-bot')); ?>');">
|
|
471
|
+
<?php esc_html_e('Clear SQL cache table ($wpdb)', 'fingerprint-anti-bot'); ?>
|
|
467
472
|
</button>
|
|
468
473
|
</p>
|
|
469
474
|
</form>
|
|
@@ -471,49 +476,49 @@ function fingerprint_render_admin_page(): void {
|
|
|
471
476
|
|
|
472
477
|
<!-- TAB 2 : VUE DÉTAILLÉE DES MÉTRIQUES -->
|
|
473
478
|
<div id="tab-metrics" class="fingerprint-tab-content" style="display:none;background:#fff;padding:20px;border:1px solid #ccd0d4;border-top:none;">
|
|
474
|
-
<h3><?php esc_html_e('Behavioral & Transport Indicator Weights (Active Frontend Profile)', 'fingerprint-
|
|
475
|
-
<p class="description"><?php echo wp_kses_post(__('The final score of each request is computed using the weighted sum: <code>Score = Σ (Metric × Weight)</code>.', 'fingerprint-
|
|
479
|
+
<h3><?php esc_html_e('Behavioral & Transport Indicator Weights (Active Frontend Profile)', 'fingerprint-anti-bot'); ?></h3>
|
|
480
|
+
<p class="description"><?php echo wp_kses_post(__('The final score of each request is computed using the weighted sum: <code>Score = Σ (Metric × Weight)</code>.', 'fingerprint-anti-bot')); ?></p>
|
|
476
481
|
|
|
477
482
|
<form method="post" action="">
|
|
478
483
|
<?php wp_nonce_field('fingerprint_settings_nonce', 'fingerprint_nonce'); ?>
|
|
479
484
|
<table class="wp-list-table widefat fixed striped">
|
|
480
485
|
<thead>
|
|
481
486
|
<tr>
|
|
482
|
-
<th style="width:280px;"><?php esc_html_e('Indicator / Metric', 'fingerprint-
|
|
483
|
-
<th style="width:120px;"><?php esc_html_e('Current Weight', 'fingerprint-
|
|
484
|
-
<th><?php esc_html_e('Description & Detection Role', 'fingerprint-
|
|
487
|
+
<th style="width:280px;"><?php esc_html_e('Indicator / Metric', 'fingerprint-anti-bot'); ?></th>
|
|
488
|
+
<th style="width:120px;"><?php esc_html_e('Current Weight', 'fingerprint-anti-bot'); ?></th>
|
|
489
|
+
<th><?php esc_html_e('Description & Detection Role', 'fingerprint-anti-bot'); ?></th>
|
|
485
490
|
</tr>
|
|
486
491
|
</thead>
|
|
487
492
|
<tbody>
|
|
488
493
|
<?php
|
|
489
494
|
$metricDescriptions = [
|
|
490
|
-
'honeypotScore' => __('Triggering of invisible trap links, multi-framework honeypots, and injection probes.', 'fingerprint-
|
|
491
|
-
'headerAnomalyScore' => __('Missing, malformed, or out-of-order HTTP headers inconsistent with legitimate browsers.', 'fingerprint-
|
|
492
|
-
'tlsSpoofingScore' => __('Discrepancy between User-Agent and TLS cryptographic fingerprints (JA3/JA4, extensions, GREASE).', 'fingerprint-
|
|
493
|
-
'behaviorScore' => __('Dynamic biometrics: mouse movements, keystroke dynamics, and mobile touch anomalies.', 'fingerprint-
|
|
494
|
-
'requestPatternScore' => __('Velocity, robotic bursts, request standard deviation, and Benford\'s law statistical analysis.', 'fingerprint-
|
|
495
|
-
'inconsistencyScore' => __('Alteration or drift in the hardware fingerprint between visits with the same cookie.', 'fingerprint-
|
|
496
|
-
'subnetScore' => __('Aggregated IP reputation of the network subnet (/24 or /48) and nearby attacker density.', 'fingerprint-
|
|
497
|
-
'ipReputationScore' => __('Local historical reputation score of the client IP address with temporal decay over time.', 'fingerprint-
|
|
498
|
-
'renderingAnomalyScore' => __('Display rendering anomalies, V-Sync/FPS cadence, and OffscreenCanvas hooking.', 'fingerprint-
|
|
499
|
-
'protocolAnomalyScore' => __('Divergence in HTTP/2 and QUIC / HTTP/3 flow control frame settings.', 'fingerprint-
|
|
500
|
-
'quicAnomalyScore' => __('Anomalies in QUIC transport parameters (flow control windows, max streams, and control frame ordering).', 'fingerprint-
|
|
501
|
-
'tcpAnomalyScore' => __('Passive TCP/IP stack fingerprinting (SYN packet TTL, window size, MSS, options) vs declared operating system.', 'fingerprint-
|
|
502
|
-
'historyScore' => __('Suspicious rotation of multiple IP addresses associated with a single hardware identity.', 'fingerprint-
|
|
503
|
-
'rotationScore' => __('Rapid and abnormal modifications to the application stack.', 'fingerprint-
|
|
504
|
-
'botScore' => __('Detection of native automation attributes (navigator.webdriver, Chrome CDP).', 'fingerprint-
|
|
505
|
-
'cookieDroppingScore' => __('Detection of cookie deletion, dropping, or refusal between consecutive requests to bypass device identification.', 'fingerprint-
|
|
506
|
-
'threatIntelScore' => __('Correlation with known proxy IPs, Tor exit nodes, and federated threat intelligence blacklist.', 'fingerprint-
|
|
507
|
-
'clientHintsInconsistencyScore' => __('Discrepancies between standard User-Agent and Sec-CH-UA Client Hints headers (browser family, version drift).', 'fingerprint-
|
|
508
|
-
'clickVarianceScore' => __('Statistical analysis of click coordinate variance; flags unnaturally low pixel variance typical of click bots.', 'fingerprint-
|
|
509
|
-
'botnetClusterScore' => __('Clustering of volatile client requests sharing identical hardware signatures across distinct IP addresses.', 'fingerprint-
|
|
510
|
-
'timeInconsistencyScore' => __('Time delta between client timestamp and server reception to detect replay and automated delay attacks.', 'fingerprint-
|
|
511
|
-
'virtualizationScore' => __('Detection of headless browsers, virtual GPU renderers (SwiftShader, llvmpipe) and emulated display resolutions.', 'fingerprint-
|
|
512
|
-
'crossLayerInconsistencyScore' => __('Strict contradiction between layers (e.g. declared OS in User-Agent vs network TCP/IP stack OS).', 'fingerprint-
|
|
495
|
+
'honeypotScore' => __('Triggering of invisible trap links, multi-framework honeypots, and injection probes.', 'fingerprint-anti-bot'),
|
|
496
|
+
'headerAnomalyScore' => __('Missing, malformed, or out-of-order HTTP headers inconsistent with legitimate browsers.', 'fingerprint-anti-bot'),
|
|
497
|
+
'tlsSpoofingScore' => __('Discrepancy between User-Agent and TLS cryptographic fingerprints (JA3/JA4, extensions, GREASE).', 'fingerprint-anti-bot'),
|
|
498
|
+
'behaviorScore' => __('Dynamic biometrics: mouse movements, keystroke dynamics, and mobile touch anomalies.', 'fingerprint-anti-bot'),
|
|
499
|
+
'requestPatternScore' => __('Velocity, robotic bursts, request standard deviation, and Benford\'s law statistical analysis.', 'fingerprint-anti-bot'),
|
|
500
|
+
'inconsistencyScore' => __('Alteration or drift in the hardware fingerprint between visits with the same cookie.', 'fingerprint-anti-bot'),
|
|
501
|
+
'subnetScore' => __('Aggregated IP reputation of the network subnet (/24 or /48) and nearby attacker density.', 'fingerprint-anti-bot'),
|
|
502
|
+
'ipReputationScore' => __('Local historical reputation score of the client IP address with temporal decay over time.', 'fingerprint-anti-bot'),
|
|
503
|
+
'renderingAnomalyScore' => __('Display rendering anomalies, V-Sync/FPS cadence, and OffscreenCanvas hooking.', 'fingerprint-anti-bot'),
|
|
504
|
+
'protocolAnomalyScore' => __('Divergence in HTTP/2 and QUIC / HTTP/3 flow control frame settings.', 'fingerprint-anti-bot'),
|
|
505
|
+
'quicAnomalyScore' => __('Anomalies in QUIC transport parameters (flow control windows, max streams, and control frame ordering).', 'fingerprint-anti-bot'),
|
|
506
|
+
'tcpAnomalyScore' => __('Passive TCP/IP stack fingerprinting (SYN packet TTL, window size, MSS, options) vs declared operating system.', 'fingerprint-anti-bot'),
|
|
507
|
+
'historyScore' => __('Suspicious rotation of multiple IP addresses associated with a single hardware identity.', 'fingerprint-anti-bot'),
|
|
508
|
+
'rotationScore' => __('Rapid and abnormal modifications to the application stack.', 'fingerprint-anti-bot'),
|
|
509
|
+
'botScore' => __('Detection of native automation attributes (navigator.webdriver, Chrome CDP).', 'fingerprint-anti-bot'),
|
|
510
|
+
'cookieDroppingScore' => __('Detection of cookie deletion, dropping, or refusal between consecutive requests to bypass device identification.', 'fingerprint-anti-bot'),
|
|
511
|
+
'threatIntelScore' => __('Correlation with known proxy IPs, Tor exit nodes, and federated threat intelligence blacklist.', 'fingerprint-anti-bot'),
|
|
512
|
+
'clientHintsInconsistencyScore' => __('Discrepancies between standard User-Agent and Sec-CH-UA Client Hints headers (browser family, version drift).', 'fingerprint-anti-bot'),
|
|
513
|
+
'clickVarianceScore' => __('Statistical analysis of click coordinate variance; flags unnaturally low pixel variance typical of click bots.', 'fingerprint-anti-bot'),
|
|
514
|
+
'botnetClusterScore' => __('Clustering of volatile client requests sharing identical hardware signatures across distinct IP addresses.', 'fingerprint-anti-bot'),
|
|
515
|
+
'timeInconsistencyScore' => __('Time delta between client timestamp and server reception to detect replay and automated delay attacks.', 'fingerprint-anti-bot'),
|
|
516
|
+
'virtualizationScore' => __('Detection of headless browsers, virtual GPU renderers (SwiftShader, llvmpipe) and emulated display resolutions.', 'fingerprint-anti-bot'),
|
|
517
|
+
'crossLayerInconsistencyScore' => __('Strict contradiction between layers (e.g. declared OS in User-Agent vs network TCP/IP stack OS).', 'fingerprint-anti-bot'),
|
|
513
518
|
];
|
|
514
519
|
|
|
515
520
|
foreach ($frontendConfig['weights'] as $indicator => $weight):
|
|
516
|
-
$desc = $metricDescriptions[$indicator] ?? __('Behavioral suspicion indicator.', 'fingerprint-
|
|
521
|
+
$desc = $metricDescriptions[$indicator] ?? __('Behavioral suspicion indicator.', 'fingerprint-anti-bot');
|
|
517
522
|
?>
|
|
518
523
|
<tr>
|
|
519
524
|
<td><code><?php echo esc_html($indicator); ?></code></td>
|
|
@@ -526,15 +531,15 @@ function fingerprint_render_admin_page(): void {
|
|
|
526
531
|
</tbody>
|
|
527
532
|
</table>
|
|
528
533
|
<p style="margin-top:16px;">
|
|
529
|
-
<?php submit_button(esc_html__('Update Metric Weights', 'fingerprint-
|
|
534
|
+
<?php submit_button(esc_html__('Update Metric Weights', 'fingerprint-anti-bot'), 'primary', 'fingerprint_save_settings', false); ?>
|
|
530
535
|
</p>
|
|
531
536
|
</form>
|
|
532
537
|
</div>
|
|
533
538
|
|
|
534
539
|
<!-- TAB 3 : FLUX PROMETHEUS -->
|
|
535
540
|
<div id="tab-prometheus" class="fingerprint-tab-content" style="display:none;background:#fff;padding:20px;border:1px solid #ccd0d4;border-top:none;">
|
|
536
|
-
<h3><?php esc_html_e('Real-Time Prometheus Metrics', 'fingerprint-
|
|
537
|
-
<p class="description"><?php esc_html_e('Raw text format exported for scraping by Prometheus, Grafana Agent, or Datadog.', 'fingerprint-
|
|
541
|
+
<h3><?php esc_html_e('Real-Time Prometheus Metrics', 'fingerprint-anti-bot'); ?></h3>
|
|
542
|
+
<p class="description"><?php esc_html_e('Raw text format exported for scraping by Prometheus, Grafana Agent, or Datadog.', 'fingerprint-anti-bot'); ?></p>
|
|
538
543
|
<textarea readonly style="width:100%;height:380px;font-family:monospace;background:#f6f7f7;padding:12px;"><?php echo esc_textarea($prometheusRaw); ?></textarea>
|
|
539
544
|
</div>
|
|
540
545
|
</div>
|
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
msgid ""
|
|
2
2
|
msgstr ""
|
|
3
|
-
"Project-Id-Version: Fingerprint Anti-Bot 0.7.
|
|
3
|
+
"Project-Id-Version: Fingerprint Anti-Bot 0.7.4\n"
|
|
4
4
|
"Report-Msgid-Bugs-To: https://github.com/anonympins/fingerprint/issues\n"
|
|
5
5
|
"POT-Creation-Date: 2026-09-24 12:00+0000\n"
|
|
6
6
|
"PO-Revision-Date: 2026-09-24 12:00+0000\n"
|
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
msgid ""
|
|
2
2
|
msgstr ""
|
|
3
|
-
"Project-Id-Version: Fingerprint Anti-Bot 0.7.
|
|
3
|
+
"Project-Id-Version: Fingerprint Anti-Bot 0.7.4\n"
|
|
4
4
|
"Report-Msgid-Bugs-To: https://github.com/anonympins/fingerprint/issues\n"
|
|
5
5
|
"POT-Creation-Date: 2026-09-24 12:00+0000\n"
|
|
6
6
|
"PO-Revision-Date: 2026-09-24 12:00+0000\n"
|