fix(pythonlib): stop overriding the corpus on core counts; pinning is opt-in

Two findings from auditing the sweep's fixes against one bar: a difference is a
leak only if a page's JavaScript can actually read it.

hardwareConcurrency 2 was excluded from PLAUSIBLE_CORE_COUNTS because "2 is what
Firefox reports under resistFingerprinting". That has not been true for years:
RuntimeService::ClampedHardwareConcurrency hardcodes 4, and 8 on macOS, both of
which are already in the table. The exclusion protected against nothing and cost
every genuinely dual-core machine -- 20% of the macOS presets in the recorded
corpus, 4.2% of Linux draws. It also made the small-host tail worse: a 3-core
host reported 4, which cannot be pinned, so a page measured 3 while being told 4.
At 2 the pin succeeds.

pin_cpu_cores now defaults to False. What it buys is defence against a page
timing N parallel workers; what it costs is a browser-wide CPU cap, a per-driver
launch lock, and nothing at all on macOS. Unpinned, the host's own snapped count
is reported, so reported and measurable still agree -- the identity just loses
one drawn value. Callers who want the draw kept can still ask for it.

The WebGL sampler keeps rejecting software rasterisers, and its docstring now
says so: it described the opposite of what the code does. llvmpipe as the
presented GPU is a live check on a string every fingerprint script reads, which
is worth ~1.5% of corpus fidelity.

251 pythonlib tests pass.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jake Writer
2026-09-17 13:01:51 -06:00
co-authored by Claude Opus 5
parent 85d26d4f76
commit fd501e5d01
6 changed files with 58 additions and 39 deletions
+11 -11
View File
@@ -298,33 +298,31 @@ class TestFixHardwareConcurrency:
assert c["navigator.hardwareConcurrency"] == drawn
def test_snaps_implausible_draws_down_into_the_table(self, monkeypatch):
# browserforge draws counts no desktop ships with: over 400 linux draws
# 8.0% were < 4 cores and 4.2% were exactly 2. hardwareConcurrency == 2
# is what Firefox reports under resistFingerprinting, so CreepJS-style
# heuristics label the browser "Firefox resistFingerprinting"; odd counts
# (5, 7, 9, ...) are equally synthetic. They snap DOWN into
# browserforge draws counts no desktop ships with -- odd ones (5, 7, 9,
# ...) are Bayesian synthesis, not machines. They snap DOWN into
# PLAUSIBLE_CORE_COUNTS, with the table floor for anything below it.
# 2 IS a real count (20% of the macOS presets) and stays: Firefox's
# resistFingerprinting value is 4, or 8 on macOS, not 2.
from camoufox import cpu_affinity, fingerprints as fp
monkeypatch.setattr(cpu_affinity, "supported", lambda: True)
monkeypatch.setattr(fp, "host_cpu_count", lambda: 16)
for drawn, expected in ((1, 4), (2, 4), (3, 4), (5, 4), (7, 6), (9, 8),
for drawn, expected in ((1, 2), (2, 2), (3, 2), (5, 4), (7, 6), (9, 8),
(11, 10), (13, 12), (15, 14), (32, 16)):
c = {"navigator.hardwareConcurrency": drawn}
fp.fix_hardware_concurrency(c)
assert c["navigator.hardwareConcurrency"] == expected, drawn
# never above what the host can be pinned to
monkeypatch.setattr(fp, "host_cpu_count", lambda: 4)
c = {"navigator.hardwareConcurrency": 2}
c = {"navigator.hardwareConcurrency": 8}
fp.fix_hardware_concurrency(c)
assert c["navigator.hardwareConcurrency"] == 4
def test_snaps_host_parallelism_when_it_cannot_pin(self, monkeypatch):
# The host count, snapped DOWN into the
# counts real machines ship with; the tails report 32 / 4. Used when the
# counts real machines ship with; the tails report 32 / 2. Used when the
# draw exceeds the host or the host cannot pin (macOS).
# 18/22/24/28/32 are in the table (recorded on real devices); 2 is NOT,
# although it is recorded, because 2 is the resistFingerprinting value.
# 2/18/22/24/28/32 are all in the table, all recorded on real devices.
from camoufox import cpu_affinity, fingerprints as fp
monkeypatch.setattr(cpu_affinity, "supported", lambda: False)
@@ -338,7 +336,9 @@ class TestFixHardwareConcurrency:
(22, 22),
(7, 6),
(5, 4),
(2, 4),
(3, 2),
(2, 2),
(1, 2),
(9, 8),
):
monkeypatch.setattr(fp, "host_cpu_count", lambda host=host: host)
+6 -1
View File
@@ -100,13 +100,18 @@ class TestVoicesFollowLocale:
class TestCoreCountFloor:
def test_small_pinnable_host_reports_table_floor(self, monkeypatch):
# A 1-3 core host reports 2, the table's floor and the lowest count the
# corpus records. It used to report 4, which no 2-core machine can back
# up: 4 cannot be pinned on a 3-core host, so the page measured 3 while
# being told 4. At 2 the pin succeeds on a 2- or 3-core host, and the
# 1-core tail (told 2, measures 1) is closer than 4 was.
monkeypatch.setattr(cpu_affinity, "supported", lambda: True)
for host_cores in (1, 2, 3):
monkeypatch.setattr(fp, "host_cpu_count", lambda n=host_cores: n)
for drawn_cores in (1, 2, 3, 8):
c = {"navigator.hardwareConcurrency": drawn_cores}
fp.fix_hardware_concurrency(c)
assert c["navigator.hardwareConcurrency"] == 4, (host_cores, drawn_cores)
assert c["navigator.hardwareConcurrency"] == 2, (host_cores, drawn_cores)
def test_unpinned_launch_reports_host(self, monkeypatch):
monkeypatch.setattr(cpu_affinity, "supported", lambda: True)