Browser fingerprint checks: the full index
A subsystem-by-subsystem index of all 271 checks in the Clearcote browser fingerprint test. Each check has its own page explaining what a detector infers when it fails, what an ordinary unmodified browser yields, and how to resolve it. 159 of them also name the anti-bot systems documented to read the signal, with the published artifact behind each attribution.
What this audit checks, and why each signal is legible
Almost every check below is self-referential: it asks this browser the same question through two independent APIs and reports whether both answers can be true at once. That is why it needs no baseline corpus — a contradiction is visible from inside the page. The WebRTC address check is the lone exception, and the only one that makes a network call: comparing where your media exits against where your page arrived from is not answerable from inside. Open any check for the full mechanism, what an ordinary unmodified browser yields, how to resolve it, and which detectors are documented to read it.
HTTP request vs the runtime
Screen & display
screen-matchmediaThis check reads window.screen.width/height, then asks the CSS media-query engine the same question via matchMedia("(device-width: Npx) and (device-height: Npx)").KasadaAkamaidpr-matchmediaThe check compares window.devicePixelRatio against the layout engine's own answer, querying matchMedia with a min-resolution/max-resolution band in dppx around the reported value.KasadaCreepJSscreen-plausibleA pure sanity range on screen.width and screen.height: both must be at least 200px and no more than 16384px.Kasadataskbar-presentscreen.availWidth/availHeight describe the area left over after the OS reserves space for its own chrome — a Windows taskbar, a macOS dock and menu bar.KasadaPerimeterX / HUMANCreepJSwindow-boundsThe check asserts only the zoom-invariant bound: window.outerWidth/outerHeight must be non-zero and must fit within the screen.KasadaPerimeterX / HUMANCreepJSpointer-hover-desktopThis check applies only when the UA identifies a desktop platform (Windows, Macintosh, Mac OS X, X11, Linux, CrOS, and not Android/Mobile) and navigator.maxTouchPoints is 0; anything else reads N/A.Kasadatouch-pointer-coherenceA one-directional coherence test: if navigator.maxTouchPoints is greater than zero, matchMedia("(any-pointer: coarse)") is expected to match.KasadaPerimeterX / HUMANscreen-descriptorsFor width, height, availWidth, availHeight, colorDepth and pixelDepth this asks two questions: does the screen instance carry an own descriptor (real browsers expose these only via Screen.prototype)…CreepJSorientation-vs-screen-dimsscreen.orientation.type and screen.width/height are both device-space values sourced from the same display metrics, so they must agree: a type starting with "portrait" implies screen.height >…Kasadatouch-createevent-coherenceThis check asserts in one direction only: if navigator.userAgent matches iPhone, iPad, iPod or Android, then the environment must also have navigator.maxTouchPoints > 0 and a constructible TouchEvent…KasadaCreepJSNavigator identity
platform-coherenceThree independent surfaces each name an operating system, and this check normalises all three to one family (win / ios / mac / lin) and requires them to match.KasadaPerimeterX / HUMANCreepJSuach-ua-versionThe check extracts the major from Chrome/(\d+) in the UA string, finds the Chrome or Chromium entry in navigator.userAgentData.brands, and requires the brand's version to equal that major.PerimeterX / HUMANuach-highentropyThis awaits navigator.userAgentData.getHighEntropyValues and compares the richer hints against the UA string on three axes, collecting every disagreement.PerimeterX / HUMANDataDomelanguages-coherenceIn a real browser navigator.language is defined as the first element of navigator.languages — one preference list, two views onto it.PerimeterX / HUMANKasadaDataDomelocale-vs-voice-coherenceThe voice roster is installed at the operating-system level and the language preference is set in the browser, so the two are genuinely independent sources for one claim — which is what makes a…CloakBrowserPerimeterX / HUMANetslThe string a JS engine returns for a native function's source is an implementation detail, and its length differs per engine: eval.toString().length is 33 on V8 and 37 on Gecko and WebKit.KasadaPerimeterX / HUMANproduct-subnavigator.productSub is a frozen legacy constant, not a live value: Chrome, Safari and Opera return "20030107" while Firefox returns "20100101".PerimeterX / HUMANgecko-productsub-hardcodenavigator.productSub is a constant compiled into the engine, and the two families disagree: every Gecko build hardcodes it to "20100101" — stock Firefox, ESR, Tor Browser, LibreWolf, Firefox for…Camoufoxlegacy-engine-props-absentThere is a difference between a property that returns undefined and a property that does not exist, and only one of them is what a real browser gives.FakeBrowserdevice-memory-boundsnavigator.deviceMemory does not report actual RAM — the spec requires the UA to quantise it to a coarse power-of-two rung before exposing it, which is what makes it a low-entropy hint rather than a…PerimeterX / HUMANKasadaAkamaihardware-concurrencyThis is an info-severity observation, not a scored failure — it reports navigator.hardwareConcurrency and only notes whether the value is an integer in the range 1–128.KasadaAkamaikeyboard-api-vs-platformThe Keyboard API — navigator.keyboard, with getLayoutMap and lock — ships in desktop Chromium and nowhere else: not in Gecko, not in WebKit, and not in Chromium's own mobile builds.Kasadabrand-hints-vs-realmSome of the cheapest signals to fake are the ones that say which browser this is: navigator.brave exists only in Brave, window.duckduckgo only in DuckDuckGo's browser, and isSecureContext reflects how…Kasadalocation-origin-coherenceAn origin is not stored next to a URL, it is serialised from it: for an http or https document, origin is exactly the scheme, followed by two slashes, followed by the host and any non-default port.Kasadaua-oscpu-os-family-coherencenavigator.oscpu is a property only Gecko still exposes — Chromium removed it and WebKit never had it — so this check is silent on every non-Firefox engine and reads nothing there to judge.Camoufoxworker-main-timezone-coherenceA browser has one host timezone, and the specification ties both the main-thread global and every worker global to it, so a real browser resolves the same IANA zone string on both — they come from a…Camoufoxkeyboard-layout-single-originA keyboard layout is not a set of independent key mappings — it is one artifact the operating system hands over whole.CloakBrowserappversion-vs-useragentnavigator.appVersion is not an independent fact. In Blink and WebKit it is computed from the User-Agent at read time — literally the UA with everything up to the first slash removed — so it is the…KasadaPerimeterX / HUMANtrusted-types-value-invariantTrusted Types is a typed API, not a boolean feature flag, and that is the whole of the check.reCAPTCHA / BotGuarddate-tostring-coherenceA Date's text is not opaque. ECMA-262 defines toString() as toDateString() + " " + toTimeString(), fixes the weekday and month tables to English so they are never localized, and bakes the UTC offset…PerimeterX / HUMANCreepJSEngine & OS oracles
js-engine-identifier-vs-uaTwo values are read straight out of the JavaScript engine itself: the character length of the RangeError message thrown by (-1).toFixed(-1), and the length of the Array constructor's own source text…CreepJSAkamaiDataDomemath-tanh-os-vs-uaIEEE 754 fixes how a double is stored but does not require transcendental functions to be correctly rounded, so every operating system's C math library ships its own polynomial approximation and they…Scrapflycpu-arch-nan-wasm-vs-jsIEEE-754 leaves the sign bit and payload of a quiet NaN to the implementation, and the two dominant architectures chose differently: x86 sets the sign bit on the default quiet NaN (0xFFF8000000000000…Scrapflyjsheap-triplet-orderingThis check replaces a retired one, and the swap is the lesson.PerimeterX / HUMANKasadasystem-font-vs-claimed-osThe CSS2 system-font keywords — caption, icon, menu, message-box, small-caption and status-bar — are resolved by the HOST platform's font APIs, not by the page and not by anything the user agent…Camoufoxclaimed-os-typefaces-are-distinctA font request is answered by the host's font stack, not by the browser and not by anything the user agent sets, so changing navigator.platform does not move a single glyph.FingerprintJSClearcoteWorker realms
worker-realms-agreeA page is not one JavaScript realm — it is several. The audit loads one probe script into all three worker kinds the platform offers: a dedicated Worker, a SharedWorker and a ServiceWorker, raced in…CreepJSNetwork & WebRTC
webrtc-turn-egressEvery other WebRTC check on this page reads what the browser is willing to show it.Verisoulwebrtc-gathering-suppressedThe other WebRTC rows on this page read what the candidates SAY.CloakBrowserconnection-api-vs-engineThis check compares an API's mere existence against the engine family named by the User-Agent.KasadaPerimeterX / HUMANClocks & ledgers
resource-timing-vs-cssomFetching a resource writes two records: the DOM object you can see, and an immutable entry in the performance timeline.PerimeterX / HUMANwallclock-vs-monotonic-rateA browser owns two clocks and they are not the same clock. Date.now() is wall time: it can be wrong, it can be corrected, it can jump. performance.now() is monotonic from navigation: it cannot go…DataDomePerimeterX / HUMANperf-clock-grid-coherenceA timestamp's low bits are a fingerprint. DataDome ships its performance floats unrounded — 2253.7000000029802 rather than 2253.7 — and that is not sloppiness: the residue is the exact double…DataDomeAutomation surface
webdriver-offThis check is intentionally one-way. The WebDriver specification defines navigator.webdriver as the browser's assertion that it is under remote control, so true is direct evidence.PerimeterX / HUMANCreepJSKasadawebdriver-descriptor-integrityRather than reading the value, this check inspects the property's shape: it requires a getter on Navigator.prototype whose Function.prototype.toString output contains { [native code] }, no own…PerimeterX / HUMANCreepJSautomation-globalsThis check tests a fixed list of roughly two dozen known names against both window and document (Selenium's __webdriver_evaluate / __selenium_unwrapped / _Selenium_IDE_Recorder, ChromeDriver's…KasadaPerimeterX / HUMANruntime-enable-leakAn attached DevTools Runtime domain serialises console arguments and reads an Error stack accessor.Rebrowserconsole-preview-proxy-trapDevTools has to look inside an object to show it to you, and in JavaScript looking inside an object is an observable act.SvebaRebrowserchrome-objectThis is a cross-check, not a probe of window.chrome's contents: it first decides whether the browser claims to be Chrome (a Chrome/ token in the user agent, or the presence of…PerimeterX / HUMANCreepJSKasadaDataDomechrome-native-stubsWhere the previous check asks whether window.chrome exists, this one asks whether its members are genuine.PerimeterX / HUMANpermissions-notification-bugTwo independent APIs describe the same underlying notification permission: navigator.permissions.query({name:'notifications'}) returns a PermissionStatus state, and Notification.permission returns a…PerimeterX / HUMANCreepJSpermissions-query-stackThis probe calls navigator.permissions.query() with exactly zero arguments and inspects the error the native arity check produces.KasadaAkamaitimer-id-sequencingThe number setTimeout hands back is not a token, it is an index into the realm's own timer table — so it carries structure that a fabricated handle does not.Kasadawindow-globals-vs-baselineThe list of names on the global object is not written by the page — it is installed by the engine when it sets up a realm, from a table compiled into the binary.KasadaFakeBrowserelement-surface-vs-baselineA for..in over the document element does not enumerate one object: it walks the whole prototype chain — HTMLElement, Element, Node, EventTarget — and returns every enumerable member on it, which in…FakeBrowserdocument-visibility-coherencedocument.hidden and document.visibilityState are two views of one piece of state, and the specification defines the first in terms of the second: hidden is true exactly when visibilityState is the…Kasadaplugins-idl-index-wraparoundA real navigator.plugins is a PluginArray — a C++-backed IDL collection — and its indexed getter runs the Web IDL unsigned-long conversion, so item(2^32 + 1) is item(ToUint32(2^32+1)), which is…CloakBrowserstorage-quota-worker-vs-mainnavigator.storage.estimate().quota describes one storage partition, and a same-origin worker shares that partition — a single QuotaManager in the browser process answers both, keyed by one storage…CloakBrowseruser-activation-vs-interactionThis audit only runs when you press the Run button, and pressing a button is exactly what grants user activation — by pointer, by Enter or Space on a focused control, or through a screen reader, all…Kasadaactivation-without-inputThe row above this one reads navigator.userActivation once and expects it to be true, because the audit is reached by pressing a button.Kasadascroll-alias-coherencewindow.pageXOffset is not a second scroll position, it is a legacy alias of window.scrollX — the specification defines them as the same value and Blink backs both names with one getter.Kasadadocument-focus-vs-realmdocument.hasFocus() is true when the document OR any of its descendants holds focus, which makes it hierarchical rather than local: a focused child frame necessarily means its parent document reports…KasadaError subsystem
error-dialect-realm-agreementAn engine's error messages are a dialect hiding in plain sight.DataDomeAkamaierror-stack-depth-fidelityDataDome's bytecode VM does something small and sharp: new Error(), read .stack, fold a hash over the text — we can read the exact opcodes, including its fallback to an empty string for engines that…DataDomestructured-stack-vs-string-stackChrome describes one call chain twice. Once as the human-readable string on Error.stack, and once as structured CallSite objects, through a hook called Error.prepareStackTrace.DataDomeNative function integrity
tostring-nativeThe check stringifies two functions and requires both to match /\{\s*\[native code\]\s*\}/: Function.prototype.toString itself (read as Function.prototype.toString.toString()), and…KasadaPerimeterX / HUMANCreepJSnative-integrityThis runs a battery over roughly forty engine-owned callables — canvas, WebGL, navigator, iframe, shadow-DOM and fetch natives, plus the JS core (Object.*, Reflect.*, Function.prototype…PerimeterX / HUMANCreepJSKasadaiframe-coherenceThe check appends a hidden same-origin iframe to documentElement and reads its contentWindow — a brand-new JavaScript realm with its own fresh copies of navigator, Function and HTMLCanvasElement.PerimeterX / HUMANCreepJSKasadapage-world-wrappersThis probe stringifies window.fetch and window.Request and asks whether each still renders as native code, then checks whether document carries its own createElement, querySelector or addEventListener…Kasadanative-brand-checksTwo native methods are invoked with their own bare prototype as the receiver: WebGLRenderingContext.prototype.getParameter.call(WebGLRenderingContext.prototype, 37445) and…CreepJSiframe-srcdoc-placementA fresh <iframe> is created with document.createElement and inspected for own property descriptors on srcdoc, src and contentWindow.KasadaCreepJSshadow-dom-integrityThe check reads Element.prototype.attachShadow four ways and asserts they agree: its name is "attachShadow", its length (declared parameter count) is 1, it stringifies as native code — measured both…Kasadarng-integrityThe check verifies that Math.random is the engine's native generator and that its output is high-entropy.Kasadawindow-globals-vs-realmThe audit builds a fresh same-origin iframe and enumerates the own properties of both global objects, then asserts two things a browser cannot violate on its own.PerimeterX / HUMANCreepJSKasadacontentwindow-realm-identityThis is the check that guards the others. A large part of this audit — the global property diff, all six capability surfaces, the brand hints, the shadow DOM probe, the iframe scalar comparison…KasadaRender & GPU
webgl-not-softwareThe audit reads UNMASKED_RENDERER through the WEBGL_debug_renderer_info extension and matches it against SwiftShader, llvmpipe and Software.KasadaPerimeterX / HUMANCreepJSwebgl-param-tableBeyond the two headline strings, a WebGL context answers getParameter for dozens of driver-specific limits.PerimeterX / HUMANKasadaAkamaiwebgl-param-value-typesgetParameter does not return loose values: the WebGL specification fixes the JavaScript TYPE of each one.FakeBrowserwebgl-worker-vs-mainThe audit reads UNMASKED_VENDOR and UNMASKED_RENDERER on the main thread, then spawns a dedicated Worker that builds its own WebGL context on an OffscreenCanvas and reads the same two strings…CreepJSwebgl1-webgl2-coherenceThe check creates a WebGL1 context and a WebGL2 context and reads UNMASKED_VENDOR_WEBGL / UNMASKED_RENDERER_WEBGL from each through the WEBGL_debug_renderer_info extension, then asserts the two…Kasadacanvas-tamperThe probe fills a single pixel with pure black on a 1x1 canvas and reads it straight back with getImageData.CreepJSAkamaiDataDomecanvas-flat-fill-uniformThis is the area form of the 1×1 canvas probe, and it exists because that probe is easy to pass by accident.CloakBrowsercanvas-subrect-consistencyThe same pixels, asked for twice through different windows. A full-canvas read and an inner 16×16 read overlap on 256 pixels, and those are literally the same pixels of the same untouched bitmap, so…CloakBrowserwebgl-readback-flat-uniformA single glClear writes one colour into every pixel of the framebuffer, so reading that framebuffer back must yield exactly one colour.CloakBrowserwebgl-webgpu-readback-agreeOne clear, two GPU APIs, one adapter. WebGL paints a flat colour and reads it back with readPixels; WebGPU renders the same clear into a texture and copies it into a mapped buffer.CloakBrowsermeasuretext-gridChrome's 2D text metrics are quantised: advance widths are computed in fixed-point and land on a dyadic 1/512-pixel grid.CreepJStext-metrics-uniform-scaleThis is the sub-pixel grid check asked one question deeper. That check reports THAT widths have left Blink's 1/512-pixel grid; this one asks what SHAPE the deviation has, which turns out to separate…CloakBrowsertext-ink-extent-vs-advanceTextMetrics reports two numbers produced by different parts of the engine. width is the sum of the glyph advances the shaper accumulated. actualBoundingBoxRight is the rightmost inked pixel, derived…Camoufoxbcr-vs-rangeTwo independent APIs are pointed at the same laid-out text: an absolutely-positioned div containing "WWWWWiiiii" is measured with element.getBoundingClientRect().left, and a Range selecting the same…CreepJSlayout-box-arithmeticclientWidth and offsetWidth are not opinions the browser offers — CSSOM defines them as arithmetic over values the same element hands you through getComputedStyle.DataDomeclient-rect-origin-vs-positionZero is scale-invariant, and that single property is the whole check.CloakBrowsersvg-ctm-vs-client-rectTwo independent routes to a single fact. getScreenCTM maps an SVG element's user space into viewport coordinates, and getBoundingClientRect reports that same element's border box in those same…CloakBrowserclient-rect-vs-observerA third account of where one element sits, from the most ordinary API that has one.CloakBrowserwebgpu-sync-surface-vs-realmWebGPU's cheapest fingerprint is not the GPU at all. navigator.gpu.getPreferredCanvasFormat() and navigator.gpu.wgslLanguageFeatures are compiled-in build constants — no adapter, no device, no await…DataDomewebgl-limits-vs-driverEvery other WebGL check on this page reads what getParameter SAYS.Kasadashader-backend-vs-rendererThe UNMASKED_RENDERER_WEBGL string is a label — a piece of text a page can rewrite to name any GPU and any graphics backend.Kasadawebgl-extensions-vs-drivergetSupportedExtensions() returns a list a page can rewrite; getExtension(name) either hands back a real extension object or null, and that answer is the driver.CloakBrowserwebgl-draw-path-invarianceOpaque red can be produced two ways: the fixed-function clear path, and a fragment shader emitting vec4(1,0,0,1).CloakBrowsershader-mediump-claim-vs-arithmeticgetShaderPrecisionFormat is a claim about float precision; a shader that computes a value only fp32 can represent is the GPU keeping or breaking that claim.CloakBrowseraudio-render-silence-integrityThe other audio checks compare two renders of a sound; this one renders silence and asserts it stayed silent, which catches a different kind of tamper.CloakBrowseraudio-render-reproducibilityAn OfflineAudioContext render involves no output device and no clock.Scrapflyeme-clearkey-baselineEncrypted Media Extensions is the DRM entry point, and it has one part that cannot be missing.ScrapflyCloakBrowsercanvas-toblob-vs-todataurlA canvas has three exits — getImageData, toDataURL and toBlob — and a build that perturbs canvas readback has to perturb all three identically or it contradicts itself.CloakBrowserClearcotewebgl-max-elements-readoutMAX_ELEMENTS_INDICES and MAX_ELEMENTS_VERTICES are hints the driver publishes about how many indices and vertices it draws efficiently in one call.CloakBrowserClearcotewebgpu-canvas-format-readoutnavigator.gpu.getPreferredCanvasFormat() returns the texture byte order the platform's compositor wants to be handed — and that preference belongs to the real graphics stack, not to the identity the…CloakBrowserCapability surfaces
css-surface-vs-realmWhich CSS properties, values and selectors an engine understands is decided when the browser is compiled.Kasadamedia-surface-vs-realmMedia features are answered by the layout engine rather than by the JavaScript properties that describe the same machine, which is what makes them worth asking twice.Kasadacodec-surface-vs-realmcanPlayType answers come from the media stack compiled into the browser, and the shape of that matrix is genuinely informative: branded Chrome ships proprietary decoders (H.264, AAC) that a bare…CreepJSKasadainput-surface-vs-realmAssigning an unrecognised type to an <input> element does not throw — the element silently falls back to reporting type "text".Kasadaemoji-surface-vs-realmEmoji do not render from the page's fonts but from a platform font supplied by the operating system — Segoe UI Emoji on Windows, Apple Color Emoji on macOS, Noto Color Emoji on Linux and Android.CreepJSKasadaanimation-surface-vs-realmThe Web Animations API exposes a small, precisely specified surface: whether Element.animate exists, whether the timeline and KeyframeEffect constructors are present, and what a created animation…Kasadasystem-colors-vs-platformThe CSS system-colour keywords — Highlight, HighlightText, Canvas, CanvasText, ButtonFace, ButtonText, GrayText and their newer siblings — are not resolved by JavaScript and not from a table inside…CloakBrowserdefault-style-values-vs-realmEvery browser ships a user-agent stylesheet: the rules that make a heading bold and a button look like a button before any site CSS exists.FakeBrowserpermission-name-support-setThe Permissions specification deliberately fixes no list of names.FakeBrowserplatform-gated-apis-vs-form-factorSome Web APIs are not compiled for every platform, so their presence is a fact about the binary rather than about the user agent.FakeBrowserbluetooth-availability-vs-platformnavigator.bluetooth is part of Chrome's desktop surface on Windows, macOS and Linux, and it is provided by the platform layer rather than by JavaScript — the object's methods are native bindings onto…CloakBrowserwebauthn-surface-vs-platformWebAuthn reaches further down the stack than most web APIs: PublicKeyCredential is not a self-contained JavaScript object but the front door to the platform's authenticator plumbing, which is why…CloakBrowserlegacy-quota-surface-agreementnavigator.webkitTemporaryStorage.queryUsageAndQuota and navigator.storage.estimate() describe the same thing — this origin's storage quota — through two APIs separated by about a decade.CloakBrowserEnvironment & locale
timezone-presentThis check reads Intl.DateTimeFormat().resolvedOptions().timeZone and records it alongside -new Date().getTimezoneOffset() and navigator.language.KasadaPerimeterX / HUMANCreepJStimezone-not-utcThe check resolves the Intl zone and fails only when it is exactly 'UTC' or 'Etc/UTC'.Kasadatimezone-offset-coherenceThis is a two-source cross-check on the same fact. It takes the resolved IANA zone, formats the current instant through Intl.DateTimeFormat with that timeZone, reconstructs the wall-clock time as a…PerimeterX / HUMANCreepJSKasadaAkamaihas-pluginsAn empty navigator.plugins is only meaningful when it contradicts something else, and this check is written to respect that.KasadaPerimeterX / HUMANCreepJSpdf-viewerA direct read of navigator.pdfViewerEnabled. It is N/A when the property is not exposed at all, passes when true, and is marked false otherwise — at 'info' severity, so it is contextual and not…PerimeterX / HUMANCreepJSplugins-mimetypesThis walks navigator.mimeTypes, and for each entry reads .enabledPlugin and checks that the exact object is present in a Set built from navigator.plugins.PerimeterX / HUMANCreepJSKasadaDataDomeAkamaiblink-web-apisWhen the UA matches Chrome/\d+ and the page is a secure context, this probes four Blink-only surfaces: navigator.connection, navigator.userAgentData, performance.memory, and — unless the UA is an iOS…PerimeterX / HUMANcss-engine-surfaceFor any UA containing 'Chrome/', this requires CSS.supports('-webkit-app-region', 'drag') to be true and the Gecko markers — MozAppearance in the inline style object, or…Kasadaintl-locale-coherenceEvery Intl constructor — NumberFormat, DateTimeFormat, PluralRules, Collator — resolves its locale through the same underlying ICU data, so all four must report the same base language tag.CreepJSKasadaplugins-structured-cloneThe structured-clone algorithm is implemented in C++ and interrogates objects about what they actually are, not what they claim.CreepJScanplaytype-parser-trapsA real canPlayType is an RFC-6381 parser, not a dictionary. This check exercises two properties only a parser has.Kasadaaudio-context-coherenceThe check constructs a live AudioContext and reads four invariants — sampleRate, baseLatency, the destination node's channelCount against its maxChannelCount, and channelInterpretation — then renders…PerimeterX / HUMANKasadaspeech-voicesspeechSynthesis.getVoices() enumerates the host operating system's speech engine — a resource stealth stacks essentially never touch, which makes it a useful window onto the real environment…PerimeterX / HUMANCreepJSKasadaspeech-voices-async-pathspeech-voices reads WHAT is in the voice list. This reads HOW the list arrived, which is a separate fact and survives a roster whose every value is plausible.CloakBrowserPerimeterX / HUMANaudio-sink-vs-device-listA resource oracle, and deliberately a different resource from the voice list.CloakBrowserClearcotebattery-spec-invariantsThe probe calls navigator.getBattery() once and records four fields together: level, charging, chargingTime, dischargingTime.CreepJSAkamaibroken-image-intrinsic-sizeAn image that cannot decode still has intrinsic dimensions, and where they come from is the interesting part: the browser substitutes a broken-image placeholder, and the placeholder is a drawn asset.CloakBrowserstorage-quota-vs-heap-ceilingTwo published classifiers read the ratio between an origin's storage quota and the JavaScript heap ceiling, and — this is the whole point of the row — they read it in opposite directions.CloakBrowserClearcoteTLS & the network layer
Connection & locale
Input & behaviour
pointer-path-linearityThe check captures the pointer path across the pad and measures two things about its geometry: the RMS perpendicular distance of every sample from the straight line joining the first and last point…Akamaipointer-movement-delta-coherenceEvery pointer event carries two independent accounts of the same displacement. screenX and screenY are where the pointer is; movementX and movementY are how far the user agent says it travelled since…Akamai