@anonympins/fingerprint 0.7.0 → 0.7.2

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.
Files changed (66) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +1 -1
  3. package/composer.json +8 -1
  4. package/package.json +1 -1
  5. package/public/fingerprint-wordpress.zip +0 -0
  6. package/src/js/build-client.js +8 -10
  7. package/src/js/fingerprint.builder.js +37 -38
  8. package/src/js/fingerprint.client.js +1531 -1463
  9. package/src/js/fingerprint.client.obfuscated.js +1 -0
  10. package/src/js/fingerprint.js +190 -16
  11. package/src/js/fingerprint.utils.js +213 -213
  12. package/src/js/library.js +340 -376
  13. package/src/js/mongodb-store.js +1 -1
  14. package/src/js/optimization.worker.js +27 -27
  15. package/src/js/pow.solver.inline.js +154 -56
  16. package/src/js/pow.solver.js +180 -92
  17. package/src/js/pow.worker.js +48 -48
  18. package/src/js/redis-store.js +1 -1
  19. package/src/js/tests/fingerprint.client.init.test.js +146 -143
  20. package/src/js/tests/fingerprint.test.js +124 -10
  21. package/src/js/tests/ip-reputation.test.js +1 -0
  22. package/src/js/upow-model-task.js +14 -15
  23. package/src/php/AutoTuner.php +34 -34
  24. package/src/php/Challenge/ChallengeUtils.php +57 -11
  25. package/src/php/Config/SecurityProfiles.php +20 -0
  26. package/src/php/DirectFingerprint.php +190 -145
  27. package/src/php/FingerprintBuilder.php +29 -30
  28. package/src/php/FingerprintClient.php +147 -148
  29. package/src/php/FingerprintEngine.php +44 -17
  30. package/src/php/Ja3AnomalyDetector.php +33 -32
  31. package/src/php/Optimization/FunctionRegistry.php +7 -7
  32. package/src/php/Optimization/Optimization.php +24 -24
  33. package/src/php/Optimization/OptimizationOperators.php +26 -25
  34. package/src/php/Optimization/ProblemInitializers.php +52 -52
  35. package/src/php/ProblemManager.php +31 -34
  36. package/src/php/RequestContext.php +8 -1
  37. package/src/php/Store/IStore.php +7 -8
  38. package/src/php/Store/InMemoryStore.php +66 -66
  39. package/src/php/Store/MongoDbStore.php +5 -5
  40. package/src/php/Store/RedisStore.php +5 -5
  41. package/src/php/Store/StoreManager.php +35 -35
  42. package/src/php/Tests/ChallengeUtilsTest.php +453 -453
  43. package/src/php/Tests/DnsCircuitBreakerTest.php +105 -105
  44. package/src/php/Tests/FingerprintEngineTest.php +38 -0
  45. package/src/php/Tests/IpReputationTest.php +10 -0
  46. package/src/php/Tests/MaliciousPatternsTest.php +103 -103
  47. package/src/php/Tests/MetricsTest.php +97 -97
  48. package/src/php/Tests/ProblemManagerTest.php +376 -376
  49. package/src/php/Tests/QuicFingerprintTest.php +53 -53
  50. package/src/php/Tests/RequestUtilsTest.php +471 -471
  51. package/src/php/Tests/TLSClientHelloParserTest.php +177 -177
  52. package/src/php/Tests/config/ed25519_key.json +3 -3
  53. package/src/php/Utils/BlockList.php +99 -99
  54. package/src/php/Utils/Env.php +49 -49
  55. package/src/php/Utils/MaliciousPatterns.php +74 -74
  56. package/src/php/Utils/MetricsManager.php +209 -209
  57. package/src/php/Utils/RequestUtils.php +129 -7
  58. package/src/php/Utils/TLSClientHelloParser.php +369 -369
  59. package/src/php/WordPress/WpDbStore.php +155 -0
  60. package/src/php/WordPress/fingerprint-wordpress.php +554 -0
  61. package/src/php/WordPress/languages/fingerprint-wordpress-de_DE.mo +0 -0
  62. package/src/php/WordPress/languages/fingerprint-wordpress-de_DE.po +262 -0
  63. package/src/php/WordPress/languages/fingerprint-wordpress-fr_FR.mo +0 -0
  64. package/src/php/WordPress/languages/fingerprint-wordpress-fr_FR.po +268 -0
  65. package/src/php/WordPress/package.php +218 -0
  66. package/src/php/bin/auto-tune.php +118 -118
@@ -0,0 +1,155 @@
1
+ <?php
2
+
3
+ declare(strict_types=1);
4
+
5
+ namespace Anonympins\Fingerprint\WordPress;
6
+
7
+ use Anonympins\Fingerprint\Store\IStore;
8
+
9
+ // Polyfill pour ARRAY_A si chargé hors du cycle de vie standard de WordPress
10
+ if (!defined('ARRAY_A')) {
11
+ define('ARRAY_A', 'ARRAY_A');
12
+ }
13
+
14
+ /**
15
+ * Adaptateur IStore persistant pour WordPress exploitant l'objet $wpdb.
16
+ * Permet de stocker les sessions d'appareils, nonces et états de PoW
17
+ * sans dépendre d'une extension mémoire comme Redis ou APCu.
18
+ */
19
+ class WpDbStore implements IStore
20
+ {
21
+ /** @var \wpdb|object|null */
22
+ private $db;
23
+ private string $table;
24
+
25
+ public function __construct($db = null)
26
+ {
27
+ global $wpdb;
28
+ $this->db = $db ?? $wpdb;
29
+ $prefix = (is_object($this->db) && isset($this->db->prefix)) ? $this->db->prefix : 'wp_';
30
+ $this->table = $prefix . 'fingerprint_store';
31
+ }
32
+
33
+ /**
34
+ * Crée la table de stockage si elle n'existe pas encore.
35
+ */
36
+ public function ensureTable(): void
37
+ {
38
+ if (!$this->db || !method_exists($this->db, 'get_charset_collate')) {
39
+ return;
40
+ }
41
+
42
+ $charsetCollate = $this->db->get_charset_collate();
43
+ $sql = "CREATE TABLE IF NOT EXISTS {$this->table} (
44
+ `key_id` VARCHAR(191) NOT NULL,
45
+ `value` LONGTEXT NOT NULL,
46
+ `expires_at` BIGINT UNSIGNED NULL,
47
+ PRIMARY KEY (`key_id`),
48
+ KEY `expires_idx` (`expires_at`)
49
+ ) {$charsetCollate};";
50
+
51
+ // Chargement sécurisé de dbDelta si ABSPATH est présent
52
+ if (!function_exists('dbDelta') && defined('ABSPATH')) {
53
+ $upgradeFile = ABSPATH . 'wp-admin/includes/upgrade.php';
54
+ if (file_exists($upgradeFile)) {
55
+ require_once $upgradeFile;
56
+ }
57
+ }
58
+
59
+ if (function_exists('dbDelta')) {
60
+ dbDelta($sql);
61
+ } elseif (method_exists($this->db, 'query')) {
62
+ $this->db->query($sql);
63
+ }
64
+ }
65
+
66
+ public function get(string $key)
67
+ {
68
+ if (!$this->db || !method_exists($this->db, 'prepare')) {
69
+ return null;
70
+ }
71
+
72
+ $sql = $this->db->prepare(
73
+ "SELECT `value`, `expires_at` FROM {$this->table} WHERE `key_id` = %s",
74
+ $key
75
+ );
76
+ $outputType = defined('ARRAY_A') ? \ARRAY_A : 'ARRAY_A';
77
+ $row = $this->db->get_row($sql, $outputType);
78
+
79
+ if (!$row) {
80
+ return null;
81
+ }
82
+
83
+ if ($row['expires_at'] !== null && (int)$row['expires_at'] < time()) {
84
+ $this->delete($key);
85
+ return null;
86
+ }
87
+
88
+ $decoded = json_decode((string)$row['value'], true);
89
+ return (json_last_error() === JSON_ERROR_NONE) ? $decoded : $row['value'];
90
+ }
91
+
92
+ public function set(string $key, $value, ?int $ttl = null): void
93
+ {
94
+ if (!$this->db || !method_exists($this->db, 'replace')) {
95
+ return;
96
+ }
97
+
98
+ $expiresAt = ($ttl !== null && $ttl > 0) ? (time() + $ttl) : null;
99
+ $serialized = is_scalar($value) && !is_bool($value)
100
+ ? (string)$value
101
+ : json_encode($value, JSON_UNESCAPED_SLASHES);
102
+
103
+ $this->db->replace(
104
+ $this->table,
105
+ [
106
+ 'key_id' => $key,
107
+ 'value' => $serialized,
108
+ 'expires_at' => $expiresAt
109
+ ],
110
+ ['%s', '%s', $expiresAt !== null ? '%d' : null]
111
+ );
112
+ }
113
+
114
+ public function has(string $key): bool
115
+ {
116
+ return $this->get($key) !== null;
117
+ }
118
+
119
+ public function delete(string $key): void
120
+ {
121
+ if (!$this->db || !method_exists($this->db, 'delete')) {
122
+ return;
123
+ }
124
+
125
+ $this->db->delete(
126
+ $this->table,
127
+ ['key_id' => $key],
128
+ ['%s']
129
+ );
130
+ }
131
+
132
+ public function clear(): void
133
+ {
134
+ if (!$this->db || !method_exists($this->db, 'query')) {
135
+ return;
136
+ }
137
+ $this->db->query("TRUNCATE TABLE {$this->table}");
138
+ }
139
+
140
+ /**
141
+ * Nettoie les lignes expirées (appelé par le WP-Cron périodique).
142
+ */
143
+ public function pruneExpired(): int
144
+ {
145
+ if (!$this->db || !method_exists($this->db, 'prepare')) {
146
+ return 0;
147
+ }
148
+
149
+ $now = time();
150
+ $deleted = $this->db->query(
151
+ $this->db->prepare("DELETE FROM {$this->table} WHERE `expires_at` IS NOT NULL AND `expires_at` < %d", $now)
152
+ );
153
+ return is_numeric($deleted) ? (int)$deleted : 0;
154
+ }
155
+ }