@aientrophy/sdk 0.3.1 → 0.3.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.
@@ -211,7 +211,9 @@ const THREAT_EVENTS = /* @__PURE__ */ new Set([
211
211
  "init_signals",
212
212
  "automation_detected",
213
213
  "cross_context_mismatch",
214
- "headless_probe"
214
+ "headless_probe",
215
+ "script_injection",
216
+ "worker_integrity"
215
217
  ]);
216
218
  class CallbackManager {
217
219
  constructor() {
@@ -2360,6 +2362,516 @@ class HeadlessProbeDetector {
2360
2362
  });
2361
2363
  }
2362
2364
  }
2365
+ class ScriptInjectionDetector {
2366
+ constructor(transmitter) {
2367
+ __publicField(this, "transmitter");
2368
+ __publicField(this, "hasRun", false);
2369
+ __publicField(this, "injectedScriptCount", 0);
2370
+ __publicField(this, "cspViolations", []);
2371
+ this.transmitter = transmitter;
2372
+ }
2373
+ start() {
2374
+ if (this.hasRun || typeof window === "undefined") return;
2375
+ this.hasRun = true;
2376
+ this.startDOMObserver();
2377
+ this.startCSPMonitor();
2378
+ setTimeout(() => this.detect(), 1500);
2379
+ }
2380
+ detect() {
2381
+ const signals = {};
2382
+ let score = 0;
2383
+ try {
2384
+ const nativeIntegrity = this.checkNativeFunctionIntegrity();
2385
+ if (nativeIntegrity.issues.length > 0) {
2386
+ signals.nativeFunctionIntegrity = nativeIntegrity.issues;
2387
+ score += 25;
2388
+ }
2389
+ } catch (e) {
2390
+ }
2391
+ try {
2392
+ const overrides = this.checkPropertyOverrides();
2393
+ if (overrides.issues.length > 0) {
2394
+ signals.propertyOverrides = overrides.issues;
2395
+ score += 30;
2396
+ }
2397
+ } catch (e) {
2398
+ }
2399
+ if (this.injectedScriptCount > 0) {
2400
+ signals.domScriptInjection = {
2401
+ count: this.injectedScriptCount
2402
+ };
2403
+ score += 20;
2404
+ }
2405
+ if (this.cspViolations.length > 0) {
2406
+ signals.cspViolations = this.cspViolations.slice(0, 10);
2407
+ score += 15;
2408
+ }
2409
+ try {
2410
+ const globals = this.checkGlobalPollution();
2411
+ if (globals.length > 0) {
2412
+ signals.globalPollution = globals;
2413
+ score += 20;
2414
+ }
2415
+ } catch (e) {
2416
+ }
2417
+ try {
2418
+ const protoIssues = this.checkPrototypeIntegrity();
2419
+ if (protoIssues.length > 0) {
2420
+ signals.prototypeIntegrity = protoIssues;
2421
+ score += 20;
2422
+ }
2423
+ } catch (e) {
2424
+ }
2425
+ if (score > 0) {
2426
+ this.transmitter.send("script_injection", {
2427
+ signals,
2428
+ score,
2429
+ timestamp: Date.now()
2430
+ });
2431
+ }
2432
+ }
2433
+ /**
2434
+ * 1. Native Function Integrity
2435
+ * Checks if navigator.webdriver descriptor, navigator getters, and
2436
+ * Function.prototype.toString have been tampered with.
2437
+ */
2438
+ checkNativeFunctionIntegrity() {
2439
+ const issues = [];
2440
+ try {
2441
+ const desc = Object.getOwnPropertyDescriptor(navigator, "webdriver");
2442
+ if (desc) {
2443
+ if (desc.configurable === true) {
2444
+ issues.push("webdriver_descriptor_configurable");
2445
+ }
2446
+ if (desc.get) {
2447
+ const getterStr = Function.prototype.toString.call(desc.get);
2448
+ if (!/\[native code\]/.test(getterStr)) {
2449
+ issues.push("webdriver_non_native_getter");
2450
+ }
2451
+ }
2452
+ }
2453
+ } catch (e) {
2454
+ }
2455
+ try {
2456
+ const propsToCheck = ["userAgent", "platform", "languages", "hardwareConcurrency"];
2457
+ for (const prop of propsToCheck) {
2458
+ const protoDesc = Object.getOwnPropertyDescriptor(Navigator.prototype, prop);
2459
+ if (protoDesc && protoDesc.get) {
2460
+ const getterStr = Function.prototype.toString.call(protoDesc.get);
2461
+ if (!/\[native code\]/.test(getterStr)) {
2462
+ issues.push(`navigator_${prop}_non_native`);
2463
+ }
2464
+ }
2465
+ }
2466
+ } catch (e) {
2467
+ }
2468
+ try {
2469
+ const toStringStr = Function.prototype.toString.call(Function.prototype.toString);
2470
+ if (!/\[native code\]/.test(toStringStr)) {
2471
+ issues.push("function_tostring_overridden");
2472
+ }
2473
+ } catch (e) {
2474
+ }
2475
+ return { issues };
2476
+ }
2477
+ /**
2478
+ * 2. Property Override Detection
2479
+ * Checks for Object.defineProperty abuse on navigator,
2480
+ * proxy wrappers, and spoofed navigator.plugins.
2481
+ */
2482
+ checkPropertyOverrides() {
2483
+ const issues = [];
2484
+ try {
2485
+ const navigatorStr = Object.prototype.toString.call(navigator);
2486
+ if (navigatorStr !== "[object Navigator]") {
2487
+ issues.push("navigator_proxy_or_spoofed");
2488
+ }
2489
+ } catch (e) {
2490
+ }
2491
+ try {
2492
+ if (navigator.plugins) {
2493
+ const pluginsStr = Object.prototype.toString.call(navigator.plugins);
2494
+ if (pluginsStr !== "[object PluginArray]") {
2495
+ issues.push("plugins_spoofed");
2496
+ }
2497
+ if (Array.isArray(navigator.plugins)) {
2498
+ issues.push("plugins_is_array");
2499
+ }
2500
+ }
2501
+ } catch (e) {
2502
+ }
2503
+ try {
2504
+ if (navigator.mimeTypes) {
2505
+ const mimeStr = Object.prototype.toString.call(navigator.mimeTypes);
2506
+ if (mimeStr !== "[object MimeTypeArray]") {
2507
+ issues.push("mimetypes_spoofed");
2508
+ }
2509
+ }
2510
+ } catch (e) {
2511
+ }
2512
+ try {
2513
+ const descStr = Function.prototype.toString.call(Object.getOwnPropertyDescriptor);
2514
+ if (!/\[native code\]/.test(descStr)) {
2515
+ issues.push("getOwnPropertyDescriptor_overridden");
2516
+ }
2517
+ } catch (e) {
2518
+ }
2519
+ return { issues };
2520
+ }
2521
+ /**
2522
+ * 3. DOM Script Injection Monitoring
2523
+ * Sets up MutationObserver to watch for dynamically added <script> tags.
2524
+ */
2525
+ startDOMObserver() {
2526
+ try {
2527
+ if (typeof MutationObserver === "undefined") return;
2528
+ const observer = new MutationObserver((mutations) => {
2529
+ for (const mutation of mutations) {
2530
+ for (let i = 0; i < mutation.addedNodes.length; i++) {
2531
+ const node = mutation.addedNodes[i];
2532
+ if (node.nodeName === "SCRIPT") {
2533
+ const script = node;
2534
+ if (!script.src) {
2535
+ this.injectedScriptCount++;
2536
+ }
2537
+ }
2538
+ }
2539
+ }
2540
+ });
2541
+ observer.observe(document.documentElement, {
2542
+ childList: true,
2543
+ subtree: true
2544
+ });
2545
+ setTimeout(() => {
2546
+ try {
2547
+ observer.disconnect();
2548
+ } catch (e) {
2549
+ }
2550
+ }, 1e4);
2551
+ } catch (e) {
2552
+ }
2553
+ }
2554
+ /**
2555
+ * 4. CSP Violation Monitoring
2556
+ * Listens for securitypolicyviolation events indicating injection attempts.
2557
+ */
2558
+ startCSPMonitor() {
2559
+ try {
2560
+ const handler = (event) => {
2561
+ try {
2562
+ const entry = `${event.violatedDirective}|${event.blockedURI || "inline"}`;
2563
+ this.cspViolations.push(entry);
2564
+ } catch (e) {
2565
+ }
2566
+ };
2567
+ document.addEventListener("securitypolicyviolation", handler);
2568
+ setTimeout(() => {
2569
+ try {
2570
+ document.removeEventListener("securitypolicyviolation", handler);
2571
+ } catch (e) {
2572
+ }
2573
+ }, 1e4);
2574
+ } catch (e) {
2575
+ }
2576
+ }
2577
+ /**
2578
+ * 5. Global Variable Pollution
2579
+ * Checks for known automation framework globals and CDP-injected patterns.
2580
+ */
2581
+ checkGlobalPollution() {
2582
+ const found = [];
2583
+ const w = window;
2584
+ const d = document;
2585
+ const checks = [
2586
+ ["__webdriver_evaluate", () => !!d.__webdriver_evaluate],
2587
+ ["__selenium_evaluate", () => !!d.__selenium_evaluate],
2588
+ ["__webdriver_script_function", () => !!d.__webdriver_script_function],
2589
+ ["__webdriver_script_func", () => !!d.__webdriver_script_func],
2590
+ ["__webdriver_script_fn", () => !!d.__webdriver_script_fn],
2591
+ ["_Selenium_IDE_Recorder", () => !!w._Selenium_IDE_Recorder],
2592
+ ["__lastWatirAlert", () => !!w.__lastWatirAlert],
2593
+ ["__lastWatirConfirm", () => !!w.__lastWatirConfirm],
2594
+ ["__lastWatirPrompt", () => !!w.__lastWatirPrompt],
2595
+ ["_phantom", () => !!w._phantom],
2596
+ ["callPhantom", () => !!w.callPhantom],
2597
+ ["__nightmare", () => !!w.__nightmare],
2598
+ // Buffer and process should not exist in browser context
2599
+ ["Buffer", () => typeof w.Buffer === "function" && typeof w.Buffer.alloc === "function"],
2600
+ ["process", () => !!w.process && !!w.process.versions],
2601
+ // global redefined (in normal browsers, window.global is undefined)
2602
+ ["global_redefined", () => !!w.global && w.global !== w && typeof w.global === "object"],
2603
+ // emit on window (frameworks sometimes attach this)
2604
+ ["window_emit", () => typeof w.emit === "function"]
2605
+ ];
2606
+ for (const [name, check] of checks) {
2607
+ try {
2608
+ if (check()) found.push(name);
2609
+ } catch (e) {
2610
+ }
2611
+ }
2612
+ try {
2613
+ const keys = Object.keys(document);
2614
+ for (const key of keys) {
2615
+ if (/^cdc_|^__cdc_/.test(key)) {
2616
+ found.push(`cdc:${key}`);
2617
+ }
2618
+ }
2619
+ } catch (e) {
2620
+ }
2621
+ try {
2622
+ const wKeys = Object.keys(window);
2623
+ for (const key of wKeys) {
2624
+ if (/^cdc_|^__cdc_/.test(key)) {
2625
+ found.push(`cdc_window:${key}`);
2626
+ }
2627
+ }
2628
+ } catch (e) {
2629
+ }
2630
+ return found;
2631
+ }
2632
+ /**
2633
+ * 6. Prototype Chain Integrity
2634
+ * Verifies HTMLElement.prototype, document.createElement, and Event constructor.
2635
+ */
2636
+ checkPrototypeIntegrity() {
2637
+ const issues = [];
2638
+ try {
2639
+ const htmlProto = HTMLElement.prototype;
2640
+ const htmlProtoKeys = Object.getOwnPropertyNames(htmlProto);
2641
+ for (const key of htmlProtoKeys) {
2642
+ if (/^__selenium|^__webdriver|^__playwright|^__puppeteer/.test(key)) {
2643
+ issues.push(`htmlelement_proto_${key}`);
2644
+ }
2645
+ }
2646
+ } catch (e) {
2647
+ }
2648
+ try {
2649
+ const div = document.createElement("div");
2650
+ if (!(div instanceof HTMLDivElement)) {
2651
+ issues.push("createElement_not_genuine");
2652
+ }
2653
+ const divStr = Object.prototype.toString.call(div);
2654
+ if (divStr !== "[object HTMLDivElement]") {
2655
+ issues.push("createElement_wrong_tostring");
2656
+ }
2657
+ } catch (e) {
2658
+ }
2659
+ try {
2660
+ const evt = new Event("test");
2661
+ if (!(evt instanceof Event)) {
2662
+ issues.push("event_not_instance");
2663
+ }
2664
+ const evtStr = Object.prototype.toString.call(evt);
2665
+ if (evtStr !== "[object Event]") {
2666
+ issues.push("event_wrong_prototype");
2667
+ }
2668
+ } catch (e) {
2669
+ }
2670
+ try {
2671
+ const createStr = Function.prototype.toString.call(document.createElement);
2672
+ if (!/\[native code\]/.test(createStr)) {
2673
+ issues.push("createElement_overridden");
2674
+ }
2675
+ } catch (e) {
2676
+ }
2677
+ return issues;
2678
+ }
2679
+ }
2680
+ class WorkerIntegrityDetector {
2681
+ constructor(transmitter) {
2682
+ __publicField(this, "transmitter");
2683
+ __publicField(this, "hasRun", false);
2684
+ this.transmitter = transmitter;
2685
+ }
2686
+ start() {
2687
+ if (this.hasRun || typeof window === "undefined") return;
2688
+ this.hasRun = true;
2689
+ setTimeout(() => this.detect(), 2e3);
2690
+ }
2691
+ async detect() {
2692
+ try {
2693
+ if (typeof Worker === "undefined" || typeof Blob === "undefined") return;
2694
+ const mainValues = {
2695
+ webdriver: !!navigator.webdriver,
2696
+ userAgent: navigator.userAgent || "",
2697
+ platform: navigator.platform || "",
2698
+ languages: JSON.stringify(navigator.languages || []),
2699
+ hardwareConcurrency: navigator.hardwareConcurrency || 0,
2700
+ dateNow: Date.now(),
2701
+ perfNow: performance.now(),
2702
+ toStringNative: false
2703
+ };
2704
+ try {
2705
+ mainValues.toStringNative = /\[native code\]/.test(
2706
+ Function.prototype.toString.call(Array.prototype.push)
2707
+ );
2708
+ } catch (_e) {
2709
+ mainValues.toStringNative = false;
2710
+ }
2711
+ const workerResult = await this.runWorker(mainValues);
2712
+ if (!workerResult) return;
2713
+ const signals = {};
2714
+ let score = 0;
2715
+ const navMismatches = [];
2716
+ if (!mainValues.webdriver && workerResult.webdriver === true) {
2717
+ navMismatches.push("webdriver_spoofed");
2718
+ score += 40;
2719
+ } else if (workerResult.webdriver !== mainValues.webdriver) {
2720
+ navMismatches.push("webdriver_mismatch");
2721
+ score += 30;
2722
+ }
2723
+ if (workerResult.userAgent !== mainValues.userAgent) {
2724
+ navMismatches.push("userAgent_mismatch");
2725
+ score += 30;
2726
+ }
2727
+ if (workerResult.platform !== mainValues.platform) {
2728
+ navMismatches.push("platform_mismatch");
2729
+ score += 30;
2730
+ }
2731
+ if (workerResult.languages !== mainValues.languages) {
2732
+ navMismatches.push("languages_mismatch");
2733
+ score += 30;
2734
+ }
2735
+ if (workerResult.hardwareConcurrency !== mainValues.hardwareConcurrency) {
2736
+ navMismatches.push("hardwareConcurrency_mismatch");
2737
+ score += 30;
2738
+ }
2739
+ if (navMismatches.length > 0) {
2740
+ signals.navigatorMismatch = navMismatches;
2741
+ }
2742
+ const benchmarkMs = workerResult.benchmarkMs;
2743
+ if (typeof benchmarkMs === "number") {
2744
+ if (benchmarkMs < 1 || benchmarkMs > 500) {
2745
+ signals.benchmarkAnomaly = {
2746
+ benchmarkMs,
2747
+ reason: benchmarkMs < 1 ? "abnormally_fast" : "abnormally_slow"
2748
+ };
2749
+ score += 20;
2750
+ }
2751
+ }
2752
+ if (workerResult.cryptoEntropy === false) {
2753
+ signals.cryptoMock = {
2754
+ entropy: false,
2755
+ values: workerResult.cryptoValues
2756
+ };
2757
+ score += 15;
2758
+ }
2759
+ const timeDelta = Math.abs(workerResult.dateNow - mainValues.dateNow);
2760
+ if (timeDelta > 1e3) {
2761
+ signals.timeManipulation = {
2762
+ mainDateNow: mainValues.dateNow,
2763
+ workerDateNow: workerResult.dateNow,
2764
+ deltaMs: timeDelta
2765
+ };
2766
+ score += 15;
2767
+ }
2768
+ if (!workerResult.toStringNative || !mainValues.toStringNative) {
2769
+ const toStringSignals = [];
2770
+ if (!workerResult.toStringNative) toStringSignals.push("worker_tampered");
2771
+ if (!mainValues.toStringNative) toStringSignals.push("main_tampered");
2772
+ signals.toStringTampering = toStringSignals;
2773
+ score += 20;
2774
+ }
2775
+ if (score > 0) {
2776
+ this.transmitter.send("worker_integrity", {
2777
+ signals,
2778
+ score,
2779
+ timestamp: Date.now()
2780
+ });
2781
+ }
2782
+ } catch (_e) {
2783
+ }
2784
+ }
2785
+ /**
2786
+ * Spawn an inline Web Worker via Blob URL and collect integrity signals.
2787
+ * Returns null if Worker is not supported or times out.
2788
+ */
2789
+ runWorker(mainValues) {
2790
+ return new Promise((resolve) => {
2791
+ try {
2792
+ const workerCode = `
2793
+ self.onmessage = function(e) {
2794
+ var results = {};
2795
+
2796
+ // 1. Navigator check
2797
+ try {
2798
+ results.webdriver = !!navigator.webdriver;
2799
+ results.userAgent = navigator.userAgent || '';
2800
+ results.platform = navigator.platform || '';
2801
+ results.languages = JSON.stringify(navigator.languages || []);
2802
+ results.hardwareConcurrency = navigator.hardwareConcurrency || 0;
2803
+ } catch(ex) {
2804
+ results.webdriver = false;
2805
+ results.userAgent = '';
2806
+ results.platform = '';
2807
+ results.languages = '[]';
2808
+ results.hardwareConcurrency = 0;
2809
+ }
2810
+
2811
+ // 2. Performance benchmark
2812
+ try {
2813
+ var start = performance.now();
2814
+ var sum = 0;
2815
+ for (var i = 0; i < 1000000; i++) sum += i;
2816
+ results.benchmarkMs = performance.now() - start;
2817
+ } catch(ex) {
2818
+ results.benchmarkMs = -1;
2819
+ }
2820
+
2821
+ // 3. Crypto check
2822
+ try {
2823
+ var arr = new Uint32Array(4);
2824
+ crypto.getRandomValues(arr);
2825
+ results.cryptoEntropy = arr[0] !== arr[1] && arr[1] !== arr[2] && arr[0] !== 0;
2826
+ results.cryptoValues = Array.from(arr);
2827
+ } catch(ex) {
2828
+ results.cryptoEntropy = false;
2829
+ results.cryptoValues = [];
2830
+ }
2831
+
2832
+ // 4. Time check
2833
+ results.dateNow = Date.now();
2834
+ results.perfNow = performance.now();
2835
+
2836
+ // 5. toString integrity
2837
+ try {
2838
+ results.toStringNative = /\\[native code\\]/.test(
2839
+ Function.prototype.toString.call(Array.prototype.push)
2840
+ );
2841
+ } catch(ex) {
2842
+ results.toStringNative = false;
2843
+ }
2844
+
2845
+ self.postMessage(results);
2846
+ };
2847
+ `;
2848
+ const blob = new Blob([workerCode], { type: "application/javascript" });
2849
+ const url = URL.createObjectURL(blob);
2850
+ const worker = new Worker(url);
2851
+ const timeout = setTimeout(() => {
2852
+ worker.terminate();
2853
+ URL.revokeObjectURL(url);
2854
+ resolve(null);
2855
+ }, 5e3);
2856
+ worker.onmessage = (e) => {
2857
+ clearTimeout(timeout);
2858
+ worker.terminate();
2859
+ URL.revokeObjectURL(url);
2860
+ resolve(e.data);
2861
+ };
2862
+ worker.onerror = () => {
2863
+ clearTimeout(timeout);
2864
+ worker.terminate();
2865
+ URL.revokeObjectURL(url);
2866
+ resolve(null);
2867
+ };
2868
+ worker.postMessage({ mainValues });
2869
+ } catch (_e) {
2870
+ resolve(null);
2871
+ }
2872
+ });
2873
+ }
2874
+ }
2363
2875
  const COOKIE_NAME = "__aie_token";
2364
2876
  const RENEWAL_MARGIN_MS = 5 * 60 * 1e3;
2365
2877
  class CrawlProtect {
@@ -2541,6 +3053,8 @@ class SecuritySDK {
2541
3053
  __publicField(this, "cloudEnvironmentDetector");
2542
3054
  __publicField(this, "crossContextDetector");
2543
3055
  __publicField(this, "headlessProbeDetector");
3056
+ __publicField(this, "scriptInjectionDetector");
3057
+ __publicField(this, "workerIntegrityDetector");
2544
3058
  __publicField(this, "crawlProtect", null);
2545
3059
  __publicField(this, "initialized", false);
2546
3060
  __publicField(this, "wasmService");
@@ -2562,6 +3076,8 @@ class SecuritySDK {
2562
3076
  this.cloudEnvironmentDetector = new CloudEnvironmentDetector(this.transmitter);
2563
3077
  this.crossContextDetector = new CrossContextDetector(this.transmitter);
2564
3078
  this.headlessProbeDetector = new HeadlessProbeDetector(this.transmitter);
3079
+ this.scriptInjectionDetector = new ScriptInjectionDetector(this.transmitter);
3080
+ this.workerIntegrityDetector = new WorkerIntegrityDetector(this.transmitter);
2565
3081
  }
2566
3082
  async init(config) {
2567
3083
  var _a, _b;
@@ -2583,9 +3099,16 @@ class SecuritySDK {
2583
3099
  }
2584
3100
  const devtoolsEnabled = ((_b = config.serverConfig) == null ? void 0 : _b.devtoolsDetection) ?? !config.debug;
2585
3101
  if (devtoolsEnabled) {
2586
- import("../anti-debug-CRuvY4WC.js").then(({ AntiDebug }) => {
3102
+ import("../anti-debug-Cf0ePnTv.js").then(({ AntiDebug }) => {
2587
3103
  AntiDebug.start();
2588
- import("../console-DbZZ4Ctg.js").then(({ ConsoleDetector }) => {
3104
+ AntiDebug.setOnDevtoolsMaxed(() => {
3105
+ this.transmitter.send("devtools_force_close", {
3106
+ reason: "devtools_threshold_exceeded",
3107
+ detectionCount: 3,
3108
+ maxThreat: true
3109
+ });
3110
+ });
3111
+ import("../console-n38-3CrG.js").then(({ ConsoleDetector }) => {
2589
3112
  new ConsoleDetector(() => {
2590
3113
  this.transmitter.send("devtools_open", { detected: true });
2591
3114
  }).start();
@@ -2639,6 +3162,8 @@ class SecuritySDK {
2639
3162
  this.cloudEnvironmentDetector.start();
2640
3163
  this.crossContextDetector.start();
2641
3164
  this.headlessProbeDetector.start();
3165
+ this.scriptInjectionDetector.start();
3166
+ this.workerIntegrityDetector.start();
2642
3167
  }
2643
3168
  }
2644
3169
  const securitySDK = new SecuritySDK();
@@ -1,8 +1,8 @@
1
1
  {
2
- "generated": "2026-03-20T02:39:39.149Z",
2
+ "generated": "2026-03-20T07:11:02.283Z",
3
3
  "algorithm": "sha384",
4
4
  "hashes": {
5
- "core.js": "sha384-a9oAPKIopFcC2T2/9FpPpgShfpq4tmSJuIAjkcTXEh2IdydxjJ5V642FuwONhhNv",
5
+ "core.js": "sha384-6X6rQ1r2g8Xe7Ip9yTnbfB4yCg1NJ4eQBROEDFGAHLDngu98b3ed7XTzR5zTVWx4",
6
6
  "core.wasm": "sha384-fPJjZg5frGy3uptl1c6t4ekPOoQRQPquQVQEbrMf09T7mCur5iJVX4gGqkRfu93q",
7
7
  "loader.js": "sha384-0v1eaWmQUDG7Xzh8ujnAFroO2azUb0n547CCqAL1opB0WUltJC8WMyV8e1XoKf2R"
8
8
  }
@@ -33,6 +33,8 @@ declare class SecuritySDK {
33
33
  private cloudEnvironmentDetector;
34
34
  private crossContextDetector;
35
35
  private headlessProbeDetector;
36
+ private scriptInjectionDetector;
37
+ private workerIntegrityDetector;
36
38
  private crawlProtect;
37
39
  private initialized;
38
40
  private wasmService;
@@ -0,0 +1,56 @@
1
+ import { Transmitter } from '../transport';
2
+ /**
3
+ * ScriptInjectionDetector — Detects script injection attacks.
4
+ *
5
+ * Defends against SeleniumBase's insertScript, Puppeteer's evaluateOnNewDocument,
6
+ * and similar techniques that inject JavaScript before or after page load.
7
+ *
8
+ * Detection layers:
9
+ * 1. Native function integrity (navigator property tampering)
10
+ * 2. Property override detection (defineProperty / Proxy on navigator)
11
+ * 3. DOM script injection monitoring (MutationObserver)
12
+ * 4. CSP violation monitoring (securitypolicyviolation events)
13
+ * 5. Global variable pollution (automation framework globals)
14
+ * 6. Prototype chain integrity (HTMLElement, Event, createElement)
15
+ */
16
+ export declare class ScriptInjectionDetector {
17
+ private transmitter;
18
+ private hasRun;
19
+ private injectedScriptCount;
20
+ private cspViolations;
21
+ constructor(transmitter: Transmitter);
22
+ start(): void;
23
+ private detect;
24
+ /**
25
+ * 1. Native Function Integrity
26
+ * Checks if navigator.webdriver descriptor, navigator getters, and
27
+ * Function.prototype.toString have been tampered with.
28
+ */
29
+ private checkNativeFunctionIntegrity;
30
+ /**
31
+ * 2. Property Override Detection
32
+ * Checks for Object.defineProperty abuse on navigator,
33
+ * proxy wrappers, and spoofed navigator.plugins.
34
+ */
35
+ private checkPropertyOverrides;
36
+ /**
37
+ * 3. DOM Script Injection Monitoring
38
+ * Sets up MutationObserver to watch for dynamically added <script> tags.
39
+ */
40
+ private startDOMObserver;
41
+ /**
42
+ * 4. CSP Violation Monitoring
43
+ * Listens for securitypolicyviolation events indicating injection attempts.
44
+ */
45
+ private startCSPMonitor;
46
+ /**
47
+ * 5. Global Variable Pollution
48
+ * Checks for known automation framework globals and CDP-injected patterns.
49
+ */
50
+ private checkGlobalPollution;
51
+ /**
52
+ * 6. Prototype Chain Integrity
53
+ * Verifies HTMLElement.prototype, document.createElement, and Event constructor.
54
+ */
55
+ private checkPrototypeIntegrity;
56
+ }
@@ -0,0 +1,26 @@
1
+ import { Transmitter } from '../transport';
2
+ /**
3
+ * WorkerIntegrityDetector — Web Worker 격리 환경을 이용한 브라우저 무결성 검증.
4
+ *
5
+ * SeleniumBase/Puppeteer의 insertScript는 메인 스레드에만 영향을 주므로,
6
+ * Worker 내부에서 독립적으로 브라우저 상태를 검증하면 스푸핑을 탐지할 수 있음.
7
+ *
8
+ * Detection:
9
+ * 1. Navigator 일관성 — Worker vs 메인 스레드 navigator 속성 비교
10
+ * 2. Performance 벤치마크 — 마이크로 벤치마크로 비정상 실행 속도 탐지
11
+ * 3. Crypto API 검증 — crypto.getRandomValues 엔트로피 확인
12
+ * 4. Date/Time 일관성 — Worker vs 메인 스레드 시간 불일치 탐지
13
+ * 5. Function.prototype.toString 무결성 — 네이티브 함수 변조 탐지
14
+ */
15
+ export declare class WorkerIntegrityDetector {
16
+ private transmitter;
17
+ private hasRun;
18
+ constructor(transmitter: Transmitter);
19
+ start(): void;
20
+ private detect;
21
+ /**
22
+ * Spawn an inline Web Worker via Blob URL and collect integrity signals.
23
+ * Returns null if Worker is not supported or times out.
24
+ */
25
+ private runWorker;
26
+ }
@@ -3,10 +3,17 @@ export declare class AntiDebug {
3
3
  private static intervalId;
4
4
  static start(): void;
5
5
  static stop(): void;
6
+ /** Set callback for when DevTools detection exceeds threshold (called by SDK core). */
7
+ static setOnDevtoolsMaxed(callback: () => void): void;
8
+ /** Called by ConsoleDetector or size detection when DevTools is detected. */
9
+ static reportDevtoolsDetection(): void;
6
10
  /** Returns saved original console methods (bound to console). */
7
11
  static getOriginalConsole(): Record<string, Function>;
12
+ private static handleDevtoolsMaxed;
8
13
  private static saveConsole;
9
14
  private static preventDevTools;
10
15
  private static debuggerCheck;
16
+ /** Block F12, Ctrl+Shift+I/J/C, Ctrl+U and right-click */
17
+ private static blockDevToolsKeys;
11
18
  private static disableConsole;
12
19
  }