| <!DOCTYPE html> |
| <html> |
| <head> |
| <title>Bot Detection Tests</title> |
| <style> |
| body { font-family: monospace; padding: 20px; background: #1a1a1a; color: #eee; } |
| .pass { color: #4caf50; } |
| .fail { color: #f44336; } |
| .warn { color: #ff9800; } |
| table { border-collapse: collapse; margin: 20px 0; width: 100%; } |
| td, th { border: 1px solid #444; padding: 8px; text-align: left; } |
| th { background: #333; } |
| h2 { color: #888; margin-top: 30px; } |
| </style> |
| </head> |
| <body> |
| <h1>π€ Bot Detection Tests</h1> |
| <p>Comprehensive checks based on bot.sannysoft.com and other detection methods</p> |
| |
| <h2>Critical Tests (must pass)</h2> |
| <table id="critical"> |
| <tr><th>Test</th><th>Result</th><th>Value</th></tr> |
| </table> |
| |
| <h2>Warning Tests (should pass)</h2> |
| <table id="warnings"> |
| <tr><th>Test</th><th>Result</th><th>Value</th></tr> |
| </table> |
| |
| <h2>Info</h2> |
| <table id="info"> |
| <tr><th>Property</th><th>Value</th></tr> |
| </table> |
| |
| <script> |
| const results = {}; |
| const criticalTable = document.getElementById('critical'); |
| const warnTable = document.getElementById('warnings'); |
| const infoTable = document.getElementById('info'); |
| |
| function addResult(name, passed, value, severity = 'critical') { |
| results[name] = { passed, value, severity }; |
| const table = severity === 'critical' ? criticalTable : warnTable; |
| const row = table.insertRow(); |
| row.innerHTML = ` |
| <td>${name}</td> |
| <td class="${passed ? 'pass' : (severity === 'warn' ? 'warn' : 'fail')}">${passed ? 'β PASS' : (severity === 'warn' ? 'β WARN' : 'β FAIL')}</td> |
| <td>${String(value).substring(0, 100)}</td> |
| `; |
| } |
| |
| function addInfo(name, value) { |
| const row = infoTable.insertRow(); |
| row.innerHTML = `<td>${name}</td><td>${String(value).substring(0, 150)}</td>`; |
| } |
| |
| |
| |
| |
| |
| |
| const webdriverValue = navigator.webdriver; |
| addResult('webdriver_value', webdriverValue === undefined || webdriverValue === false, |
| `navigator.webdriver = ${webdriverValue}`); |
| |
| |
| const webdriverExists = 'webdriver' in navigator; |
| addResult('webdriver_in_navigator', !webdriverExists, |
| `"webdriver" in navigator = ${webdriverExists}`); |
| |
| |
| const pluginsValid = navigator.plugins instanceof PluginArray; |
| addResult('plugins_instanceof', pluginsValid, |
| `navigator.plugins instanceof PluginArray = ${pluginsValid}`); |
| |
| |
| const hasPlugins = navigator.plugins && navigator.plugins.length > 0; |
| addResult('plugins_present', hasPlugins, |
| `navigator.plugins.length = ${navigator.plugins?.length || 0}`); |
| |
| |
| const chromeRuntime = !!(window.chrome && window.chrome.runtime); |
| addResult('chrome_runtime', chromeRuntime, |
| `window.chrome.runtime = ${chromeRuntime}`); |
| |
| |
| const ua = navigator.userAgent; |
| const isHeadlessUA = ua.includes('HeadlessChrome') || ua.includes('Headless'); |
| addResult('ua_not_headless', !isHeadlessUA, |
| isHeadlessUA ? 'Contains HeadlessChrome' : 'Normal Chrome UA'); |
| |
| |
| const hasLanguages = navigator.languages && navigator.languages.length > 0; |
| addResult('languages', hasLanguages, |
| `navigator.languages = ${navigator.languages?.join(', ') || 'none'}`); |
| |
| |
| let permissionsOk = false; |
| try { |
| permissionsOk = navigator.permissions && typeof navigator.permissions.query === 'function'; |
| } catch (e) {} |
| addResult('permissions_api', permissionsOk, |
| permissionsOk ? 'Available' : 'Broken/Missing'); |
| |
| |
| const hasCDPTraces = !!(window.cdc_adoQpoasnfa76pfcZLmcfl_Array || |
| window.cdc_adoQpoasnfa76pfcZLmcfl_Promise || |
| window.__webdriver_script_fn); |
| addResult('no_cdp_traces', !hasCDPTraces, |
| hasCDPTraces ? 'CDP traces found!' : 'Clean'); |
| |
| |
| |
| |
| |
| |
| const platform = navigator.platform; |
| let platformMatch = true; |
| if (ua.includes('Linux') && !platform.includes('Linux')) platformMatch = false; |
| if (ua.includes('Macintosh') && platform !== 'MacIntel') platformMatch = false; |
| if (ua.includes('Windows') && !platform.includes('Win')) platformMatch = false; |
| addResult('platform_ua_match', platformMatch, |
| `UA: ${ua.includes('Linux') ? 'Linux' : ua.includes('Mac') ? 'Mac' : 'Win'}, platform: ${platform}`, 'warn'); |
| |
| |
| let webglRenderer = 'unknown'; |
| try { |
| const canvas = document.createElement('canvas'); |
| const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl'); |
| if (gl) { |
| const dbg = gl.getExtension('WEBGL_debug_renderer_info'); |
| if (dbg) webglRenderer = gl.getParameter(dbg.UNMASKED_RENDERER_WEBGL); |
| } |
| } catch (e) {} |
| const isSwiftShader = webglRenderer.toLowerCase().includes('swiftshader'); |
| addResult('webgl_not_swiftshader', !isSwiftShader, webglRenderer, 'warn'); |
| |
| |
| const hasOuterDims = window.outerWidth > 0 && window.outerHeight > 0; |
| addResult('outer_dimensions', hasOuterDims, |
| `${window.outerWidth}x${window.outerHeight}`, 'warn'); |
| |
| |
| const cores = navigator.hardwareConcurrency || 0; |
| const coresOk = cores >= 2 && cores <= 64; |
| addResult('hardware_concurrency', coresOk, `${cores} cores`, 'warn'); |
| |
| |
| const deviceMem = navigator.deviceMemory; |
| const hasDeviceMem = deviceMem && deviceMem > 0; |
| addResult('device_memory', hasDeviceMem, `${deviceMem || 0} GB`, 'warn'); |
| |
| |
| const rtt = navigator.connection?.rtt; |
| const hasRtt = rtt !== undefined && rtt > 0; |
| addResult('connection_rtt', hasRtt, `${rtt || 0} ms`, 'warn'); |
| |
| |
| const screenOk = screen.width > 0 && screen.height > 0 && screen.colorDepth >= 24; |
| addResult('screen_dimensions', screenOk, |
| `${screen.width}x${screen.height} @ ${screen.colorDepth}bit`, 'warn'); |
| |
| |
| let notifOk = true; |
| try { |
| |
| notifOk = Notification.permission !== undefined; |
| } catch (e) { notifOk = false; } |
| addResult('notification_api', notifOk, |
| `Notification.permission = ${Notification.permission}`, 'warn'); |
| |
| |
| let toStringOk = true; |
| try { |
| const fnStr = Function.prototype.toString.call(navigator.permissions.query); |
| toStringOk = fnStr.includes('[native code]'); |
| } catch (e) { toStringOk = false; } |
| addResult('function_tostring', toStringOk, |
| toStringOk ? 'Native' : 'Modified', 'warn'); |
| |
| |
| |
| |
| addInfo('User Agent', navigator.userAgent); |
| addInfo('Platform', navigator.platform); |
| addInfo('Vendor', navigator.vendor); |
| addInfo('Languages', navigator.languages?.join(', ')); |
| addInfo('Timezone', Intl.DateTimeFormat().resolvedOptions().timeZone); |
| addInfo('Screen', `${screen.width}x${screen.height} @ ${screen.colorDepth}bit`); |
| addInfo('Window Inner', `${window.innerWidth}x${window.innerHeight}`); |
| addInfo('Window Outer', `${window.outerWidth}x${window.outerHeight}`); |
| addInfo('Device Pixel Ratio', window.devicePixelRatio); |
| addInfo('Cookies Enabled', navigator.cookieEnabled); |
| addInfo('Do Not Track', navigator.doNotTrack); |
| addInfo('WebGL Renderer', webglRenderer); |
| |
| |
| |
| |
| window.__botDetectResults = results; |
| |
| const criticalTests = Object.values(results).filter(r => r.severity === 'critical'); |
| const warnTests = Object.values(results).filter(r => r.severity === 'warn'); |
| const criticalPassed = criticalTests.filter(r => r.passed).length; |
| const warnPassed = warnTests.filter(r => r.passed).length; |
| |
| window.__botDetectScore = { |
| critical: criticalPassed, |
| criticalTotal: criticalTests.length, |
| warnings: warnPassed, |
| warningsTotal: warnTests.length, |
| total: criticalPassed + warnPassed, |
| totalTests: criticalTests.length + warnTests.length, |
| passed: criticalPassed === criticalTests.length |
| }; |
| |
| |
| const summaryDiv = document.createElement('div'); |
| summaryDiv.style.cssText = 'margin: 20px 0; padding: 20px; border-radius: 8px; font-size: 18px;'; |
| summaryDiv.style.background = window.__botDetectScore.passed ? '#1b5e20' : '#b71c1c'; |
| summaryDiv.innerHTML = ` |
| <strong>${window.__botDetectScore.passed ? 'β PASSED' : 'β FAILED'}</strong><br> |
| Critical: ${criticalPassed}/${criticalTests.length} | |
| Warnings: ${warnPassed}/${warnTests.length} |
| `; |
| document.body.insertBefore(summaryDiv, document.querySelector('h2')); |
| </script> |
| </body> |
| </html> |
|
|