Download index.html from iuseonly/bots: direct link, hf CLI and curl.
- Browser
- Download file 6.28 kB
-
https://huggingface.co/spaces/iuseonly/bots/resolve/main/index.html
- Command line
-
hf download hf://spaces/iuseonly/bots/index.html
-
curl -L -o index.html https://huggingface.co/spaces/iuseonly/bots/resolve/main/index.html
6.28 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8"> | |
| <title>stealth-probe</title> | |
| <style> | |
| body { font-family: "Fira Mono", Menlo, monospace; background:#0d1117; color:#c9d1d9; padding:24px; } | |
| h1 { font-size: 1.1rem; color:#58a6ff; } | |
| code#jsonResult { white-space: pre; display:block; background:#161b22; padding:16px; border-radius:8px; } | |
| .badge { display:inline-block; padding:2px 8px; border-radius:4px; font-weight:bold; } | |
| .badge.bot { background:#f85149; color:#fff; } | |
| .badge.clean { background:#3fb950; color:#fff; } | |
| </style> | |
| </head> | |
| <body> | |
| <h1>stealth-probe — client-side automation fingerprint check</h1> | |
| <div id="badge"></div> | |
| <code class="language-json" id="jsonResult">{}</code> | |
| <script> | |
| (function () { | |
| "use strict"; | |
| function safe(fn, fallback) { | |
| try { return fn(); } catch (e) { return fallback; } | |
| } | |
| // --- 1. Automation object leaks (Selenium / old CDP shims) --------------- | |
| function detectCdpLeakKeys() { | |
| let suspects = [ | |
| "__webdriver_evaluate", "__selenium_evaluate", "__webdriver_script_function", | |
| "__webdriver_script_func", "__webdriver_script_fn", "__fxdriver_evaluate", | |
| "__driver_unwrapped", "__webdriver_unwrapped", "__selenium_unwrapped", | |
| "__fxdriver_unwrapped", "__driver_evaluate", "$cdc_asdjflasutopfhvcZLmcfl_", | |
| "$chrome_asyncScriptInfo", "domAutomation", "domAutomationController" | |
| ]; | |
| let found = []; | |
| try { | |
| for (let i = 0; i < suspects.length; i++) { | |
| if (suspects[i] in window) found.push(suspects[i]); | |
| } | |
| } catch (e) {} | |
| try { | |
| let winKeys = Object.getOwnPropertyNames(window); | |
| for (let j = 0; j < winKeys.length; j++) { | |
| if (winKeys[j].indexOf("cdc_") === 0 || winKeys[j].indexOf("__webdriver") === 0) { | |
| found.push(winKeys[j]); | |
| } | |
| } | |
| } catch (e) {} | |
| return found; | |
| } | |
| // --- 2. Function.toString native-code spoofing --------------------------- | |
| function functionsLookNative() { | |
| let fns = [window.alert, Function.prototype.bind, navigator.permissions ? navigator.permissions.query : null]; | |
| return fns.every(function (f) { | |
| if (!f) return true; | |
| return safe(function () { return f.toString().indexOf("[native code]") !== -1; }, false); | |
| }); | |
| } | |
| // --- 3. Canvas fingerprint sanity (blank / blocked canvas = automation tell) --- | |
| function canvasWorks() { | |
| return safe(function () { | |
| let c = document.createElement("canvas"); | |
| c.width = 220; c.height = 30; | |
| let ctx = c.getContext("2d"); | |
| ctx.textBaseline = "top"; | |
| ctx.font = "14px Arial"; | |
| ctx.fillStyle = "#f60"; | |
| ctx.fillRect(0, 0, 220, 30); | |
| ctx.fillStyle = "#069"; | |
| ctx.fillText("stealth-probe 🦊 canvas", 2, 2); | |
| let data = c.toDataURL(); | |
| return data.length > 100 && data !== "data:,"; | |
| }, false); | |
| } | |
| // --- 4. WebGL vendor/renderer consistency --------------------------------- | |
| function webglInfo() { | |
| return safe(function () { | |
| let c = document.createElement("canvas"); | |
| let gl = c.getContext("webgl") || c.getContext("experimental-webgl"); | |
| if (!gl) return { supported: false }; | |
| let dbg = gl.getExtension("WEBGL_debug_renderer_info"); | |
| return { | |
| supported: true, | |
| vendor: gl.getParameter(gl.VENDOR), | |
| renderer: gl.getParameter(gl.RENDERER), | |
| unmaskedVendor: dbg ? gl.getParameter(dbg.UNMASKED_VENDOR_WEBGL) : null, | |
| unmaskedRenderer: dbg ? gl.getParameter(dbg.UNMASKED_RENDERER_WEBGL) : null | |
| }; | |
| }, { supported: false }); | |
| } | |
| // --- 5. Headless-default screen resolution tell --------------------------- | |
| function hasHeadlessDefaultResolution() { | |
| // classic old-headless Chrome default viewport | |
| return (window.outerWidth === 0 || window.outerHeight === 0) || | |
| (screen.width === 800 && screen.height === 600); | |
| } | |
| // --- 6. Permissions API mismatch (a known Chrome headless tell) ----------- | |
| function permissionsInconsistent() { | |
| // Notification.permission === 'denied' while permissions.query resolves to 'prompt' | |
| // is asynchronous; we just record raw values here, evaluated further downstream if needed. | |
| return safe(function () { | |
| return typeof Notification === "undefined" ? null : Notification.permission; | |
| }, null); | |
| } | |
| // --- 7. Timing resolution jitter (automation frameworks sometimes clamp) -- | |
| function timingHasJitter() { | |
| let samples = []; | |
| for (let i = 0; i < 20; i++) samples.push(performance.now()); | |
| let allRounded = samples.every(function (v) { return v === Math.floor(v); }); | |
| return !allRounded; | |
| } | |
| let ua = navigator.userAgent || ""; | |
| let details = { | |
| hasWebdriverTrue: navigator.webdriver === true, | |
| hasBotUserAgent: /HeadlessChrome|bot|crawl|spider|slimerjs|phantomjs/i.test(ua), | |
| hasInconsistentChromeObject: /Chrome/.test(ua) && typeof window.chrome !== "object", | |
| hasNoPlugins: (navigator.plugins ? navigator.plugins.length : 0) === 0, | |
| hasNoLanguages: !(navigator.languages && navigator.languages.length), | |
| cdpLeakKeys: detectCdpLeakKeys(), | |
| functionsSpoofed: !functionsLookNative(), | |
| canvasBlocked: !canvasWorks(), | |
| webgl: webglInfo(), | |
| hasHeadlessDefaultScreenResolution: hasHeadlessDefaultResolution(), | |
| hardwareConcurrency: navigator.hardwareConcurrency || 0, | |
| hasHighHardwareConcurrency: (navigator.hardwareConcurrency || 0) > 32, | |
| notificationPermission: permissionsInconsistent(), | |
| hasSuspiciousTimingResolution: !timingHasJitter(), | |
| userAgent: ua | |
| }; | |
| let isBot = details.hasWebdriverTrue || | |
| details.hasBotUserAgent || | |
| details.hasInconsistentChromeObject || | |
| details.cdpLeakKeys.length > 0 || | |
| details.functionsSpoofed || | |
| details.canvasBlocked || | |
| details.hasHeadlessDefaultScreenResolution; | |
| let result = { isBot: isBot, details: details }; | |
| document.getElementById("jsonResult").textContent = JSON.stringify(result, null, 2); | |
| let badge = document.getElementById("badge"); | |
| badge.innerHTML = '<span class="badge ' + (isBot ? "bot" : "clean") + '">' + | |
| (isBot ? "DETECTED AS BOT" : "CLEAN") + "</span>"; | |
| // Expose for Playwright evaluate() convenience without re-parsing text. | |
| window.__stealthProbeResult = result; | |
| })(); | |
| </script> | |
| </body> | |
| </html> |