@webdecoy/fcaptcha 1.0.1 → 1.0.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/server.js +45 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webdecoy/fcaptcha",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Open source CAPTCHA with PoW, bot detection, and Vision AI protection",
5
5
  "main": "index.js",
6
6
  "exports": {
package/server.js CHANGED
@@ -42,13 +42,11 @@ const powChallengeStore = {
42
42
  };
43
43
 
44
44
  // Sign the challenge
45
- const sig = crypto.createHmac('sha256', SECRET_KEY)
45
+ challengeData.sig = crypto.createHmac('sha256', SECRET_KEY)
46
46
  .update(JSON.stringify(challengeData))
47
47
  .digest('hex')
48
48
  .slice(0, 16);
49
49
 
50
- challengeData.sig = sig;
51
-
52
50
  // Store challenge
53
51
  this.challenges.set(challengeId, {
54
52
  ...challengeData,
@@ -187,7 +185,8 @@ const WEIGHTS = {
187
185
  vision_ai: 0.15,
188
186
  headless: 0.15,
189
187
  automation: 0.10,
190
- behavioral: 0.20,
188
+ cdp: 0.12,
189
+ behavioral: 0.18,
191
190
  fingerprint: 0.10,
192
191
  rate_limit: 0.05,
193
192
  datacenter: 0.10,
@@ -383,6 +382,46 @@ function detectAutomation(signals) {
383
382
  return detections;
384
383
  }
385
384
 
385
+ function detectCDP(signals) {
386
+ const detections = [];
387
+ const env = signals.environmental || {};
388
+ const cdp = env.cdp || {};
389
+
390
+ if (cdp.detected) {
391
+ const signalList = cdp.signals || [];
392
+ const signalCount = signalList.length;
393
+
394
+ // High-confidence signals
395
+ const highConfSignals = ['chromedriver_cdc', 'puppeteer_eval', 'cdp_script_injection'];
396
+ const hasHighConf = signalList.some(s => highConfSignals.includes(s));
397
+
398
+ if (hasHighConf) {
399
+ detections.push({
400
+ category: 'cdp',
401
+ score: 0.9,
402
+ confidence: 0.95,
403
+ reason: `CDP automation detected: ${signalList.join(', ')}`
404
+ });
405
+ } else if (signalCount >= 2) {
406
+ detections.push({
407
+ category: 'cdp',
408
+ score: 0.8,
409
+ confidence: 0.85,
410
+ reason: `Multiple CDP indicators: ${signalList.join(', ')}`
411
+ });
412
+ } else if (signalCount === 1) {
413
+ detections.push({
414
+ category: 'cdp',
415
+ score: 0.6,
416
+ confidence: 0.7,
417
+ reason: `CDP indicator: ${signalList.join(', ')}`
418
+ });
419
+ }
420
+ }
421
+
422
+ return detections;
423
+ }
424
+
386
425
  function detectBehavioral(signals) {
387
426
  const detections = [];
388
427
  const b = signals.behavioral || {};
@@ -585,8 +624,7 @@ function generateToken(ip, siteKey, score) {
585
624
  };
586
625
 
587
626
  const payload = JSON.stringify(data, Object.keys(data).sort());
588
- const sig = crypto.createHmac('sha256', SECRET_KEY).update(payload).digest('hex').slice(0, 16);
589
- data.sig = sig;
627
+ data.sig = crypto.createHmac('sha256', SECRET_KEY).update(payload).digest('hex').slice(0, 16);
590
628
 
591
629
  return Buffer.from(JSON.stringify(data)).toString('base64url');
592
630
  }
@@ -626,6 +664,7 @@ function runVerification(signals, ip, siteKey, userAgent, headers = {}, ja3Hash
626
664
  ...detectVisionAI(signals),
627
665
  ...detectHeadless(signals, userAgent),
628
666
  ...detectAutomation(signals),
667
+ ...detectCDP(signals),
629
668
  ...detectBehavioral(signals),
630
669
  ...detectFingerprint(signals, ip, siteKey),
631
670
  ...detectRateAbuse(ip, siteKey)