@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
|
@@ -412,54 +412,80 @@ const ClientLibrary = {
|
|
|
412
412
|
},
|
|
413
413
|
|
|
414
414
|
/**
|
|
415
|
-
* Injects invisible phantom interactive elements to trap bots (focus/hover).
|
|
415
|
+
* Injects invisible phantom interactive elements and forms within a closed Shadow DOM container to trap bots (focus/hover/click).
|
|
416
416
|
*/
|
|
417
417
|
injectPhantomTraps() {
|
|
418
|
-
if (typeof document === 'undefined') return;
|
|
418
|
+
if (typeof document === 'undefined' || !document.body) return;
|
|
419
|
+
|
|
420
|
+
const host = document.createElement('div');
|
|
421
|
+
host.setAttribute('aria-hidden', 'true');
|
|
422
|
+
host.style.position = 'absolute';
|
|
423
|
+
host.style.left = '-9999px';
|
|
424
|
+
host.style.top = '-9999px';
|
|
425
|
+
host.style.width = '0';
|
|
426
|
+
host.style.height = '0';
|
|
427
|
+
host.style.overflow = 'hidden';
|
|
428
|
+
|
|
429
|
+
const shadow = typeof host.attachShadow === 'function'
|
|
430
|
+
? host.attachShadow({ mode: 'closed' })
|
|
431
|
+
: host;
|
|
432
|
+
|
|
433
|
+
const style = document.createElement('style');
|
|
434
|
+
style.textContent = `
|
|
435
|
+
:host {
|
|
436
|
+
position: absolute;
|
|
437
|
+
left: -9999px;
|
|
438
|
+
top: -9999px;
|
|
439
|
+
width: 0;
|
|
440
|
+
height: 0;
|
|
441
|
+
overflow: hidden;
|
|
442
|
+
}
|
|
443
|
+
a, input, button, form {
|
|
444
|
+
opacity: 0.001;
|
|
445
|
+
pointer-events: auto;
|
|
446
|
+
}
|
|
447
|
+
`;
|
|
448
|
+
shadow.appendChild(style);
|
|
419
449
|
|
|
420
|
-
|
|
450
|
+
const triggerTrap = () => {
|
|
451
|
+
this.onHoneypotTrigger();
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
// 1. Phantom interactive link
|
|
421
455
|
const phantom = document.createElement('a');
|
|
422
456
|
phantom.href = '#';
|
|
423
457
|
// Random deceptive name to attract automated link/form parsers
|
|
424
458
|
const phantomNames = ['sys-session-recovery', 'auth-token-refresh', 'debug-console-login', 'admin-portal-access', 'security-bypass-bypass', 'recovery-key-session', 'api-key-test', 'client-secrets-access'];
|
|
425
459
|
phantom.id = phantomNames[Math.floor(secureRandom() * phantomNames.length)] + '-' + genRandStr(6);
|
|
426
460
|
phantom.className = genRandStr(8);
|
|
427
|
-
phantom.tabIndex = 0; // In natural tab flow
|
|
428
|
-
phantom.setAttribute('aria-hidden', 'true'); // Hidden from legitimate screen readers
|
|
429
|
-
|
|
430
|
-
// Invisible yet interactive style (1px x 1px, nearly transparent)
|
|
431
|
-
phantom.style.position = 'fixed';
|
|
432
|
-
phantom.style.top = '1px';
|
|
433
|
-
phantom.style.left = '1px';
|
|
434
|
-
phantom.style.width = '1px';
|
|
435
|
-
phantom.style.height = '1px';
|
|
436
|
-
phantom.style.opacity = '0.001';
|
|
437
|
-
phantom.style.zIndex = '99999';
|
|
438
|
-
phantom.style.overflow = 'hidden';
|
|
439
|
-
phantom.style.pointerEvents = 'auto';
|
|
440
|
-
|
|
441
|
-
const triggerTrap = () => {
|
|
442
|
-
this.onHoneypotTrigger();
|
|
443
|
-
};
|
|
444
|
-
|
|
461
|
+
phantom.tabIndex = 0; // In natural tab flow for crawler parsers
|
|
445
462
|
phantom.addEventListener('focus', triggerTrap, { passive: true });
|
|
446
463
|
phantom.addEventListener('mouseover', triggerTrap, { passive: true });
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
464
|
+
phantom.addEventListener('click', (e) => {
|
|
465
|
+
if (e && typeof e.preventDefault === 'function') e.preventDefault();
|
|
466
|
+
triggerTrap();
|
|
467
|
+
}, { passive: false });
|
|
468
|
+
|
|
469
|
+
// 2. Deceptive hidden form with bait input
|
|
470
|
+
const phantomForm = document.createElement('form');
|
|
471
|
+
phantomForm.action = '#';
|
|
472
|
+
phantomForm.tabIndex = -1;
|
|
473
|
+
const inputNames = ['session_token', 'admin_pwd', 'secret_key', 'auth_bypass'];
|
|
474
|
+
const phantomInput = document.createElement('input');
|
|
475
|
+
phantomInput.type = 'text';
|
|
476
|
+
phantomInput.name = inputNames[Math.floor(secureRandom() * inputNames.length)] + '_' + genRandStr(4);
|
|
477
|
+
phantomInput.tabIndex = 0;
|
|
478
|
+
phantomInput.autocomplete = 'off';
|
|
479
|
+
phantomInput.addEventListener('focus', triggerTrap, { passive: true });
|
|
480
|
+
phantomInput.addEventListener('input', triggerTrap, { passive: true });
|
|
481
|
+
phantomInput.addEventListener('click', triggerTrap, { passive: true });
|
|
482
|
+
phantomInput.addEventListener('change', triggerTrap, { passive: true });
|
|
483
|
+
|
|
484
|
+
phantomForm.appendChild(phantomInput);
|
|
485
|
+
shadow.appendChild(phantom);
|
|
486
|
+
shadow.appendChild(phantomForm);
|
|
487
|
+
|
|
488
|
+
document.body.appendChild(host);
|
|
463
489
|
},
|
|
464
490
|
|
|
465
491
|
/**
|
|
@@ -800,7 +826,7 @@ const ClientLibrary = {
|
|
|
800
826
|
});
|
|
801
827
|
|
|
802
828
|
// 3. Generate trap inputs inside a closed Shadow DOM
|
|
803
|
-
if (typeof document !== 'undefined' && honeypotFieldNames.length > 0) {
|
|
829
|
+
if (typeof document !== 'undefined' && honeypotFieldNames.length > 0 && document.body) {
|
|
804
830
|
const host = document.createElement('div');
|
|
805
831
|
host.setAttribute('aria-hidden', 'true');
|
|
806
832
|
host.style.position = 'absolute';
|
|
@@ -808,7 +834,9 @@ const ClientLibrary = {
|
|
|
808
834
|
host.style.height = '0';
|
|
809
835
|
host.style.overflow = 'hidden';
|
|
810
836
|
|
|
811
|
-
const shadow = host.attachShadow
|
|
837
|
+
const shadow = typeof host.attachShadow === 'function'
|
|
838
|
+
? host.attachShadow({ mode: 'closed' })
|
|
839
|
+
: host;
|
|
812
840
|
|
|
813
841
|
// Randomize classes, CSS variables, and layout tags
|
|
814
842
|
const wrapperClass = genRandStr(10);
|
|
@@ -858,6 +886,7 @@ const ClientLibrary = {
|
|
|
858
886
|
input.addEventListener('input', trigger, { passive: true });
|
|
859
887
|
input.addEventListener('change', trigger, { passive: true });
|
|
860
888
|
input.addEventListener('focus', trigger, { passive: true });
|
|
889
|
+
input.addEventListener('click', trigger, { passive: true });
|
|
861
890
|
|
|
862
891
|
// Polymorphic nesting of label and input
|
|
863
892
|
const nestingType = Math.floor(secureRandom() * 3);
|
|
@@ -1255,7 +1284,7 @@ const ClientLibrary = {
|
|
|
1255
1284
|
* @private
|
|
1256
1285
|
*/
|
|
1257
1286
|
injectTrapLinks(urls) {
|
|
1258
|
-
if (!urls || urls.length === 0 || typeof document === 'undefined') {
|
|
1287
|
+
if (!urls || urls.length === 0 || typeof document === 'undefined' || !document.body) {
|
|
1259
1288
|
return;
|
|
1260
1289
|
}
|
|
1261
1290
|
|
|
@@ -1266,7 +1295,9 @@ const ClientLibrary = {
|
|
|
1266
1295
|
host.style.height = '0';
|
|
1267
1296
|
host.style.overflow = 'hidden';
|
|
1268
1297
|
|
|
1269
|
-
const shadow = host.attachShadow
|
|
1298
|
+
const shadow = typeof host.attachShadow === 'function'
|
|
1299
|
+
? host.attachShadow({ mode: 'closed' })
|
|
1300
|
+
: host;
|
|
1270
1301
|
|
|
1271
1302
|
// Randomize classes, CSS variables, and layout tags
|
|
1272
1303
|
const wrapperClass = genRandStr(10);
|
|
@@ -1330,10 +1361,13 @@ const ClientLibrary = {
|
|
|
1330
1361
|
link.innerHTML = `<span>> ${i + 1}</span>`;
|
|
1331
1362
|
}
|
|
1332
1363
|
|
|
1333
|
-
const trigger = () => {
|
|
1364
|
+
const trigger = (e) => {
|
|
1365
|
+
if (e && typeof e.preventDefault === 'function') {
|
|
1366
|
+
e.preventDefault();
|
|
1367
|
+
}
|
|
1334
1368
|
this.onHoneypotTrigger();
|
|
1335
1369
|
};
|
|
1336
|
-
link.addEventListener('click', trigger, { passive:
|
|
1370
|
+
link.addEventListener('click', trigger, { passive: false });
|
|
1337
1371
|
link.addEventListener('focus', trigger, { passive: true });
|
|
1338
1372
|
link.addEventListener('mouseover', trigger, { passive: true });
|
|
1339
1373
|
|