Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions fingerprint_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,20 @@ def playwright_context_kwargs(fp: dict) -> dict:
kwargs["viewport"] = {"width": outer_w, "height": max(400, outer_h)}
kwargs["screen"] = {"width": width, "height": height}

# The device pixel ratio, which Playwright takes as its own context
# option and which was previously dropped on the floor. Measured
# 2026-09-11 against the live API and a live browser: a fingerprint
# stating `deviceScaleFactor: 1.25` produced a browser reporting
# `window.devicePixelRatio === 1`, so the identity contradicted itself
# on an axis any fingerprinter reads for free -- and a contradiction is
# exactly what this flag exists to avoid. Same shape as the three
# defects the family notes already list for this file: a key the API
# returns that nothing applies. Found by comparing a live browser
# against the fingerprint rather than by reading the code.
scale = (fp.get("screen") or {}).get("deviceScaleFactor")
if isinstance(scale, (int, float)) and not isinstance(scale, bool) and scale > 0:
kwargs["device_scale_factor"] = float(scale)

intl = fp.get("intl") or {}
# The fingerprint's OWN locale. This used to be built as
# f"en-{country}", which produced "en-DE" for a German fingerprint — an
Expand Down
10 changes: 9 additions & 1 deletion smoke_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1407,7 +1407,8 @@ def wait_for_timeout(self, ms): pass
from fingerprint_client import playwright_context_kwargs, playwright_init_script

FP = {"id": "fp_test", "country": "us",
"screen": {"width": 1920, "height": 1080},
"screen": {"width": 1920, "height": 1080,
"deviceScaleFactor": 1},
"userAgent": {"value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/145.0.0.0"},
"navigator": {"platform": "Win32", "hardwareConcurrency": 8, "deviceMemory": 8},
"webgl": {"vendor": 'Google Inc. "quoted"', "renderer": "ANGLE (RTX 3060)"}}
Expand All @@ -1421,6 +1422,13 @@ def wait_for_timeout(self, ms): pass
and kw["screen"]["width"] == 1920)

js = playwright_init_script(FP)
# The device pixel ratio, which Playwright takes as its own option
# and which was dropped on the floor until a live browser was
# compared against the fingerprint: one stating 1.25 produced a
# browser reporting `devicePixelRatio === 1`, an identity
# contradicting itself on an axis a fingerprinter reads for free.
ok &= check("fingerprint: the device scale factor is carried",
kw.get("device_scale_factor") == 1)
ok &= check("fingerprint: values are JSON-encoded, so a quote in an API string "
"cannot break out of the script",
'\\"quoted\\"' in js and "Google Inc. \"quoted\"" not in js)
Expand Down
Loading