@anonympins/fingerprint 0.7.4 → 0.7.5
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 +27 -0
- package/README.md +1 -1
- package/package.json +1 -1
- package/public/fingerprint-anti-bot.zip +0 -0
- package/src/js/dynamic-wasm.js +218 -218
- package/src/js/fingerprint.client.js +77 -43
- package/src/js/fingerprint.client.obfuscated.js +1 -1
- package/src/js/fingerprint.js +291 -71
- package/src/js/tests/dynamic-wasm.test.js +77 -77
- package/src/js/tests/fingerprint.client.init.test.js +78 -0
- package/src/js/tests/fingerprint.test.js +18 -0
- package/src/js/tests/threatIntel.test.js +40 -1
- package/src/php/Challenge/ChallengeUtils.php +10 -0
- package/src/php/Config/SecurityProfiles.php +5 -0
- package/src/php/FingerprintEngine.php +186 -37
- package/src/php/Tests/ThreatIntelTest.php +34 -0
- package/src/php/Utils/RequestUtils.php +48 -0
- package/src/php/WordPress/fingerprint-anti-bot.php +1 -1
- 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/readme.txt +1 -1
|
@@ -1,78 +1,78 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { DynamicWasmGenerator } from '../dynamic-wasm.js';
|
|
3
|
-
|
|
4
|
-
// Helper function to decode ULEB128 (for verification)
|
|
5
|
-
function decodeULEB128(bytes) {
|
|
6
|
-
let result = 0;
|
|
7
|
-
let shift = 0;
|
|
8
|
-
for (const byte of bytes) {
|
|
9
|
-
result |= (byte & 0x7f) << shift;
|
|
10
|
-
if (!(byte & 0x80)) {
|
|
11
|
-
break;
|
|
12
|
-
}
|
|
13
|
-
shift += 7;
|
|
14
|
-
}
|
|
15
|
-
return result;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
describe('DynamicWasmGenerator', () => {
|
|
19
|
-
it('should generate a valid WASM module buffer', () => {
|
|
20
|
-
const constants = { seed: 123, multiplier: 33, adder: 7 };
|
|
21
|
-
const wasmBuffer = DynamicWasmGenerator.generate(constants);
|
|
22
|
-
|
|
23
|
-
// Basic check: ensure it's a Buffer and starts with WASM magic number
|
|
24
|
-
expect(wasmBuffer).toBeInstanceOf(Buffer);
|
|
25
|
-
expect(wasmBuffer.slice(0, 4).toString('hex')).toBe('0061736d'); // \0asm
|
|
26
|
-
expect(wasmBuffer.slice(4, 8).toString('hex')).toBe('01000000'); // Version 1
|
|
27
|
-
|
|
28
|
-
// Attempt to compile and instantiate the module to ensure validity
|
|
29
|
-
let instance;
|
|
30
|
-
try {
|
|
31
|
-
const module = new WebAssembly.Module(wasmBuffer);
|
|
32
|
-
instance = new WebAssembly.Instance(module, {});
|
|
33
|
-
} catch (e) {
|
|
34
|
-
// If compilation/instantiation fails, it's an invalid WASM module
|
|
35
|
-
expect.fail(`Generated WASM module is invalid: ${e.message}`);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// Verify the exported hash function exists
|
|
39
|
-
expect(instance.exports.hash).toBeInstanceOf(Function);
|
|
40
|
-
expect(instance.exports.memory).toBeInstanceOf(WebAssembly.Memory);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it('should produce a consistent hash result with the JS fallback', () => {
|
|
44
|
-
const constants = { seed: 42, multiplier: 1597334677, adder: 12345 };
|
|
45
|
-
const testString = "hello world";
|
|
46
|
-
|
|
47
|
-
const wasmBuffer = DynamicWasmGenerator.generate(constants);
|
|
48
|
-
const module = new WebAssembly.Module(wasmBuffer);
|
|
49
|
-
const instance = new WebAssembly.Instance(module, {});
|
|
50
|
-
const exports = instance.exports;
|
|
51
|
-
const memory = exports.memory;
|
|
52
|
-
|
|
53
|
-
// Write string to WASM memory
|
|
54
|
-
const encoder = new TextEncoder();
|
|
55
|
-
const bytes = encoder.encode(testString);
|
|
56
|
-
const view = new Uint8Array(memory.buffer);
|
|
57
|
-
view.set(bytes, 0); // Assuming hash function expects string at address 0
|
|
58
|
-
|
|
59
|
-
// Calculate hash using WASM
|
|
60
|
-
const wasmHash = exports.hash(0, bytes.length);
|
|
61
|
-
|
|
62
|
-
// Calculate hash using JS fallback
|
|
63
|
-
const jsHash = DynamicWasmGenerator.hashJs(testString, constants);
|
|
64
|
-
|
|
65
|
-
// The WASM and JS implementations should yield the same result
|
|
66
|
-
expect(wasmHash).toBe(jsHash);
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
it('should generate different WASM modules for different constants', () => {
|
|
70
|
-
const constants1 = { seed: 1, multiplier: 2, adder: 3 };
|
|
71
|
-
const constants2 = { seed: 4, multiplier: 5, adder: 6 };
|
|
72
|
-
|
|
73
|
-
const wasmBuffer1 = DynamicWasmGenerator.generate(constants1);
|
|
74
|
-
const wasmBuffer2 = DynamicWasmGenerator.generate(constants2);
|
|
75
|
-
|
|
76
|
-
expect(wasmBuffer1.toString('hex')).not.toBe(wasmBuffer2.toString('hex'));
|
|
77
|
-
});
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { DynamicWasmGenerator } from '../dynamic-wasm.js';
|
|
3
|
+
|
|
4
|
+
// Helper function to decode ULEB128 (for verification)
|
|
5
|
+
function decodeULEB128(bytes) {
|
|
6
|
+
let result = 0;
|
|
7
|
+
let shift = 0;
|
|
8
|
+
for (const byte of bytes) {
|
|
9
|
+
result |= (byte & 0x7f) << shift;
|
|
10
|
+
if (!(byte & 0x80)) {
|
|
11
|
+
break;
|
|
12
|
+
}
|
|
13
|
+
shift += 7;
|
|
14
|
+
}
|
|
15
|
+
return result;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
describe('DynamicWasmGenerator', () => {
|
|
19
|
+
it('should generate a valid WASM module buffer', () => {
|
|
20
|
+
const constants = { seed: 123, multiplier: 33, adder: 7 };
|
|
21
|
+
const wasmBuffer = DynamicWasmGenerator.generate(constants);
|
|
22
|
+
|
|
23
|
+
// Basic check: ensure it's a Buffer and starts with WASM magic number
|
|
24
|
+
expect(wasmBuffer).toBeInstanceOf(Buffer);
|
|
25
|
+
expect(wasmBuffer.slice(0, 4).toString('hex')).toBe('0061736d'); // \0asm
|
|
26
|
+
expect(wasmBuffer.slice(4, 8).toString('hex')).toBe('01000000'); // Version 1
|
|
27
|
+
|
|
28
|
+
// Attempt to compile and instantiate the module to ensure validity
|
|
29
|
+
let instance;
|
|
30
|
+
try {
|
|
31
|
+
const module = new WebAssembly.Module(wasmBuffer);
|
|
32
|
+
instance = new WebAssembly.Instance(module, {});
|
|
33
|
+
} catch (e) {
|
|
34
|
+
// If compilation/instantiation fails, it's an invalid WASM module
|
|
35
|
+
expect.fail(`Generated WASM module is invalid: ${e.message}`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Verify the exported hash function exists
|
|
39
|
+
expect(instance.exports.hash).toBeInstanceOf(Function);
|
|
40
|
+
expect(instance.exports.memory).toBeInstanceOf(WebAssembly.Memory);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('should produce a consistent hash result with the JS fallback', () => {
|
|
44
|
+
const constants = { seed: 42, multiplier: 1597334677, adder: 12345 };
|
|
45
|
+
const testString = "hello world";
|
|
46
|
+
|
|
47
|
+
const wasmBuffer = DynamicWasmGenerator.generate(constants);
|
|
48
|
+
const module = new WebAssembly.Module(wasmBuffer);
|
|
49
|
+
const instance = new WebAssembly.Instance(module, {});
|
|
50
|
+
const exports = instance.exports;
|
|
51
|
+
const memory = exports.memory;
|
|
52
|
+
|
|
53
|
+
// Write string to WASM memory
|
|
54
|
+
const encoder = new TextEncoder();
|
|
55
|
+
const bytes = encoder.encode(testString);
|
|
56
|
+
const view = new Uint8Array(memory.buffer);
|
|
57
|
+
view.set(bytes, 0); // Assuming hash function expects string at address 0
|
|
58
|
+
|
|
59
|
+
// Calculate hash using WASM
|
|
60
|
+
const wasmHash = exports.hash(0, bytes.length);
|
|
61
|
+
|
|
62
|
+
// Calculate hash using JS fallback
|
|
63
|
+
const jsHash = DynamicWasmGenerator.hashJs(testString, constants);
|
|
64
|
+
|
|
65
|
+
// The WASM and JS implementations should yield the same result
|
|
66
|
+
expect(wasmHash).toBe(jsHash);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('should generate different WASM modules for different constants', () => {
|
|
70
|
+
const constants1 = { seed: 1, multiplier: 2, adder: 3 };
|
|
71
|
+
const constants2 = { seed: 4, multiplier: 5, adder: 6 };
|
|
72
|
+
|
|
73
|
+
const wasmBuffer1 = DynamicWasmGenerator.generate(constants1);
|
|
74
|
+
const wasmBuffer2 = DynamicWasmGenerator.generate(constants2);
|
|
75
|
+
|
|
76
|
+
expect(wasmBuffer1.toString('hex')).not.toBe(wasmBuffer2.toString('hex'));
|
|
77
|
+
});
|
|
78
78
|
});
|
|
@@ -21,6 +21,7 @@ if (typeof globalThis.crypto !== 'undefined') {
|
|
|
21
21
|
Object.defineProperty(dom.window, 'crypto', { value: globalThis.crypto, writable: true, configurable: true });
|
|
22
22
|
}
|
|
23
23
|
Object.defineProperty(global, 'CustomEvent', { value: dom.window.CustomEvent, writable: true, configurable: true });
|
|
24
|
+
Object.defineProperty(global, 'Event', { value: dom.window.Event, writable: true, configurable: true });
|
|
24
25
|
|
|
25
26
|
global.fetch = vi.fn(); // Mock global fetch
|
|
26
27
|
window.fetch = (...args) => global.fetch(...args);
|
|
@@ -174,4 +175,81 @@ describe('ClientLibrary.initializeClient', () => {
|
|
|
174
175
|
expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('Challenge retry limit reached (3)'));
|
|
175
176
|
});
|
|
176
177
|
|
|
178
|
+
it('should inject phantom traps within closed shadow root and fire trigger on interaction', () => {
|
|
179
|
+
const onTriggerSpy = vi.spyOn(ClientLibrary, 'onHoneypotTrigger');
|
|
180
|
+
let capturedShadow = null;
|
|
181
|
+
const origAttachShadow = dom.window.Element.prototype.attachShadow;
|
|
182
|
+
vi.spyOn(dom.window.Element.prototype, 'attachShadow').mockImplementation(function (init) {
|
|
183
|
+
capturedShadow = origAttachShadow.call(this, init);
|
|
184
|
+
return capturedShadow;
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// Ensure document.body exists
|
|
188
|
+
document.body.innerHTML = '';
|
|
189
|
+
|
|
190
|
+
ClientLibrary.injectPhantomTraps();
|
|
191
|
+
|
|
192
|
+
const host = document.body.lastElementChild;
|
|
193
|
+
expect(host).not.toBeNull();
|
|
194
|
+
expect(host.getAttribute('aria-hidden')).toBe('true');
|
|
195
|
+
// Under closed mode, host.shadowRoot is inaccessible (null) from external callers
|
|
196
|
+
expect(host.shadowRoot).toBeNull();
|
|
197
|
+
expect(capturedShadow).not.toBeNull();
|
|
198
|
+
|
|
199
|
+
// Dispatch events on attached phantom elements inside closed shadow root
|
|
200
|
+
const link = capturedShadow.querySelector('a');
|
|
201
|
+
expect(link).not.toBeNull();
|
|
202
|
+
link.dispatchEvent(new Event('focus'));
|
|
203
|
+
expect(onTriggerSpy).toHaveBeenCalled();
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it('should inject trap links within closed shadow root and trigger on honeypot click', () => {
|
|
207
|
+
const onTriggerSpy = vi.spyOn(ClientLibrary, 'onHoneypotTrigger');
|
|
208
|
+
let capturedShadow = null;
|
|
209
|
+
const origAttachShadow = dom.window.Element.prototype.attachShadow;
|
|
210
|
+
vi.spyOn(dom.window.Element.prototype, 'attachShadow').mockImplementation(function (init) {
|
|
211
|
+
capturedShadow = origAttachShadow.call(this, init);
|
|
212
|
+
return capturedShadow;
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
document.body.innerHTML = '';
|
|
216
|
+
|
|
217
|
+
ClientLibrary.injectTrapLinks(['/trap-url-1', '/trap-url-2']);
|
|
218
|
+
|
|
219
|
+
const host = document.body.lastElementChild;
|
|
220
|
+
expect(host).not.toBeNull();
|
|
221
|
+
expect(host.getAttribute('aria-hidden')).toBe('true');
|
|
222
|
+
expect(host.shadowRoot).toBeNull(); // Closed Shadow DOM verification
|
|
223
|
+
expect(capturedShadow).not.toBeNull();
|
|
224
|
+
|
|
225
|
+
const link = capturedShadow.querySelector('a');
|
|
226
|
+
expect(link).not.toBeNull();
|
|
227
|
+
link.dispatchEvent(new Event('click'));
|
|
228
|
+
expect(onTriggerSpy).toHaveBeenCalled();
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it('should initialize honeypot form inputs within closed shadow root', () => {
|
|
232
|
+
const onTriggerSpy = vi.spyOn(ClientLibrary, 'onHoneypotTrigger');
|
|
233
|
+
let capturedShadow = null;
|
|
234
|
+
const origAttachShadow = dom.window.Element.prototype.attachShadow;
|
|
235
|
+
vi.spyOn(dom.window.Element.prototype, 'attachShadow').mockImplementation(function (init) {
|
|
236
|
+
capturedShadow = origAttachShadow.call(this, init);
|
|
237
|
+
return capturedShadow;
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
document.body.innerHTML = '';
|
|
241
|
+
|
|
242
|
+
ClientLibrary.initializeHoneypots(['bot_field_trap']);
|
|
243
|
+
|
|
244
|
+
const host = document.body.lastElementChild;
|
|
245
|
+
expect(host).not.toBeNull();
|
|
246
|
+
expect(host.getAttribute('aria-hidden')).toBe('true');
|
|
247
|
+
expect(host.shadowRoot).toBeNull();
|
|
248
|
+
expect(capturedShadow).not.toBeNull();
|
|
249
|
+
|
|
250
|
+
const input = capturedShadow.querySelector('input');
|
|
251
|
+
expect(input).not.toBeNull();
|
|
252
|
+
input.dispatchEvent(new Event('input'));
|
|
253
|
+
expect(onTriggerSpy).toHaveBeenCalled();
|
|
254
|
+
});
|
|
177
255
|
});
|
|
@@ -3200,4 +3200,22 @@ describe('IP Registration and Filtering', () => {
|
|
|
3200
3200
|
expect(process.env.ED25519_PUBLIC_KEY).toBe(dummyKeys.publicKey);
|
|
3201
3201
|
});
|
|
3202
3202
|
});
|
|
3203
|
+
|
|
3204
|
+
describe('Closed-Shadow DOM Honeypot Traps (Feature 19)', () => {
|
|
3205
|
+
it('should generate closed declarative shadow DOM trap container for trap URLs', () => {
|
|
3206
|
+
const trapUrls = ['/trap-1', '/trap-2'];
|
|
3207
|
+
const markup = __internal.generateClosedShadowTraps(trapUrls);
|
|
3208
|
+
|
|
3209
|
+
expect(markup).toContain('aria-hidden="true"');
|
|
3210
|
+
expect(markup).toContain('shadowrootmode="closed"');
|
|
3211
|
+
expect(markup).toContain('shadowroot="closed"');
|
|
3212
|
+
expect(markup).toContain('href="/trap-1"');
|
|
3213
|
+
expect(markup).toContain('href="/trap-2"');
|
|
3214
|
+
});
|
|
3215
|
+
|
|
3216
|
+
it('should return an empty string if trapUrls array is empty or invalid', () => {
|
|
3217
|
+
expect(__internal.generateClosedShadowTraps([])).toBe('');
|
|
3218
|
+
expect(__internal.generateClosedShadowTraps(null)).toBe('');
|
|
3219
|
+
});
|
|
3220
|
+
});
|
|
3203
3221
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it } from 'vitest';
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
2
|
import { __internal, configureStore } from '../fingerprint.js';
|
|
3
3
|
|
|
4
4
|
describe('Threat Intelligence - Rationale-Driven Defensive Logic', () => {
|
|
@@ -73,4 +73,43 @@ describe('Threat Intelligence - Rationale-Driven Defensive Logic', () => {
|
|
|
73
73
|
expect(vector.threatIntelScore).toBeGreaterThan(70.0);
|
|
74
74
|
expect(vector.threatIntelScore).toBeLessThanOrEqual(95.0);
|
|
75
75
|
});
|
|
76
|
+
|
|
77
|
+
it('should broadcast banned ZKP with differential privacy (perturbed timestamps and decoy injection)', async () => {
|
|
78
|
+
const calls = [];
|
|
79
|
+
const originalFetch = globalThis.fetch;
|
|
80
|
+
globalThis.fetch = vi.fn(async (url, init) => {
|
|
81
|
+
calls.push({ url, init });
|
|
82
|
+
return { ok: true, json: async () => ({ status: 'synchronized' }) };
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
const config = {
|
|
86
|
+
federatedPeers: ['https://peer1.example.com', 'https://peer2.example.com'],
|
|
87
|
+
federationSecret: 'test-secret-key-32-chars-long!!',
|
|
88
|
+
differentialPrivacy: {
|
|
89
|
+
enabled: true,
|
|
90
|
+
epsilon: 1.0,
|
|
91
|
+
dummyRate: 1.0 // Force decoy generation for deterministic testing
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const realZkpY = 'deadbeef12345678';
|
|
96
|
+
await __internal.broadcastBannedZkp(realZkpY, config);
|
|
97
|
+
|
|
98
|
+
// Should broadcast to 2 peers with real key + 2 peers with decoy key
|
|
99
|
+
expect(calls.length).toBe(4);
|
|
100
|
+
|
|
101
|
+
const bodies = calls.map(c => JSON.parse(c.init.body));
|
|
102
|
+
const zkpYs = bodies.map(b => b.zkpY);
|
|
103
|
+
|
|
104
|
+
expect(zkpYs).toContain(realZkpY);
|
|
105
|
+
const decoyKey = zkpYs.find(k => k !== realZkpY);
|
|
106
|
+
expect(decoyKey).toBeDefined();
|
|
107
|
+
expect(decoyKey).not.toBe(realZkpY);
|
|
108
|
+
|
|
109
|
+
for (const call of calls) {
|
|
110
|
+
const timestamp = Number(call.init.headers['X-Federation-Timestamp']);
|
|
111
|
+
expect(timestamp).toBeGreaterThan(0);
|
|
112
|
+
}
|
|
113
|
+
globalThis.fetch = originalFetch;
|
|
114
|
+
});
|
|
76
115
|
});
|
|
@@ -605,6 +605,11 @@ class ChallengeUtils
|
|
|
605
605
|
|
|
606
606
|
if (!$expiry || (int)floor(microtime(true) * 1000) > (int)$expiry) {
|
|
607
607
|
return false;
|
|
608
|
+
}
|
|
609
|
+
if (!empty($ticketData['greenlist']) || str_starts_with((string)$storedDeviceHash, 'webauthn:greenlist:')) {
|
|
610
|
+
if (empty($deviceId) || $deviceId === $storedDeviceId) {
|
|
611
|
+
return true;
|
|
612
|
+
}
|
|
608
613
|
}
|
|
609
614
|
if ($storedDeviceHash && str_starts_with($storedDeviceHash, 'zkp:')) {
|
|
610
615
|
$expectedY = explode(':', $storedDeviceHash, 2)[1] ?? '';
|
|
@@ -644,6 +649,11 @@ class ChallengeUtils
|
|
|
644
649
|
if (!$expiry || (int)floor(microtime(true) * 1000) > (int)$expiry) {
|
|
645
650
|
$store->delete("ticket:{$ticket}");
|
|
646
651
|
return false;
|
|
652
|
+
}
|
|
653
|
+
if (!empty($ticketData['greenlist']) || str_starts_with((string)$storedDeviceHash, 'webauthn:greenlist:')) {
|
|
654
|
+
if (empty($deviceId) || $deviceId === $storedDeviceId) {
|
|
655
|
+
return true;
|
|
656
|
+
}
|
|
647
657
|
}
|
|
648
658
|
if ($storedDeviceHash && str_starts_with($storedDeviceHash, 'zkp:')) {
|
|
649
659
|
$expectedY = explode(':', $storedDeviceHash, 2)[1] ?? '';
|
|
@@ -43,6 +43,7 @@ class SecurityProfiles
|
|
|
43
43
|
'tcpAnomalyScore' => 0.8,
|
|
44
44
|
'protocolAnomalyScore' => 0.8, // NEW: Anomalie de protocole (HTTP/2 et QUIC)
|
|
45
45
|
'renderingAnomalyScore' => 0.8, // NEW: Anomalie de rendu
|
|
46
|
+
'mtuAnomalyScore' => 0.9, // NOUVEAU: Poids pour l'anomalie MTU/fragmentation
|
|
46
47
|
'ipReputationScore' => 0.5, // NOUVEAU: Poids pour la réputation IP
|
|
47
48
|
'virtualizationScore' => 0.8,
|
|
48
49
|
],
|
|
@@ -97,6 +98,7 @@ class SecurityProfiles
|
|
|
97
98
|
'tcpAnomalyScore' => 1.0, // NEW: Anomalie de pile TCP/IP
|
|
98
99
|
'protocolAnomalyScore' => 1.0, // NEW: Anomalie de protocole (HTTP/2 et QUIC)
|
|
99
100
|
'renderingAnomalyScore' => 1.0, // NEW: Anomalie de rendu
|
|
101
|
+
'mtuAnomalyScore' => 0.9,
|
|
100
102
|
|
|
101
103
|
],
|
|
102
104
|
'thresholds' => ['low' => 10, 'medium' => 35, 'high' => 65, 'block' => 90],
|
|
@@ -149,6 +151,7 @@ class SecurityProfiles
|
|
|
149
151
|
'botnetClusterScore' => 0.7, // NOUVEAU: Poids pour le clustering botnet
|
|
150
152
|
'tcpAnomalyScore' => 0.8, // NEW: Anomalie de pile TCP/IP
|
|
151
153
|
'protocolAnomalyScore' => 0.8, // NEW: Anomalie de protocole (HTTP/2 et QUIC)
|
|
154
|
+
'mtuAnomalyScore' => 0.9,
|
|
152
155
|
|
|
153
156
|
],
|
|
154
157
|
'thresholds' => ['low' => 25, 'medium' => 50, 'high' => 80, 'block' => 95],
|
|
@@ -205,6 +208,7 @@ class SecurityProfiles
|
|
|
205
208
|
'tcpAnomalyScore' => 0.5, // NEW: Anomalie de pile TCP/IP
|
|
206
209
|
'protocolAnomalyScore' => 0.5, // NEW: Anomalie de protocole (HTTP/2 et QUIC)
|
|
207
210
|
'renderingAnomalyScore' => 0.5, // NEW: Anomalie de rendu
|
|
211
|
+
'mtuAnomalyScore' => 0.9,
|
|
208
212
|
|
|
209
213
|
],
|
|
210
214
|
'thresholds' => ['low' => 25, 'medium' => 55, 'high' => 80, 'block' => 95],
|
|
@@ -259,6 +263,7 @@ class SecurityProfiles
|
|
|
259
263
|
'tcpAnomalyScore' => 0.9, // NEW: Anomalie de pile TCP/IP
|
|
260
264
|
'protocolAnomalyScore' => 0.9, // NEW: Anomalie de protocole (HTTP/2 et QUIC)
|
|
261
265
|
'renderingAnomalyScore' => 0.9, // NEW: Anomalie de rendu
|
|
266
|
+
'mtuAnomalyScore' => 0.9,
|
|
262
267
|
|
|
263
268
|
],
|
|
264
269
|
'thresholds' => ['low' => 15, 'medium' => 40, 'high' => 70, 'block' => 90],
|