Skip to content
All fingerprint checksCapability surfaces

the permission descriptors this build accepts are the platform's, not a lookup table's

Check id permission-name-support-set

What an ordinary browser yields

Every real descriptor your engine supports resolves to a state, an invented name is refused with a TypeError, no refusal uses an error type the platform does not throw, and a fresh realm accepts the same set.

What a detector infers

The Permissions specification deliberately fixes no list of names. Each engine compiles in the descriptors it supports, and Chromium's set has moved almost every milestone — which makes the accepted set a property of the binary rather than of the page. This row does not need a version table to be useful, because it asserts the two things that hold on every engine at once. First, a descriptor name that exists in no browser must be REFUSED: a control name is queried alongside the real ones, and a build that accepts it is answering from a JavaScript lookup table rather than from the platform. Second, the refusal must come from the platform's own error machinery. Which error, exactly, was settled by measuring a stock Chromium rather than by reasoning: an unknown NAME fails WebIDL enum conversion and throws TypeError, a name the build knows but has not enabled ALSO throws TypeError with a feature message, but `push` rejects with a NotSupportedError DOMException because its descriptor is valid and the objection is to userVisibleOnly. So the type is pinned only where the platform pins it — on the invented control name — and every other refusal is held to the weaker rule that it is a platform error type at all. A shim that rejects with a bare Error, or resolves everything to 'granted', fails both halves. The obvious stricter assertion, 'every refusal is a TypeError', would have failed real Chrome on `push`, which is the kind of false positive that makes a whole audit unreadable. Finally the accepted SET is compared against a fresh realm's, which catches a shim installed in the main world only. The set itself is reported rather than scored: naming which versions support which descriptor is exactly the kind of table that rots, so the audit records the reading and leaves the version inference to the corpus.

How to resolve it

Let the platform answer permission queries. A JavaScript table over navigator.permissions.query will accept names no engine has and refuse real ones with the wrong error type, both of which are visible without knowing anything about your browser version.

Read in the wild by

FakeBrowser (collector)

Queries 31 descriptor names taken from Chromium's own permission_descriptor.idl and stores, for each failure, the exception's constructor name and message — collecting the refusal dialect, not just the accepted set.

dumpPermissions(), script/dumpDD.js

kkoooqq/fakebrowser script/dumpDD.js

Every attribution traces to a published artifact. See the sources and their limits.

Nearby checks in Capability surfaces

See all 13 checks in Capability surfaces
Who builds this test

Clearcote is a browser built for fingerprint coherence

It is a Chromium fork, maintained by the same people who wrote this reference. It ships as a compiled browser rather than as a stealth script injected into someone else's — which is a description of how it is built, and is not an argument about how it behaves on this check.

This audit takes no position on how Clearcote scores on Capability surfaces checks, on this one, or anywhere else. It has no baseline corpus of other people's fingerprints to rank you against and no vendor scoreboard — nearly every check is self-referential, asking one browser the same question through two independent APIs and reporting whether both answers can be true at once. It runs identically on any browser, including ours. Run it on yours and read the result yourself.

See the other checks in Capability surfaces — the family permission-name-support-set belongs to.