@anonympins/fingerprint 0.7.4 → 0.8.0
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 +59 -0
- package/README.md +1 -1
- package/package.json +1 -1
- package/public/anonympins-bot-mitigation-pow.zip +0 -0
- package/src/js/dynamic-wasm.js +218 -218
- package/src/js/fingerprint.client.js +1784 -1738
- package/src/js/fingerprint.client.obfuscated.js +1 -1
- package/src/js/fingerprint.js +489 -99
- package/src/js/fingerprint.utils.js +252 -2
- package/src/js/pow.worker.js +2 -2
- package/src/js/tests/cross_parity.test.js +3 -3
- package/src/js/tests/dns-circuit-breaker.test.js +6 -6
- package/src/js/tests/dynamic-wasm.test.js +77 -77
- package/src/js/tests/fingerprint.builder.test.js +76 -78
- package/src/js/tests/fingerprint.client.init.test.js +78 -0
- package/src/js/tests/fingerprint.client.test.js +16 -17
- package/src/js/tests/fingerprint.test.js +37 -12
- package/src/js/tests/ja3AnomalyDetector.test.js +135 -136
- package/src/js/tests/library.test.js +94 -95
- package/src/js/tests/obfuscation.test.js +8 -8
- package/src/js/tests/quicFingerprint.test.js +47 -0
- package/src/js/tests/tcpFingerprint.test.js +4 -4
- package/src/js/tests/threatIntel.test.js +40 -1
- package/src/js/upow-model-task.js +155 -112
- package/src/php/Challenge/ChallengeUtils.php +392 -86
- package/src/php/Config/SecurityProfiles.php +79 -61
- package/src/php/DirectFingerprint.php +55 -8
- package/src/php/FingerprintBuilder.php +13 -13
- package/src/php/FingerprintClient.php +6 -6
- package/src/php/FingerprintEngine.php +2122 -1690
- package/src/php/Ja3AnomalyDetector.php +22 -22
- package/src/php/Optimization/FunctionRegistry.php +4 -4
- package/src/php/Optimization/Optimization.php +6 -6
- package/src/php/RequestContext.php +11 -11
- package/src/php/Store/InMemoryStore.php +96 -66
- package/src/php/Store/MongoDbStore.php +2 -2
- package/src/php/Store/RedisStore.php +1 -1
- package/src/php/Store/StoreManager.php +48 -35
- package/src/php/Tests/ChallengeUtilsTest.php +31 -0
- package/src/php/Tests/DnsCircuitBreakerTest.php +105 -105
- package/src/php/Tests/FingerprintClientTest.php +70 -70
- package/src/php/Tests/PowTest.php +37 -39
- package/src/php/Tests/QuicFingerprintTest.php +115 -53
- package/src/php/Tests/ThreatIntelTest.php +34 -0
- package/src/php/Utils/BigInt.php +202 -202
- package/src/php/Utils/BlockList.php +13 -13
- package/src/php/Utils/Logger.php +19 -1
- package/src/php/Utils/MaliciousPatterns.php +6 -6
- package/src/php/Utils/MetricsManager.php +209 -209
- package/src/php/Utils/RequestUtils.php +362 -1
- package/src/php/Utils/TLSClientHelloParser.php +385 -369
- package/src/php/WordPress/WpDbStore.php +7 -7
- package/src/php/WordPress/anonympins-bot-mitigation-pow.php +1121 -0
- package/src/php/WordPress/fingerprint-anti-bot.php +0 -559
- package/src/php/WordPress/languages/anonympins-bot-mitigation-pow-fr_FR.mo +0 -0
- package/src/php/WordPress/languages/anonympins-bot-mitigation-pow-fr_FR.po +232 -0
- package/src/php/WordPress/languages/fingerprint-wordpress-de_DE.mo +0 -0
- package/src/php/WordPress/languages/fingerprint-wordpress-de_DE.po +297 -261
- package/src/php/WordPress/languages/fingerprint-wordpress-fr_FR.mo +0 -0
- package/src/php/WordPress/languages/fingerprint-wordpress-fr_FR.po +348 -267
- package/src/php/WordPress/package.php +80 -101
- package/src/php/WordPress/readme.txt +21 -5
- package/src/php/bin/auto-tune.php +1 -1
- package/public/fingerprint-anti-bot.zip +0 -0
package/src/php/Utils/BigInt.php
CHANGED
|
@@ -1,203 +1,203 @@
|
|
|
1
|
-
<?php
|
|
2
|
-
|
|
3
|
-
declare(strict_types=1);
|
|
4
|
-
|
|
5
|
-
namespace Anonympins\Fingerprint\Utils;
|
|
6
|
-
|
|
7
|
-
class BigInt
|
|
8
|
-
{
|
|
9
|
-
private static ?bool $useGmp = null;
|
|
10
|
-
/** @var \GMP|string */
|
|
11
|
-
private $value;
|
|
12
|
-
|
|
13
|
-
private static function useGmp(): bool
|
|
14
|
-
{
|
|
15
|
-
if (self::$useGmp === null) {
|
|
16
|
-
self::$useGmp = extension_loaded('gmp');
|
|
17
|
-
}
|
|
18
|
-
return self::$useGmp;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* @param \GMP|string|int $number
|
|
23
|
-
*/
|
|
24
|
-
public function __construct($number)
|
|
25
|
-
{
|
|
26
|
-
if (self::useGmp()) {
|
|
27
|
-
if ($number instanceof \GMP) {
|
|
28
|
-
$this->value = $number;
|
|
29
|
-
} else {
|
|
30
|
-
$str = (string)$number;
|
|
31
|
-
if (($dot = strpos($str, '.')) !== false) {
|
|
32
|
-
$str = substr($str, 0, $dot);
|
|
33
|
-
}
|
|
34
|
-
$this->value = gmp_init($str);
|
|
35
|
-
}
|
|
36
|
-
} else {
|
|
37
|
-
if ($number instanceof BigInt) {
|
|
38
|
-
$this->value = $number->value;
|
|
39
|
-
} else {
|
|
40
|
-
$str = (string)$number;
|
|
41
|
-
if (($dot = strpos($str, '.')) !== false) {
|
|
42
|
-
$str = substr($str, 0, $dot);
|
|
43
|
-
}
|
|
44
|
-
$this->value = $str;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
*
|
|
51
|
-
*/
|
|
52
|
-
public static function fromHex(string $hex): BigInt
|
|
53
|
-
{
|
|
54
|
-
$hex = trim(strtolower($hex));
|
|
55
|
-
if (substr($hex, 0, 2) === '0x') {
|
|
56
|
-
$hex = substr($hex, 2);
|
|
57
|
-
}
|
|
58
|
-
if (self::useGmp()) {
|
|
59
|
-
return new self(gmp_init($hex, 16));
|
|
60
|
-
} else {
|
|
61
|
-
$dec = '0';
|
|
62
|
-
$len = strlen($hex);
|
|
63
|
-
for ($i = 0; $i < $len; $i++) {
|
|
64
|
-
$dec = bcadd(bcmul($dec, '16', 0), (string)hexdec($hex[$i]), 0);
|
|
65
|
-
}
|
|
66
|
-
return new self($dec);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
*
|
|
72
|
-
* @return int < 0
|
|
73
|
-
*/
|
|
74
|
-
public function compareTo(BigInt $other): int
|
|
75
|
-
{
|
|
76
|
-
if (self::useGmp()) {
|
|
77
|
-
return gmp_cmp($this->value, $other->value);
|
|
78
|
-
} else {
|
|
79
|
-
return bccomp($this->value, $other->value, 0);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
*
|
|
85
|
-
*/
|
|
86
|
-
public function shiftLeft(int $bits): BigInt
|
|
87
|
-
{
|
|
88
|
-
if (self::useGmp()) {
|
|
89
|
-
return new self(gmp_mul($this->value, gmp_pow("2", $bits)));
|
|
90
|
-
} else {
|
|
91
|
-
return new self(bcmul($this->value, bcpow("2", (string)$bits, 0), 0));
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
*
|
|
97
|
-
*/
|
|
98
|
-
public function shiftRight(int $bits): BigInt
|
|
99
|
-
{
|
|
100
|
-
if (self::useGmp()) {
|
|
101
|
-
return new self(gmp_div_q($this->value, gmp_pow("2", $bits)));
|
|
102
|
-
} else {
|
|
103
|
-
return new self(bcdiv($this->value, bcpow("2", (string)$bits, 0), 0));
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
*
|
|
109
|
-
*/
|
|
110
|
-
public function __toString(): string
|
|
111
|
-
{
|
|
112
|
-
if (self::useGmp()) {
|
|
113
|
-
return gmp_strval($this->value);
|
|
114
|
-
} else {
|
|
115
|
-
return $this->value;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
*
|
|
121
|
-
*/
|
|
122
|
-
public function toHex(): string
|
|
123
|
-
{
|
|
124
|
-
if (self::useGmp()) {
|
|
125
|
-
return gmp_strval($this->value, 16);
|
|
126
|
-
} else {
|
|
127
|
-
$hex = '';
|
|
128
|
-
$dec = $this->value;
|
|
129
|
-
while (bccomp($dec, '0', 0) > 0) {
|
|
130
|
-
$rem = bcmod($dec, '16', 0);
|
|
131
|
-
$hex = dechex((int)$rem) . $hex;
|
|
132
|
-
$dec = bcdiv($dec, '16', 0);
|
|
133
|
-
}
|
|
134
|
-
return $hex ?: '0';
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
*
|
|
140
|
-
*/
|
|
141
|
-
public static function pow(int $base, int $exp): BigInt
|
|
142
|
-
{
|
|
143
|
-
if (self::useGmp()) {
|
|
144
|
-
return new self(gmp_pow((string)$base, $exp));
|
|
145
|
-
} else {
|
|
146
|
-
return new self(bcpow((string)$base, (string)$exp, 0));
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
*
|
|
152
|
-
*/
|
|
153
|
-
public function sub(BigInt $other): BigInt
|
|
154
|
-
{
|
|
155
|
-
if (self::useGmp()) {
|
|
156
|
-
return new self(gmp_sub($this->value, $other->value));
|
|
157
|
-
} else {
|
|
158
|
-
return new self(bcsub($this->value, $other->value, 0));
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Computes ($this ^ $exponent) % $modulus
|
|
164
|
-
*/
|
|
165
|
-
public function modPow(BigInt $exponent, BigInt $modulus): BigInt
|
|
166
|
-
{
|
|
167
|
-
if (self::useGmp()) {
|
|
168
|
-
return new self(gmp_powm($this->value, $exponent->value, $modulus->value));
|
|
169
|
-
} else {
|
|
170
|
-
return new self(bcpowmod((string)$this->value, (string)$exponent->value, (string)$modulus->value, 0));
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Computes $this % $modulus
|
|
176
|
-
*/
|
|
177
|
-
public function mod(BigInt $modulus): BigInt
|
|
178
|
-
{
|
|
179
|
-
if (self::useGmp()) {
|
|
180
|
-
return new self(gmp_mod($this->value, $modulus->value));
|
|
181
|
-
} else {
|
|
182
|
-
return new self(bcmod((string)$this->value, (string)$modulus->value, 0));
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
public function add(BigInt $other): BigInt
|
|
187
|
-
{
|
|
188
|
-
if (self::useGmp()) {
|
|
189
|
-
return new self(gmp_add($this->value, $other->value));
|
|
190
|
-
} else {
|
|
191
|
-
return new self(bcadd((string)$this->value, (string)$other->value, 0));
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
public function mul(BigInt $other): BigInt
|
|
196
|
-
{
|
|
197
|
-
if (self::useGmp()) {
|
|
198
|
-
return new self(gmp_mul($this->value, $other->value));
|
|
199
|
-
} else {
|
|
200
|
-
return new self(bcmul((string)$this->value, (string)$other->value, 0));
|
|
201
|
-
}
|
|
202
|
-
}
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
declare(strict_types=1);
|
|
4
|
+
|
|
5
|
+
namespace Anonympins\Fingerprint\Utils;
|
|
6
|
+
|
|
7
|
+
class BigInt
|
|
8
|
+
{
|
|
9
|
+
private static ?bool $useGmp = null;
|
|
10
|
+
/** @var \GMP|string */
|
|
11
|
+
private $value;
|
|
12
|
+
|
|
13
|
+
private static function useGmp(): bool
|
|
14
|
+
{
|
|
15
|
+
if (self::$useGmp === null) {
|
|
16
|
+
self::$useGmp = extension_loaded('gmp');
|
|
17
|
+
}
|
|
18
|
+
return self::$useGmp;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @param \GMP|string|int $number Initial number.
|
|
23
|
+
*/
|
|
24
|
+
public function __construct($number)
|
|
25
|
+
{
|
|
26
|
+
if (self::useGmp()) {
|
|
27
|
+
if ($number instanceof \GMP) {
|
|
28
|
+
$this->value = $number;
|
|
29
|
+
} else {
|
|
30
|
+
$str = (string)$number;
|
|
31
|
+
if (($dot = strpos($str, '.')) !== false) {
|
|
32
|
+
$str = substr($str, 0, $dot);
|
|
33
|
+
}
|
|
34
|
+
$this->value = gmp_init($str);
|
|
35
|
+
}
|
|
36
|
+
} else {
|
|
37
|
+
if ($number instanceof BigInt) {
|
|
38
|
+
$this->value = $number->value;
|
|
39
|
+
} else {
|
|
40
|
+
$str = (string)$number;
|
|
41
|
+
if (($dot = strpos($str, '.')) !== false) {
|
|
42
|
+
$str = substr($str, 0, $dot);
|
|
43
|
+
}
|
|
44
|
+
$this->value = $str;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Creates an instance from a hexadecimal string.
|
|
51
|
+
*/
|
|
52
|
+
public static function fromHex(string $hex): BigInt
|
|
53
|
+
{
|
|
54
|
+
$hex = trim(strtolower($hex));
|
|
55
|
+
if (substr($hex, 0, 2) === '0x') {
|
|
56
|
+
$hex = substr($hex, 2);
|
|
57
|
+
}
|
|
58
|
+
if (self::useGmp()) {
|
|
59
|
+
return new self(gmp_init($hex, 16));
|
|
60
|
+
} else {
|
|
61
|
+
$dec = '0';
|
|
62
|
+
$len = strlen($hex);
|
|
63
|
+
for ($i = 0; $i < $len; $i++) {
|
|
64
|
+
$dec = bcadd(bcmul($dec, '16', 0), (string)hexdec($hex[$i]), 0);
|
|
65
|
+
}
|
|
66
|
+
return new self($dec);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Compares this instance with another.
|
|
72
|
+
* @return int < 0 if this < other, 0 if this == other, > 0 if this > other.
|
|
73
|
+
*/
|
|
74
|
+
public function compareTo(BigInt $other): int
|
|
75
|
+
{
|
|
76
|
+
if (self::useGmp()) {
|
|
77
|
+
return gmp_cmp($this->value, $other->value);
|
|
78
|
+
} else {
|
|
79
|
+
return bccomp($this->value, $other->value, 0);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Performs bitwise left shift (<<).
|
|
85
|
+
*/
|
|
86
|
+
public function shiftLeft(int $bits): BigInt
|
|
87
|
+
{
|
|
88
|
+
if (self::useGmp()) {
|
|
89
|
+
return new self(gmp_mul($this->value, gmp_pow("2", $bits)));
|
|
90
|
+
} else {
|
|
91
|
+
return new self(bcmul($this->value, bcpow("2", (string)$bits, 0), 0));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Performs bitwise right shift (>>).
|
|
97
|
+
*/
|
|
98
|
+
public function shiftRight(int $bits): BigInt
|
|
99
|
+
{
|
|
100
|
+
if (self::useGmp()) {
|
|
101
|
+
return new self(gmp_div_q($this->value, gmp_pow("2", $bits)));
|
|
102
|
+
} else {
|
|
103
|
+
return new self(bcdiv($this->value, bcpow("2", (string)$bits, 0), 0));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Returns the string representation.
|
|
109
|
+
*/
|
|
110
|
+
public function __toString(): string
|
|
111
|
+
{
|
|
112
|
+
if (self::useGmp()) {
|
|
113
|
+
return gmp_strval($this->value);
|
|
114
|
+
} else {
|
|
115
|
+
return $this->value;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Returns the hexadecimal representation.
|
|
121
|
+
*/
|
|
122
|
+
public function toHex(): string
|
|
123
|
+
{
|
|
124
|
+
if (self::useGmp()) {
|
|
125
|
+
return gmp_strval($this->value, 16);
|
|
126
|
+
} else {
|
|
127
|
+
$hex = '';
|
|
128
|
+
$dec = $this->value;
|
|
129
|
+
while (bccomp($dec, '0', 0) > 0) {
|
|
130
|
+
$rem = bcmod($dec, '16', 0);
|
|
131
|
+
$hex = dechex((int)$rem) . $hex;
|
|
132
|
+
$dec = bcdiv($dec, '16', 0);
|
|
133
|
+
}
|
|
134
|
+
return $hex ?: '0';
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Creates an instance from a power of two.
|
|
140
|
+
*/
|
|
141
|
+
public static function pow(int $base, int $exp): BigInt
|
|
142
|
+
{
|
|
143
|
+
if (self::useGmp()) {
|
|
144
|
+
return new self(gmp_pow((string)$base, $exp));
|
|
145
|
+
} else {
|
|
146
|
+
return new self(bcpow((string)$base, (string)$exp, 0));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Subtracts another BigInt.
|
|
152
|
+
*/
|
|
153
|
+
public function sub(BigInt $other): BigInt
|
|
154
|
+
{
|
|
155
|
+
if (self::useGmp()) {
|
|
156
|
+
return new self(gmp_sub($this->value, $other->value));
|
|
157
|
+
} else {
|
|
158
|
+
return new self(bcsub($this->value, $other->value, 0));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Computes ($this ^ $exponent) % $modulus
|
|
164
|
+
*/
|
|
165
|
+
public function modPow(BigInt $exponent, BigInt $modulus): BigInt
|
|
166
|
+
{
|
|
167
|
+
if (self::useGmp()) {
|
|
168
|
+
return new self(gmp_powm($this->value, $exponent->value, $modulus->value));
|
|
169
|
+
} else {
|
|
170
|
+
return new self(bcpowmod((string)$this->value, (string)$exponent->value, (string)$modulus->value, 0));
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Computes $this % $modulus
|
|
176
|
+
*/
|
|
177
|
+
public function mod(BigInt $modulus): BigInt
|
|
178
|
+
{
|
|
179
|
+
if (self::useGmp()) {
|
|
180
|
+
return new self(gmp_mod($this->value, $modulus->value));
|
|
181
|
+
} else {
|
|
182
|
+
return new self(bcmod((string)$this->value, (string)$modulus->value, 0));
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
public function add(BigInt $other): BigInt
|
|
187
|
+
{
|
|
188
|
+
if (self::useGmp()) {
|
|
189
|
+
return new self(gmp_add($this->value, $other->value));
|
|
190
|
+
} else {
|
|
191
|
+
return new self(bcadd((string)$this->value, (string)$other->value, 0));
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
public function mul(BigInt $other): BigInt
|
|
196
|
+
{
|
|
197
|
+
if (self::useGmp()) {
|
|
198
|
+
return new self(gmp_mul($this->value, $other->value));
|
|
199
|
+
} else {
|
|
200
|
+
return new self(bcmul((string)$this->value, (string)$other->value, 0));
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
203
|
}
|
|
@@ -5,18 +5,18 @@ declare(strict_types=1);
|
|
|
5
5
|
namespace Anonympins\Fingerprint\Utils;
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* PHP implementation of an IP/CIDR blocklist, similar to Node.js `net.BlockList`.
|
|
9
9
|
*/
|
|
10
10
|
class BlockList
|
|
11
11
|
{
|
|
12
12
|
/**
|
|
13
|
-
* @var array<string>
|
|
13
|
+
* @var array<string> List of IPs or CIDR blocks to filter.
|
|
14
14
|
*/
|
|
15
15
|
private array $entries = [];
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
19
|
-
* @param string $entry
|
|
18
|
+
* Adds an IP address or CIDR range to the list.
|
|
19
|
+
* @param string $entry An IP address (e.g. '192.168.1.1') or CIDR range (e.g. '192.168.1.0/24').
|
|
20
20
|
* @return void
|
|
21
21
|
*/
|
|
22
22
|
public function add(string $entry): void
|
|
@@ -25,20 +25,20 @@ class BlockList
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
*
|
|
29
|
-
* @param string $ip
|
|
30
|
-
* @return bool True
|
|
28
|
+
* Checks if an IP address exists in the blocklist.
|
|
29
|
+
* @param string $ip The IP address to verify.
|
|
30
|
+
* @return bool True if the IP matches, false otherwise.
|
|
31
31
|
*/
|
|
32
32
|
public function check(string $ip): bool
|
|
33
33
|
{
|
|
34
34
|
foreach ($this->entries as $entry) {
|
|
35
35
|
if (str_contains($entry, '/')) {
|
|
36
|
-
//
|
|
36
|
+
// CIDR range
|
|
37
37
|
if ($this->ipInCidr($ip, $entry)) {
|
|
38
38
|
return true;
|
|
39
39
|
}
|
|
40
40
|
} else {
|
|
41
|
-
//
|
|
41
|
+
// Direct IP match
|
|
42
42
|
if ($ip === $entry) {
|
|
43
43
|
return true;
|
|
44
44
|
}
|
|
@@ -48,10 +48,10 @@ class BlockList
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
|
-
*
|
|
52
|
-
* @param string $ip
|
|
53
|
-
* @param string $cidr
|
|
54
|
-
* @return bool True
|
|
51
|
+
* Checks if an IP address belongs to a given CIDR range.
|
|
52
|
+
* @param string $ip The IP address to verify.
|
|
53
|
+
* @param string $cidr The CIDR range (e.g. '192.168.1.0/24').
|
|
54
|
+
* @return bool True if the IP is within the range, false otherwise.
|
|
55
55
|
*/
|
|
56
56
|
private function ipInCidr(string $ip, string $cidr): bool
|
|
57
57
|
{
|
package/src/php/Utils/Logger.php
CHANGED
|
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
|
|
5
5
|
namespace Anonympins\Fingerprint\Utils;
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* A simple logger wrapper to forward data to a callback function.
|
|
9
9
|
*/
|
|
10
10
|
class Logger
|
|
11
11
|
{
|
|
@@ -14,11 +14,29 @@ class Logger
|
|
|
14
14
|
*/
|
|
15
15
|
private $callback;
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Creates a new Logger instance with the given callback.
|
|
19
|
+
* The callback will be invoked with a single log entry array argument
|
|
20
|
+
* each time `log()` is called.
|
|
21
|
+
*
|
|
22
|
+
* @param callable $callback The callback used to process log entries.
|
|
23
|
+
*/
|
|
17
24
|
public function __construct(callable $callback)
|
|
18
25
|
{
|
|
19
26
|
$this->callback = $callback;
|
|
20
27
|
}
|
|
21
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Emits a log entry by merging the provided data with a type and a
|
|
31
|
+
* millisecond-precision timestamp, then forwarding it to the callback.
|
|
32
|
+
* Note: the `$level` parameter is currently accepted but not included
|
|
33
|
+
* in the emitted log entry.
|
|
34
|
+
*
|
|
35
|
+
* @param string $level The log level (e.g. "info", "warning", "error").
|
|
36
|
+
* @param string $type The log entry type/category.
|
|
37
|
+
* @param array $data Additional data to include in the log entry.
|
|
38
|
+
* @return void
|
|
39
|
+
*/
|
|
22
40
|
public function log(string $level, string $type, array $data): void
|
|
23
41
|
{
|
|
24
42
|
$logEntry = array_merge($data, [
|
|
@@ -5,12 +5,12 @@ declare(strict_types=1);
|
|
|
5
5
|
namespace Anonympins\Fingerprint\Utils;
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Provides utilities to detect malicious injection patterns.
|
|
9
9
|
*/
|
|
10
10
|
class MaliciousPatterns
|
|
11
11
|
{
|
|
12
12
|
/**
|
|
13
|
-
* @var array<string, string> Map
|
|
13
|
+
* @var array<string, string> Map of malicious patterns grouped by threat category.
|
|
14
14
|
*/
|
|
15
15
|
private const INJECTION_PATTERNS = [
|
|
16
16
|
// SQL/NoSQL injections, including time-based attacks
|
|
@@ -44,10 +44,10 @@ class MaliciousPatterns
|
|
|
44
44
|
];
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
|
-
*
|
|
48
|
-
* @param string $str
|
|
49
|
-
* @param array<string> $typesToDetect
|
|
50
|
-
* @return bool True
|
|
47
|
+
* Checks whether a string matches known injection patterns.
|
|
48
|
+
* @param string $str The input string to inspect.
|
|
49
|
+
* @param array<string> $typesToDetect Specific injection categories to detect (defaults to all).
|
|
50
|
+
* @return bool True if a malicious pattern is detected, false otherwise.
|
|
51
51
|
*/
|
|
52
52
|
public static function isMalicious(string $str, array $typesToDetect = []): bool
|
|
53
53
|
{
|