@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.
Files changed (64) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/README.md +1 -1
  3. package/package.json +1 -1
  4. package/public/anonympins-bot-mitigation-pow.zip +0 -0
  5. package/src/js/dynamic-wasm.js +218 -218
  6. package/src/js/fingerprint.client.js +1784 -1738
  7. package/src/js/fingerprint.client.obfuscated.js +1 -1
  8. package/src/js/fingerprint.js +489 -99
  9. package/src/js/fingerprint.utils.js +252 -2
  10. package/src/js/pow.worker.js +2 -2
  11. package/src/js/tests/cross_parity.test.js +3 -3
  12. package/src/js/tests/dns-circuit-breaker.test.js +6 -6
  13. package/src/js/tests/dynamic-wasm.test.js +77 -77
  14. package/src/js/tests/fingerprint.builder.test.js +76 -78
  15. package/src/js/tests/fingerprint.client.init.test.js +78 -0
  16. package/src/js/tests/fingerprint.client.test.js +16 -17
  17. package/src/js/tests/fingerprint.test.js +37 -12
  18. package/src/js/tests/ja3AnomalyDetector.test.js +135 -136
  19. package/src/js/tests/library.test.js +94 -95
  20. package/src/js/tests/obfuscation.test.js +8 -8
  21. package/src/js/tests/quicFingerprint.test.js +47 -0
  22. package/src/js/tests/tcpFingerprint.test.js +4 -4
  23. package/src/js/tests/threatIntel.test.js +40 -1
  24. package/src/js/upow-model-task.js +155 -112
  25. package/src/php/Challenge/ChallengeUtils.php +392 -86
  26. package/src/php/Config/SecurityProfiles.php +79 -61
  27. package/src/php/DirectFingerprint.php +55 -8
  28. package/src/php/FingerprintBuilder.php +13 -13
  29. package/src/php/FingerprintClient.php +6 -6
  30. package/src/php/FingerprintEngine.php +2122 -1690
  31. package/src/php/Ja3AnomalyDetector.php +22 -22
  32. package/src/php/Optimization/FunctionRegistry.php +4 -4
  33. package/src/php/Optimization/Optimization.php +6 -6
  34. package/src/php/RequestContext.php +11 -11
  35. package/src/php/Store/InMemoryStore.php +96 -66
  36. package/src/php/Store/MongoDbStore.php +2 -2
  37. package/src/php/Store/RedisStore.php +1 -1
  38. package/src/php/Store/StoreManager.php +48 -35
  39. package/src/php/Tests/ChallengeUtilsTest.php +31 -0
  40. package/src/php/Tests/DnsCircuitBreakerTest.php +105 -105
  41. package/src/php/Tests/FingerprintClientTest.php +70 -70
  42. package/src/php/Tests/PowTest.php +37 -39
  43. package/src/php/Tests/QuicFingerprintTest.php +115 -53
  44. package/src/php/Tests/ThreatIntelTest.php +34 -0
  45. package/src/php/Utils/BigInt.php +202 -202
  46. package/src/php/Utils/BlockList.php +13 -13
  47. package/src/php/Utils/Logger.php +19 -1
  48. package/src/php/Utils/MaliciousPatterns.php +6 -6
  49. package/src/php/Utils/MetricsManager.php +209 -209
  50. package/src/php/Utils/RequestUtils.php +362 -1
  51. package/src/php/Utils/TLSClientHelloParser.php +385 -369
  52. package/src/php/WordPress/WpDbStore.php +7 -7
  53. package/src/php/WordPress/anonympins-bot-mitigation-pow.php +1121 -0
  54. package/src/php/WordPress/fingerprint-anti-bot.php +0 -559
  55. package/src/php/WordPress/languages/anonympins-bot-mitigation-pow-fr_FR.mo +0 -0
  56. package/src/php/WordPress/languages/anonympins-bot-mitigation-pow-fr_FR.po +232 -0
  57. package/src/php/WordPress/languages/fingerprint-wordpress-de_DE.mo +0 -0
  58. package/src/php/WordPress/languages/fingerprint-wordpress-de_DE.po +297 -261
  59. package/src/php/WordPress/languages/fingerprint-wordpress-fr_FR.mo +0 -0
  60. package/src/php/WordPress/languages/fingerprint-wordpress-fr_FR.po +348 -267
  61. package/src/php/WordPress/package.php +80 -101
  62. package/src/php/WordPress/readme.txt +21 -5
  63. package/src/php/bin/auto-tune.php +1 -1
  64. package/public/fingerprint-anti-bot.zip +0 -0
@@ -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
  });
@@ -1,113 +1,156 @@
1
- import crypto from "node:crypto";
2
-
3
- /**
4
- * Abstract base class defining useful Proof-of-Work (uPoW) tasks based on ML training
5
- * or inference validation (e.g. PyTorch models exported to ONNX format).
6
- */
7
- export class UpowModelTask {
8
- constructor(problemId, modelPath, config = {}) {
9
- if (new.target === UpowModelTask) {
10
- throw new TypeError("Cannot construct UpowModelTask instances directly");
11
- }
12
- this.problemId = problemId;
13
- this.modelPath = modelPath;
14
- this.config = {
15
- batchSize: 32,
16
- learningRate: 0.01,
17
- validationTolerance: 0.15,
18
- ...config
19
- };
20
- }
21
-
22
- /**
23
- * Returns the unique problem identifier.
24
- * @returns {string}
25
- */
26
- getProblemId() {
27
- return this.problemId;
28
- }
29
-
30
- /**
31
- * Returns the network asset path of the model.
32
- * @returns {string}
33
- */
34
- getModelAssetPath() {
35
- return this.modelPath;
36
- }
37
-
38
- /**
39
- * Dispatches task workload to the client.
40
- * Transmits current model weights and mini-batch sample data.
41
- * @param {number} suspicionFactor
42
- * @returns {object} Task payload dispatched to client
43
- */
44
- dispatchTask(suspicionFactor) {
45
- throw new Error("Method 'dispatchTask(suspicionFactor)' must be implemented.");
46
- }
47
-
48
- /**
49
- * Validates solution returned by the client.
50
- * Implements anti-poisoning guards and gradient bounds checks.
51
- * @param {object} taskContext
52
- * @param {object} solution
53
- * @returns {boolean}
54
- */
55
- verifySolution(taskContext, solution) {
56
- throw new Error("Method 'verifySolution(taskContext, solution)' must be implemented.");
57
- }
58
-
59
- /**
60
- * Integrates validated gradients into global model weights (e.g. FedAvg).
61
- * @param {object} solution
62
- */
63
- integrateSolution(solution) {
64
- throw new Error("Method 'integrateSolution(solution)' must be implemented.");
65
- }
66
- }
67
-
68
- /**
69
- * Example training task implementation (suspicious request classifier).
70
- */
71
- export class RequestClassifierTask extends UpowModelTask {
72
- constructor(modelPath, config) {
73
- super("request_classifier_nn", modelPath, config);
74
- // Initial model weights (linear neural network)
75
- this.weights = [0.1, -0.2, 0.8, 0.5];
76
- }
77
-
78
- dispatchTask(suspicionFactor) {
79
- // Anonymized sample training batch dispatched to client
80
- const inputs = [
81
- [1.0, 0.5, 0.0, 1.2],
82
- [0.0, 1.0, -0.5, 0.8]
83
- ];
84
- return {
85
- weights: [...this.weights],
86
- inputs: inputs,
87
- learningRate: this.config.learningRate,
88
- batchSize: this.config.batchSize
89
- };
90
- }
91
-
92
- verifySolution(taskContext, solution) {
93
- const gradients = solution?.gradients;
94
- if (!Array.isArray(gradients) || gradients.length !== this.weights.length) {
95
- return false;
96
- }
97
- // Anti-poisoning guard: ensure gradients do not exceed threshold norms (gradient clipping)
98
- const maxGradientNorm = 10.0;
99
- for (const grad of gradients) {
100
- if (typeof grad !== 'number' || isNaN(grad) || Math.abs(grad) > maxGradientNorm) {
101
- return false;
102
- }
103
- }
104
- return true;
105
- }
106
-
107
- integrateSolution(solution) {
108
- const gradients = solution.gradients;
109
- for (let i = 0; i < this.weights.length; i++) {
110
- this.weights[i] -= this.config.learningRate * gradients[i];
111
- }
112
- }
1
+ import crypto from "node:crypto";
2
+
3
+ /**
4
+ * Abstract base class defining useful Proof-of-Work (uPoW) tasks based on ML training
5
+ * or inference validation (e.g. PyTorch models exported to ONNX format).
6
+ */
7
+ export class UpowModelTask {
8
+ /**
9
+ * Creates a new UpowModelTask. This class is abstract and cannot be
10
+ * instantiated directly.
11
+ *
12
+ * @param {string} problemId - The unique identifier of the problem.
13
+ * @param {string} modelPath - The network asset path of the model.
14
+ * @param {object} [config={}] - Optional configuration overrides.
15
+ * @param {number} [config.batchSize=32] - Mini-batch size.
16
+ * @param {number} [config.learningRate=0.01] - Learning rate.
17
+ * @param {number} [config.validationTolerance=0.15] - Validation tolerance.
18
+ * @throws {TypeError} If instantiated directly.
19
+ */
20
+ constructor(problemId, modelPath, config = {}) {
21
+ if (new.target === UpowModelTask) {
22
+ throw new TypeError("Cannot construct UpowModelTask instances directly");
23
+ }
24
+ this.problemId = problemId;
25
+ this.modelPath = modelPath;
26
+ this.config = {
27
+ batchSize: 32,
28
+ learningRate: 0.01,
29
+ validationTolerance: 0.15,
30
+ ...config
31
+ };
32
+ }
33
+
34
+ /**
35
+ * Returns the unique problem identifier.
36
+ * @returns {string}
37
+ */
38
+ getProblemId() {
39
+ return this.problemId;
40
+ }
41
+
42
+ /**
43
+ * Returns the network asset path of the model.
44
+ * @returns {string}
45
+ */
46
+ getModelAssetPath() {
47
+ return this.modelPath;
48
+ }
49
+
50
+ /**
51
+ * Dispatches task workload to the client.
52
+ * Transmits current model weights and mini-batch sample data.
53
+ * @param {number} suspicionFactor
54
+ * @returns {object} Task payload dispatched to client
55
+ */
56
+ dispatchTask(suspicionFactor) {
57
+ throw new Error("Method 'dispatchTask(suspicionFactor)' must be implemented.");
58
+ }
59
+
60
+ /**
61
+ * Validates solution returned by the client.
62
+ * Implements anti-poisoning guards and gradient bounds checks.
63
+ * @param {object} taskContext
64
+ * @param {object} solution
65
+ * @returns {boolean}
66
+ */
67
+ verifySolution(taskContext, solution) {
68
+ throw new Error("Method 'verifySolution(taskContext, solution)' must be implemented.");
69
+ }
70
+
71
+ /**
72
+ * Integrates validated gradients into global model weights (e.g. FedAvg).
73
+ * @param {object} solution
74
+ */
75
+ integrateSolution(solution) {
76
+ throw new Error("Method 'integrateSolution(solution)' must be implemented.");
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Example training task implementation (suspicious request classifier).
82
+ */
83
+ export class RequestClassifierTask extends UpowModelTask {
84
+ /**
85
+ * Creates a new RequestClassifierTask with an initial set of linear
86
+ * neural network weights.
87
+ *
88
+ * @param {string} modelPath - The network asset path of the model.
89
+ * @param {object} config - Configuration object (batch size, learning rate, etc.).
90
+ */
91
+ constructor(modelPath, config) {
92
+ super("request_classifier_nn", modelPath, config);
93
+ // Initial model weights (linear neural network)
94
+ this.weights = [0.1, -0.2, 0.8, 0.5];
95
+ }
96
+
97
+ /**
98
+ * Builds and returns the task payload sent to the client, including the
99
+ * current model weights, an anonymized sample training batch, the learning
100
+ * rate, and the batch size.
101
+ *
102
+ * @param {number} suspicionFactor - The suspicion factor for this request.
103
+ * @returns {object} The task payload dispatched to the client.
104
+ */
105
+ dispatchTask(suspicionFactor) {
106
+ // Anonymized sample training batch dispatched to client
107
+ const inputs = [
108
+ [1.0, 0.5, 0.0, 1.2],
109
+ [0.0, 1.0, -0.5, 0.8]
110
+ ];
111
+ return {
112
+ weights: [...this.weights],
113
+ inputs: inputs,
114
+ learningRate: this.config.learningRate,
115
+ batchSize: this.config.batchSize
116
+ };
117
+ }
118
+
119
+ /**
120
+ * Validates the solution returned by the client. Ensures the gradients
121
+ * array has the expected length and applies an anti-poisoning guard by
122
+ * rejecting any gradient whose absolute value exceeds a fixed threshold
123
+ * (gradient clipping).
124
+ *
125
+ * @param {object} taskContext - The context of the dispatched task.
126
+ * @param {object} solution - The solution returned by the client.
127
+ * @returns {boolean} True if the solution is valid, false otherwise.
128
+ */
129
+ verifySolution(taskContext, solution) {
130
+ const gradients = solution?.gradients;
131
+ if (!Array.isArray(gradients) || gradients.length !== this.weights.length) {
132
+ return false;
133
+ }
134
+ // Anti-poisoning guard: ensure gradients do not exceed threshold norms (gradient clipping)
135
+ const maxGradientNorm = 10.0;
136
+ for (const grad of gradients) {
137
+ if (typeof grad !== 'number' || isNaN(grad) || Math.abs(grad) > maxGradientNorm) {
138
+ return false;
139
+ }
140
+ }
141
+ return true;
142
+ }
143
+
144
+ /**
145
+ * Integrates the validated gradients into the global model weights using
146
+ * a simple gradient descent update: w_i -= learningRate * grad_i.
147
+ *
148
+ * @param {object} solution - The validated solution containing gradients.
149
+ */
150
+ integrateSolution(solution) {
151
+ const gradients = solution.gradients;
152
+ for (let i = 0; i < this.weights.length; i++) {
153
+ this.weights[i] -= this.config.learningRate * gradients[i];
154
+ }
155
+ }
113
156
  }