Fingerprint Checker

Desktop Chrome / Android Chrome / iOS Safari / iOS CriOS. v1.0
Fix Log
v1.0 (2026-02-25) — 56 секций, ~73 проверки

[FIX] glParamsCheck: Mali maxTextureSize — реальные значения не 8192
Было: Mali maxTex>8192 → FAIL (лимит Mali<=8192)
Причина: реальные Mali GPU на Android репортят maxTex=16383 (2^14-1) через OpenGL ES, Chrome Android обрезает до 8192. Антидетекты подставляют ровное 16384 (степень двойки).
Пруф: gpuinfo.org Mali-G57=16383, Mali-G57 MC2=16383, Mali-G68=16383, Mali-G715=65536, Mali-G52=16383.
Новая проверка: maxTex==16384 (ровная степень двойки) на Mali = FAIL, т.к. реальный Mali репортит 16383.

[FIX] batteryCheck: FAIL → WARN (полностью заряженный телефон = desktop signature)
Было: charging=true, level=1, chargingTime=0, dischargingTime=Infinity → FAIL
Причина: полностью заряженный телефон на зарядке даёт идентичную сигнатуру что и desktop PC на AC. Неотличимы по одному снимку.
Пруф: реальный Samsung Galaxy A13 (Chrome 126) — заряжен на 100%, batteryCheck=FAIL.

[FIX] portScan: antidetect FAIL → WARN при ненадёжной калибровке
Было: antidetectPortCheck=FAIL даже при reliable=false
Причина: при ненадёжной калибровке (median >100ms) все быстрые ответы считаются OPEN, но это может быть быстрый RST от сетевого оборудования (VPN, NAT). Cloud Phone Selectel показал 6 false positive антидетект-портов.
Новая логика: reliable=false → WARN вместо FAIL для antidetect и INFO вместо WARN для remote access.

[FIX] mediaCheck: hover:hover на Samsung дисплеях — не FAIL, а WARN
Было: hover:hover на mobile → FAIL
Причина: Samsung touchscreen kernel driver репортит hover:hover=true на всех устройствах с Samsung дисплеями (Samsung, Vivo, Oppo и др.). pointer:fine — надёжный индикатор десктопа, hover:hover одна — не надёжна.
Пруф: Ctrl blog: Samsung hover bug. Подтверждено: реальный Vivo X90+ (Chrome 144) и Samsung S24 Ultra (WebView).

[FIX] glParamsCheck: добавлен PowerVR с лимитом maxTex<=8192
Причина: реальный PowerVR GE8322 имеет maxTex=8192. Kameleo подставлял 16384 — спуф.
Пруф: gpuinfo.org PowerVR GE8322=8192.

[FIX] mediaCheck: hover:hover Samsung WARN → OK при прохождении всех mobile-проверок
Было: hover:hover на mobile без pointer:fine → WARN (всегда)
Причина: если все mobile-проверки пройдены (mobileIssues=0), это подтверждённый Samsung display bug, а не аномалия. На антидетектах будут другие FAIL.
Апгрейд: после вычисления mobileEmulationCheck, если WARN hover + mobileIssues==0 → OK с пометкой.

[FIX] webrtcCheck: WARN → INFO на мобильных устройствах
Было: любой exposed local IP → WARN
Причина: на реальных мобильных устройствах mDNS маскировка часто не работает, локальный IP (10.x, 192.168.x) — норма. WARN уместен только для десктопа.

[FIX] glParamsCheck: убран ложный PARTIAL SPOOF для Adreno
Было: tex=8192 + buf=16384 → FAIL: PARTIAL SPOOF
Причина: Adreno 7xx/8xx реально имеют maxTextureSize=8192 и maxRenderBufSize=16384. Это аппаратная особенность, не спуф.
Пруф: реальный Adreno (TM) 810 на Snapdragon 8 Elite (Chrome 145, Android).

[FIX] compTexCheck: S3TC допустим на Adreno GPU
Было: S3TC на mobile → WARN: desktop texture on mobile
Причина: Qualcomm Adreno поддерживает S3TC (DXT1/DXT5) аппаратно, в отличие от большинства мобильных GPU (Mali, PowerVR).
Пруф: hasS3TC=true на реальном Adreno 810. Проверка оставлена для не-Adreno мобильных GPU.

[FIX] apiGapCheck: убраны SerialPort и FileSystemWritable из gap-проверки Android
Было: наличие SerialPort/FileSystemWritable на Android → FAIL: API gap
Причина: оба API доступны и функциональны на Android Chrome 145. navigator.serial.getPorts() resolve (не reject).
Пруф: Chrome Status указывает desktop-only, но реальный тест на Android Chrome 145 показал что getPorts() работает. Ground truth устройства > документация.

[FIX] deviceApiPlatformCheck: Bluetooth/USB/Serial не desktop-only
Было: bluetooth/usb/serial на mobile → FAIL: desktop-only APIs on mobile
Причина: Web Bluetooth (Chrome 56+) и WebUSB (Chrome 61+) официально поддерживаются на Android Chrome. Web Serial exposed и функционален.
Пруф: Chrome Bluetooth docs — «available for Android, Chrome OS, Linux, macOS, and Windows». Проверка оставлена для iOS и Firefox.

[ADD] Секция 55: Mobile Emulation Detection
7 проверок для детекции десктопного Chrome, притворяющегося мобильным: screen width, DPR, physical resolution, scrollbar width, outerHeight/innerHeight, vibrate() API, DeviceMotion sensor data.
DeviceMotion — самый сильный сигнал: невозможно подделать без реального акселерометра. iOS пропускается (требует requestPermission gesture).

[FIX] hwcCheck: iOS 18+ показывает >2 ядер
Было: hwConcurrency > 2 на iOS → FAIL
Причина: WebKit документирует cap=2 на iOS (WebKit bug #132588). Но реальный iPhone 16 Pro (iOS 18.6.2) показывает 4. iOS 18+ видимо поднял cap. Safari 26 (WWDC25) будет рандомизировать значение через AFP.
Пруф: реальный iPhone 16 Pro, Safari 18.6, hardwareConcurrency=4. Лимит поднят до 8. Точный changelog не найден.

[UPDATE] compTexCheck: S3TC на Apple GPU → INFO (не OK)
CanIUse: Safari iOS НЕ поддерживает S3TC (все версии 3.2-26.4). Apple docs: Metal на iOS не поддерживает BC/S3TC форматы.
Но реальный iPhone 16 Pro показывает hasS3TC=true. Возможно software decode или A18 Pro добавил поддержку. Уровень: INFO (не WARN, не OK).

[FIX] plugins/pdfViewer: Safari iOS 18+ репортит plugins=5
Было: plugins > 0 на mobile → FAIL
Причина: WHATWG HTML Standard §8.9.1.6: при pdfViewerEnabled=true возвращается ровно 5 plugins ("PDF Viewer", "Chrome PDF Viewer", "Chromium PDF Viewer", "Microsoft Edge PDF Viewer", "WebKit built-in PDF"). WebKit source реализует этот стандарт.
Пруф: стандартное кросс-браузерное поведение для уменьшения fingerprint surface. Safari iOS 18+ присоединился к Chrome/Firefox.

[FIX] voicesCheck: iOS голоса с локализованными именами
Было: no Apple voices on iOS → WARN (искал "Samantha"/"Apple" в имени)
Причина: iOS с русской локалью возвращает 223 голоса с именами на разных языках ("Маджед", "Daria", "Монсе") без маркера "Apple". Количество голосов (200+) — надёжный iOS-маркер: Android ~5-50, Windows ~20-30.
Пруф: реальный iPhone 16 Pro. Порог снижен: >50 голосов = OK.

[FIX] mathCheck: JSC expm1 маркер достаточен
Было: JSC определялся только если expm1 И sinh не совпадают → iPhone 16 Pro: expm1≠, sinh= → V8 → FAIL
Причина: Math.expm1(1) использует разную внутреннюю реализацию в JSC vs V8. На iOS 18+ Math.sinh(1) может совпадать с полиномом. expm1 остаётся надёжным маркером JSC.
Пруф: реальный iPhone 16 Pro, mathExpm1Match=false. Конкретный WebKit commit не найден.

[FIX] stackEngineCheck: JSC и SpiderMonkey оба используют @ формат
Было: "@" в stack → SpiderMonkey → FAIL на iOS
Причина: MDN Error.stack: JSC и SpiderMonkey оба используют "func@url:line:col". Различие: JSC пишет "global code@" на top-level, SpiderMonkey — "@url". Внутри функций формат идентичен.
Пруф: реальный iPhone 16 Pro stack: "runCheck@https://...". UA-based disambiguation — единственный надёжный способ.

[FIX] crossCheck: убраны plugins/pdfViewer/hwConcurrency для iOS
Причина: plugins=5 (WHATWG стандарт), pdfViewer=true (стандарт), hwConcurrency=4 (iOS 18+) — нормальны. Проверки plugins/pdf оставлены для Android.

[FIX] vendorCheck: CriOS на iOS использует WebKit → vendor="Apple Computer, Inc."
Было: CriOS → expected "Google Inc." → FAIL (реально "Apple Computer, Inc.")
Причина: Chromium docs: Chrome на iOS использует WebKit (требование Apple), не Blink. Vendor определяется движком, не брендом браузера.
Пруф: реальный iPhone 16 Pro, CriOS 145.0.7632.108, vendor="Apple Computer, Inc.". Теперь все iOS браузеры ожидают "Apple Computer, Inc.".

[ADD] perfPrecisionCheck: sub-ms таймер на Safari/iOS = Chrome движок
Причина: MDN: Safari округляет performance.now() до 1ms, Chrome даёт 100µs.
Если iOS UA но precision <1ms → FAIL (Chrome движок вместо WebKit).
Пруф: WADE X (iOS Safari профиль): perfPrecision="<1ms (Chrome)" — пойман.

[ADD] sampleRatePlatformCheck: AudioContext sampleRate cross-platform
Причина: howler.js #1141: Safari iOS default=48000, Android Chrome default=44100.
Если iOS UA но sampleRate=44100 → WARN (Chrome audio pipeline).

[ADD] fontFallbackPlatformCheck: десктопные метрики шрифтов на mobile
Причина: monospace fallback font ~125px на mobile (iOS/Android), ~172px на Windows из-за разных системных шрифтов.
Если mobile UA но monospace >150px → FAIL (десктопные шрифты).
Пруф: WADE X (iOS Safari профиль): monospace=172.68px. Реальный iPhone=124.82px, Android=124.82px.
Questions (нерешённые вопросы)
[Q1] РЕШЕНО — Mali maxTextureSize=16383 подтверждено
Источник: Multilogin Phone, Pixel 6, Android 12, Chrome 107
Решение: gpuinfo.org подтвердил — ВСЕ Mali GPU (G52 Bifrost, G57/G68 Valhall, G715 5th Gen) репортят GL_MAX_TEXTURE_SIZE=16383 (2^14-1) через OpenGL ES. Mali-G715 — 65536. Chrome Android обрезает до 8192. 16383 — штатное значение, не спуф. Лимит "Mali<=8192" убран, добавлена проверка на ровное 16384 (антидетект спуф).

[Q2] DPR 1.63 на Pixel 6 — реальный или спуфнутый?
Источник: Multilogin Phone, Pixel 6
Проблема: реальный Pixel 6 DPR=2.625 (1080px / 412dp). 1.63 — нестандартное значение. Может быть display size settings или Multilogin подменяет.
Нужно: проверить реальный Pixel 6 без Multilogin.

[Q3] outerHeight === innerHeight на мобильном — нормально?
Источник: Multilogin Phone, Pixel 6 (outerH=innerH=739, ratio=1.00)
Проблема: на реальном Android Chrome outerH обычно > innerH (URL bar). На реальном Pixel 7 ratio=1.18. ratio=1.00 может быть fullscreen mode или headless.
Нужно: тестировать на разных Android устройствах в разных режимах.

[Q4] voicesCount=0 на Android Chrome — нормально?
Источник: Multilogin Phone, Pixel 6, Chrome 107
Проблема: реальный Android Chrome 145 = 90 голосов. Chrome 107 = 0. Может быть: TTS не установлен, голоса не загрузились, или Multilogin не проксирует speechSynthesis.
Нужно: проверить Chrome 107 на реальном устройстве или найти changelog speechSynthesis.

[Q5] S3TC hasS3TC=true на iPhone 16 Pro — откуда?
Источник: реальный iPhone 16 Pro, Safari 18.6
Проблема: CanIUse и Apple docs говорят что Metal на iOS НЕ поддерживает BC/S3TC. Но getExtension('WEBGL_compressed_texture_s3tc') возвращает объект.
Нужно: проверить другие iPhone (не 16 Pro). Возможно A18 Pro добавил, или software decode, или Apple docs устарели.

[Q6] audioHash одинаковый на разных устройствах (124.080756)
Источник: Android Chrome 145 (реальный), Multilogin Phone Chrome 107, Multilogin Phone Chrome 132
Проблема: одинаковый AudioContext hash на 3 разных устройствах (реальный + 2 облачных), разные GPU (Adreno 810, Mali-G78, Mali-G610), разные версии Chrome. Хеш должен отличаться — возможно hash слишком грубый или Chrome нормализует output.
Примечание: iPhone 16 Pro audioHash=124.043466 (отличается). Значит хеш различает iOS vs Android, но не различает Android-устройства.
Нужно: более точный audio fingerprint (больше осцилляций, двойной hash).

[Q7] Multilogin Phone: два "разных телефона" с идентичными параметрами
Источник: MLX Phone 1 (Pixel 6, Chrome 107, Mali-G78) vs MLX Phone 2 (Chrome 132, Mali-G610)
Идентичны: screenW=442, screenH=883, DPR=1.631250, audioHash, fontFallback, perfMemory heap=1136000000, maxRBuf=16383.
Проблема: реальные разные телефоны имели бы разные DPR, screen dimensions, audio pipeline. Идентичность предполагает один шаблон железа или виртуализацию.
Потенциал: cross-device fingerprint matching — если несколько "телефонов" имеют идентичный набор (screen+DPR+audio+fonts+heap) → одна ферма.

[Q8] ANGLE на Android — нормально?
Источник: MLX Phone 2, glRenderer="ANGLE (ARM, Mali-G610, OpenGL ES 3.2)"
Проблема: Android обычно использует нативный OpenGL ES, ANGLE типичен для Windows/ChromeOS. Chrome 132+ может использовать ANGLE на Android в некоторых конфигурациях (экспериментальный флаг). Или это признак эмуляции.
Нужно: проверить chrome://gpu на реальном Android Chrome 132+.