@anonympins/fingerprint 0.4.4 → 0.4.6
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 +40 -0
- package/README.md +1 -1
- package/package.json +1 -1
- package/src/js/dynamic-wasm.js +180 -0
- package/src/js/fingerprint.client.js +21 -0
- package/src/js/fingerprint.js +763 -56
- package/src/js/library.js +1740 -1729
- package/src/js/pow.solver.inline.js +381 -285
- package/src/js/pow.solver.js +97 -1
- package/src/js/tests/dynamic-wasm.test.js +78 -0
- package/src/js/tests/fingerprint.client.test.js +128 -104
- package/src/js/tests/fingerprint.test.js +79 -1
- package/src/js/tests/ip-reputation.test.js +141 -131
- package/src/js/tests/tcpFingerprint.test.js +78 -0
- package/src/php/AutoTuner.php +1 -1
- package/src/php/Challenge/ChallengeUtils.php +174 -12
- package/src/php/Config/SecurityProfiles.php +10 -0
- package/src/php/FingerprintEngine.php +140 -8
- package/src/php/Optimization/Optimization.php +257 -255
- package/src/php/Optimization/OptimizationOperators.php +41 -35
- package/src/php/RequestContext.php +2 -0
- package/src/php/Tests/FingerprintEngineTest.php +132 -1
- package/src/php/Tests/IpReputationTest.php +175 -156
- package/src/php/Tests/RequestUtilsTest.php +13 -0
- package/src/php/Utils/RequestUtils.php +319 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,43 @@
|
|
|
1
|
+
## Version 0.4.6
|
|
2
|
+
|
|
3
|
+
### ✨ New Features
|
|
4
|
+
|
|
5
|
+
- **Polymorphic WASM Modules**: Further enhances client-side WebAssembly modules by introducing polymorphic generation, making it even harder for bots to fingerprint and reverse-engineer the client-side logic.
|
|
6
|
+
- **Proof-of-Space (PoSpace) Challenge**: Implemented a new Proof-of-Space challenge type. This challenge requires clients to allocate and prove access to a certain amount of storage space, adding another layer of bot detection.
|
|
7
|
+
- **Enhanced TLS Tracking (HTTPS)**: Introduced new capabilities for tracking and analyzing TLS-related information, improving the accuracy of client identification and anomaly detection over HTTPS connections.
|
|
8
|
+
|
|
9
|
+
### 🚀 Improvements
|
|
10
|
+
|
|
11
|
+
- **Analog Cross-Layer Inconsistency Score**: Refined the `crossLayerInconsistencyScore` calculation to provide a more nuanced and "analog" assessment of inconsistencies between different layers of client data, leading to more precise bot identification.
|
|
12
|
+
|
|
13
|
+
### 🐛 Bug Fixes
|
|
14
|
+
|
|
15
|
+
- **Auto-Tuner Fix**: Addressed several issues within the auto-tuner, improving its stability, learning accuracy, and resilience against edge cases.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Version 0.4.5
|
|
20
|
+
|
|
21
|
+
### ✨ New Features
|
|
22
|
+
|
|
23
|
+
- **Stateless PoW Ticket Validation**: Introduced cryptographically secure stateless Proof-of-Work (PoW) tickets. These tickets are encrypted and signed, allowing for tamper-proof validation without requiring server-side storage, improving scalability and resilience.
|
|
24
|
+
- **TCP Anomaly Score**: Implemented a new `tcpAnomalyScore` based on passive TCP/IP fingerprinting (p0f-like analysis). This score detects inconsistencies between the client's TCP stack (TTL, window size, options) and its User-Agent, indicating potential spoofing or bot activity.
|
|
25
|
+
- **Dynamic WebAssembly (WASM) Modules**: Introduced polymorphic WASM module generation. The client-side WASM solver now generates unique, randomized code for each request or session, significantly increasing the cost and difficulty for bots to fingerprint, reverse-engineer, and bypass.
|
|
26
|
+
|
|
27
|
+
### 🚀 Improvements
|
|
28
|
+
|
|
29
|
+
- **Enhanced Client Hints Inconsistency Detection**: Improved the `clientHintsInconsistencyScore` calculation for more precise detection of discrepancies between User-Agent and Client Hints headers, leading to more accurate bot identification.
|
|
30
|
+
|
|
31
|
+
### 🛡️ Security Enhancements
|
|
32
|
+
|
|
33
|
+
- **PHP DoS Prevention**: Implemented specific measures in the PHP engine to prevent Denial-of-Service (DoS) attacks, ensuring stability and resource protection under high load or malicious activity.
|
|
34
|
+
|
|
35
|
+
### 📚 Documentation
|
|
36
|
+
|
|
37
|
+
- **README Update**: Updated `README.md` to reflect the latest features and changes in the library.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
1
41
|
## Version 0.4.4
|
|
2
42
|
|
|
3
43
|
### 🧮 Pattern Score Ratios & Weighted Subscores
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ NodeJS tests : [](https://github.com/anonympins/fingerprint/blob/main/LICENSE)
|
|
7
7
|

|
|
8
8
|
|
|
9
|
-
A multi-layered behavioral, cryptographic, and network analysis engine designed to identify and mitigate malicious requests (bots, scrapers, session hijacking) in real-time. Supports **Node.js**, **Python** and **PHP** environments.
|
|
9
|
+
A multi-layered behavioral, cryptographic, and network analysis engine designed to identify and mitigate malicious requests (bots, scrapers, session hijacking, bot farms) in real-time. Supports **Node.js**, **Python** and **PHP** environments.
|
|
10
10
|
|
|
11
11
|

|
|
12
12
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anonympins/fingerprint",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.6",
|
|
4
4
|
"description": "Advanced anti-bot library for Node.js using multi-layer fingerprinting (JA3, client-side, headers), behavioral analysis, and adaptive Proof-of-Work (PoW) challenges to mitigate scraping, scalping, and automated threats.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
|
|
3
|
+
function encodeULEB128(val) {
|
|
4
|
+
const bytes = [];
|
|
5
|
+
let num = val >>> 0;
|
|
6
|
+
do {
|
|
7
|
+
let byte = num & 0x7f;
|
|
8
|
+
num >>>= 7;
|
|
9
|
+
if (num !== 0) byte |= 0x80;
|
|
10
|
+
bytes.push(byte);
|
|
11
|
+
} while (num !== 0);
|
|
12
|
+
return bytes;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function encodeSLEB128(val) {
|
|
16
|
+
const bytes = [];
|
|
17
|
+
let num = val | 0;
|
|
18
|
+
while (true) {
|
|
19
|
+
let byte = num & 0x7f;
|
|
20
|
+
num >>= 7;
|
|
21
|
+
if ((num === 0 && (byte & 0x40) === 0) || (num === -1 && (byte & 0x40) !== 0)) {
|
|
22
|
+
bytes.push(byte);
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
bytes.push(byte | 0x80);
|
|
26
|
+
}
|
|
27
|
+
return bytes;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function generatePolymorphicInstructions() {
|
|
31
|
+
const ops = [0x6a, 0x6b, 0x6c, 0x73]; // add, sub, mul, xor
|
|
32
|
+
const insts = [];
|
|
33
|
+
const count = 3 + Math.floor(Math.random() * 5); // 3 to 7 instructions
|
|
34
|
+
|
|
35
|
+
// Initialize dummy local 4
|
|
36
|
+
const initVal = Math.floor(Math.random() * 1000) - 500;
|
|
37
|
+
insts.push(0x41, ...encodeSLEB128(initVal), 0x21, 0x04);
|
|
38
|
+
|
|
39
|
+
for (let i = 0; i < count; i++) {
|
|
40
|
+
const op = ops[Math.floor(Math.random() * ops.length)];
|
|
41
|
+
const randVal = Math.floor(Math.random() * 1000) - 500;
|
|
42
|
+
insts.push(0x20, 0x04, 0x41, ...encodeSLEB128(randVal), op, 0x21, 0x04);
|
|
43
|
+
}
|
|
44
|
+
return insts;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export class DynamicWasmGenerator {
|
|
48
|
+
/**
|
|
49
|
+
* Generates a unique polymorphic WebAssembly module containing a custom hash function
|
|
50
|
+
* with randomized constants and control flow variables.
|
|
51
|
+
* @param {object} constants - Custom seed, multiplier and adder.
|
|
52
|
+
* @returns {Buffer} Valid WebAssembly binary buffer.
|
|
53
|
+
*/
|
|
54
|
+
static generate(constants) {
|
|
55
|
+
const { seed, multiplier, adder } = constants;
|
|
56
|
+
|
|
57
|
+
const preLoopPoly = generatePolymorphicInstructions();
|
|
58
|
+
const midLoopPoly = generatePolymorphicInstructions();
|
|
59
|
+
|
|
60
|
+
const inst = [
|
|
61
|
+
0x01, 0x05, 0x7f, // Locals: 1 entry of 5 locals of type i32
|
|
62
|
+
...preLoopPoly,
|
|
63
|
+
// h = seed
|
|
64
|
+
0x41, ...encodeSLEB128(seed),
|
|
65
|
+
0x21, 0x03,
|
|
66
|
+
// i = 0
|
|
67
|
+
0x41, 0x00,
|
|
68
|
+
0x21, 0x02,
|
|
69
|
+
|
|
70
|
+
// block
|
|
71
|
+
0x02, 0x40,
|
|
72
|
+
// loop
|
|
73
|
+
0x03, 0x40,
|
|
74
|
+
|
|
75
|
+
// if i >= len break
|
|
76
|
+
0x20, 0x02,
|
|
77
|
+
0x20, 0x01,
|
|
78
|
+
0x4f,
|
|
79
|
+
0x0d, 0x01,
|
|
80
|
+
|
|
81
|
+
// byte = load8_u(ptr + i)
|
|
82
|
+
0x20, 0x00,
|
|
83
|
+
0x20, 0x02,
|
|
84
|
+
0x6a,
|
|
85
|
+
0x2d, 0x00, 0x00,
|
|
86
|
+
|
|
87
|
+
// h = h ^ byte
|
|
88
|
+
0x20, 0x03,
|
|
89
|
+
0x73,
|
|
90
|
+
|
|
91
|
+
// h = h * multiplier
|
|
92
|
+
0x41, ...encodeSLEB128(multiplier),
|
|
93
|
+
0x6c,
|
|
94
|
+
|
|
95
|
+
// h = h + adder
|
|
96
|
+
0x41, ...encodeSLEB128(adder),
|
|
97
|
+
0x6a,
|
|
98
|
+
|
|
99
|
+
// local.set 3
|
|
100
|
+
0x21, 0x03,
|
|
101
|
+
...midLoopPoly,
|
|
102
|
+
|
|
103
|
+
// i = i + 1
|
|
104
|
+
0x20, 0x02,
|
|
105
|
+
0x41, 0x01,
|
|
106
|
+
0x6a,
|
|
107
|
+
0x21, 0x02,
|
|
108
|
+
|
|
109
|
+
// br 0
|
|
110
|
+
0x0c, 0x00,
|
|
111
|
+
|
|
112
|
+
0x0b, // end loop
|
|
113
|
+
0x0b, // end block
|
|
114
|
+
|
|
115
|
+
// return h
|
|
116
|
+
0x20, 0x03,
|
|
117
|
+
0x0b // end function
|
|
118
|
+
];
|
|
119
|
+
|
|
120
|
+
const funcBody = [
|
|
121
|
+
...encodeULEB128(inst.length),
|
|
122
|
+
...inst
|
|
123
|
+
];
|
|
124
|
+
|
|
125
|
+
const codeSectionPayload = [
|
|
126
|
+
...encodeULEB128(1),
|
|
127
|
+
...funcBody
|
|
128
|
+
];
|
|
129
|
+
|
|
130
|
+
const codeSection = [
|
|
131
|
+
0x0a,
|
|
132
|
+
...encodeULEB128(codeSectionPayload.length),
|
|
133
|
+
...codeSectionPayload
|
|
134
|
+
];
|
|
135
|
+
|
|
136
|
+
const typeSection = [
|
|
137
|
+
0x01, 0x07, 0x01, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f
|
|
138
|
+
];
|
|
139
|
+
|
|
140
|
+
const funcSection = [
|
|
141
|
+
0x03, 0x02, 0x01, 0x00
|
|
142
|
+
];
|
|
143
|
+
|
|
144
|
+
const memSection = [
|
|
145
|
+
0x05, 0x03, 0x01, 0x00, 0x01
|
|
146
|
+
];
|
|
147
|
+
|
|
148
|
+
const exportSection = [
|
|
149
|
+
0x07, 0x11, 0x02, 0x04, 0x68, 0x61, 0x73, 0x68, 0x00, 0x00, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00
|
|
150
|
+
];
|
|
151
|
+
|
|
152
|
+
const wasm = [
|
|
153
|
+
0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00,
|
|
154
|
+
...typeSection,
|
|
155
|
+
...funcSection,
|
|
156
|
+
...memSection,
|
|
157
|
+
...exportSection,
|
|
158
|
+
...codeSection
|
|
159
|
+
];
|
|
160
|
+
|
|
161
|
+
return Buffer.from(wasm);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Pure JavaScript fallback equivalent of the custom polymorphic hash.
|
|
166
|
+
* @param {string} str Input string.
|
|
167
|
+
* @param {object} constants Parameters.
|
|
168
|
+
* @returns {number} 32-bit unsigned integer hash.
|
|
169
|
+
*/
|
|
170
|
+
static hashJs(str, constants) {
|
|
171
|
+
const { seed, multiplier, adder } = constants;
|
|
172
|
+
let h = seed | 0;
|
|
173
|
+
for (let i = 0; i < str.length; i++) {
|
|
174
|
+
const byte = str.charCodeAt(i) & 0xff;
|
|
175
|
+
h = h ^ byte;
|
|
176
|
+
h = Math.imul(h, multiplier) + adder;
|
|
177
|
+
}
|
|
178
|
+
return h >>> 0;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
@@ -671,6 +671,27 @@ const ClientLibrary = {
|
|
|
671
671
|
*/
|
|
672
672
|
async initializeWasm(wasmPath) {
|
|
673
673
|
try {
|
|
674
|
+
// Direct standalone polymorphic WebAssembly loading
|
|
675
|
+
if (wasmPath.endsWith('.wasm')) {
|
|
676
|
+
const response = await fetch(wasmPath);
|
|
677
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
678
|
+
const module = await WebAssembly.compile(arrayBuffer);
|
|
679
|
+
const instance = await WebAssembly.instantiate(module, {});
|
|
680
|
+
const exports = instance.exports;
|
|
681
|
+
const memory = exports.memory;
|
|
682
|
+
activeCyrb53 = (str) => {
|
|
683
|
+
const encoder = new TextEncoder();
|
|
684
|
+
const bytes = encoder.encode(str);
|
|
685
|
+
const view = new Uint8Array(memory.buffer, 0, bytes.length);
|
|
686
|
+
view.set(bytes);
|
|
687
|
+
return exports.hash(0, bytes.length);
|
|
688
|
+
};
|
|
689
|
+
console.log('[Fingerprint] Standalone polymorphic WASM loaded successfully. Using fast dynamic hashing.');
|
|
690
|
+
if (this._cachedBuilder) {
|
|
691
|
+
this._cachedBuilder.addRaw('wasm', 'true');
|
|
692
|
+
}
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
674
695
|
// 1. Injecter le script qui charge le module WASM
|
|
675
696
|
const script = document.createElement('script');
|
|
676
697
|
script.src = wasmPath;
|