@anonympins/fingerprint 0.6.0 → 0.6.3

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.
@@ -1025,7 +1025,13 @@ class RequestUtils
1025
1025
 
1026
1026
  public static function getThreatIntelScore(RequestContext $context, array $threatIntelConfig): array
1027
1027
  {
1028
- return ['threatIntelScore' => 0.0];
1028
+ $zkpY = $context->zkpY;
1029
+ if (empty($zkpY)) {
1030
+ return ['threatIntelScore' => 0.0];
1031
+ }
1032
+ $store = StoreManager::getStore();
1033
+ $isBanned = $store->has("banned-zkp-y:{$zkpY}");
1034
+ return ['threatIntelScore' => $isBanned ? 100.0 : 0.0];
1029
1035
  }
1030
1036
 
1031
1037
  /**
@@ -1248,12 +1254,20 @@ class RequestUtils
1248
1254
  'highScoreCount' => 0,
1249
1255
  'deviceIds' => [],
1250
1256
  'highScoreDevices' => [],
1251
- 'lastActivity' => 0
1257
+ 'lastActivity' => 0,
1258
+ 'ips' => [],
1259
+ 'uas' => []
1252
1260
  ];
1253
1261
 
1254
1262
  if (!isset($subnetData['highScoreDevices'])) {
1255
1263
  $subnetData['highScoreDevices'] = [];
1256
1264
  }
1265
+ if (!isset($subnetData['ips'])) {
1266
+ $subnetData['ips'] = [];
1267
+ }
1268
+ if (!isset($subnetData['uas'])) {
1269
+ $subnetData['uas'] = [];
1270
+ }
1257
1271
 
1258
1272
  // Utilisation de la partie stable du fingerprint matériel plutôt que l'ID de cookie volatil
1259
1273
  $currentDeviceHash = self::getCompositeDeviceHash($context);
@@ -1268,6 +1282,16 @@ class RequestUtils
1268
1282
  if (!in_array($stableFpId, $subnetData['deviceIds'], true)) {
1269
1283
  $subnetData['deviceIds'][] = $stableFpId;
1270
1284
  }
1285
+
1286
+ if (!in_array($context->clientIp, $subnetData['ips'], true)) {
1287
+ $subnetData['ips'][] = $context->clientIp;
1288
+ }
1289
+
1290
+ $userAgent = $context->getHeader('user-agent') ?? '';
1291
+ if (!empty($userAgent) && !in_array($userAgent, $subnetData['uas'], true)) {
1292
+ $subnetData['uas'][] = $userAgent;
1293
+ }
1294
+
1271
1295
  $subnetData['lastActivity'] = time();
1272
1296
 
1273
1297
  // Limiter la taille du tableau des deviceIds pour éviter une consommation mémoire excessive.
@@ -1279,6 +1303,12 @@ class RequestUtils
1279
1303
  unset($subnetData['highScoreDevices'][$oldDeviceId]);
1280
1304
  }
1281
1305
  }
1306
+ if (count($subnetData['ips']) > 100) {
1307
+ array_shift($subnetData['ips']);
1308
+ }
1309
+ if (count($subnetData['uas']) > 50) {
1310
+ array_shift($subnetData['uas']);
1311
+ }
1282
1312
 
1283
1313
  // TTL de 24 heures pour les données de sous-réseau.
1284
1314
  $store->set($key, $subnetData, 86400);
@@ -1312,23 +1342,32 @@ class RequestUtils
1312
1342
 
1313
1343
  $highScoreCount = $subnetData['highScoreCount'] ?? 0;
1314
1344
  $deviceCount = isset($subnetData['deviceIds']) ? count($subnetData['deviceIds']) : 0;
1345
+ $ipCount = isset($subnetData['ips']) ? count($subnetData['ips']) : 1;
1346
+ $uaCount = isset($subnetData['uas']) ? count($subnetData['uas']) : 1;
1315
1347
 
1316
1348
  if ($halfLives > 0) {
1317
- $highScoreCount = max(0, (int)floor($highScoreCount / pow(2, $halfLives)));
1318
- $deviceCount = max(0, (int)floor($deviceCount / pow(2, $halfLives)));
1349
+ $decay = pow(2, $halfLives);
1350
+ $highScoreCount = max(0, (int)floor($highScoreCount / $decay));
1351
+ $deviceCount = max(0, (int)floor($deviceCount / $decay));
1352
+ $ipCount = max(1, (int)floor($ipCount / $decay));
1353
+ $uaCount = max(1, (int)floor($uaCount / $decay));
1319
1354
  }
1320
1355
 
1321
- $score = 0.0;
1322
-
1323
- // Pénalité basée sur le nombre de devices uniques vus depuis ce sous-réseau.
1324
- if ($deviceCount > 10) {
1325
- $score += min(80.0, ($deviceCount - 10) * 5);
1356
+ if ($deviceCount === 0) {
1357
+ return ['subnetScore' => 0.0];
1326
1358
  }
1327
1359
 
1328
- // Pénalité basée sur le nombre de scores élevés enregistrés.
1329
- $score += min(40.0, $highScoreCount * 2);
1360
+ $suspicionDensity = $highScoreCount / $deviceCount;
1361
+ $ipDeviceRatio = $ipCount / $deviceCount;
1362
+
1363
+ $baseScore = 100.0 * (1.0 - exp(-0.15 * $highScoreCount));
1364
+
1365
+ $densityMultiplier = 0.4 + (1.6 * $suspicionDensity);
1366
+ $distributionMultiplier = 0.5 + (1.0 * $ipDeviceRatio);
1330
1367
 
1331
- return ['subnetScore' => min(100.0, $score)];
1368
+ $finalScore = min(100.0, round($baseScore * $densityMultiplier * $distributionMultiplier * 10.0) / 10.0);
1369
+
1370
+ return ['subnetScore' => $finalScore];
1332
1371
  }
1333
1372
 
1334
1373
  /**
@@ -1358,10 +1397,15 @@ class RequestUtils
1358
1397
  });
1359
1398
  $clusterData = array_values($clusterData);
1360
1399
 
1400
+ $userAgent = $context->getHeader('user-agent') ?? '';
1401
+ $subnet = self::getIpSubnet($context->clientIp) ?? 'unknown';
1402
+
1361
1403
  $found = false;
1362
1404
  foreach ($clusterData as &$entry) {
1363
1405
  if (isset($entry['ip']) && $entry['ip'] === $context->clientIp) {
1364
1406
  $entry['timestamp'] = $now;
1407
+ $entry['ua'] = $userAgent;
1408
+ $entry['subnet'] = $subnet;
1365
1409
  $found = true;
1366
1410
  break;
1367
1411
  }
@@ -1369,14 +1413,26 @@ class RequestUtils
1369
1413
  unset($entry);
1370
1414
 
1371
1415
  if (!$found) {
1372
- $clusterData[] = ['ip' => $context->clientIp, 'timestamp' => $now];
1416
+ $clusterData[] = [
1417
+ 'ip' => $context->clientIp,
1418
+ 'timestamp' => $now,
1419
+ 'ua' => $userAgent,
1420
+ 'subnet' => $subnet
1421
+ ];
1373
1422
  }
1374
1423
 
1375
1424
  $store->set($key, $clusterData, 600);
1376
1425
  $uniqueIpsCount = count($clusterData);
1377
1426
  $botnetClusterScore = 0.0;
1378
1427
  if ($uniqueIpsCount >= 2) {
1379
- $botnetClusterScore = min(100.0, round(100.0 * (1.0 - exp(-0.35 * ($uniqueIpsCount - 1))), 1));
1428
+ $uniqueSubnets = count(array_unique(array_filter(array_column($clusterData, 'subnet'))));
1429
+ $uniqueUserAgents = count(array_unique(array_filter(array_column($clusterData, 'ua'))));
1430
+
1431
+ $subnetMultiplier = $uniqueSubnets > 1 ? 1.3 : 0.6;
1432
+ $uaRotationMultiplier = $uniqueUserAgents > 1 ? 1.5 : 1.0;
1433
+
1434
+ $baseScore = 100.0 * (1.0 - exp(-0.35 * ($uniqueIpsCount - 1)));
1435
+ $botnetClusterScore = min(100.0, round($baseScore * $subnetMultiplier * $uaRotationMultiplier * 10.0) / 10.0);
1380
1436
  }
1381
1437
  return ['botnetClusterScore' => $botnetClusterScore];
1382
1438
  }