Signal · signalsVersion 9

noise_profile

Three known-answer probes, each read twice: canvas, WebGL and audio are exact, seeded, per_read or na. A browser trait, not an integrity flag. Not in either id.

noise_profile at a glance (from the library code, signalsVersion 9)
Component namenoise_profile
In the visitorIdno (reported, kept out of both ids)
structuredId groupnone
Hashingplain value; a digest only when longer than 128 characters or not printable ASCII
Excluded underno browser class
Inner timeout1000 ms
Added insignalsVersion 6
In plain words

Some browsers add tiny random changes to what a page reads back from a canvas, a 3D drawing or a sound, so that those reads cannot be used to recognise the device. WhiskerJS draws three things whose exact result is known in advance (two colours on a canvas, one colour in WebGL, a constant level of sound), reads each twice and compares. The result says, for each of the three, whether the browser returned the exact answer, the same wrong answer twice, or a different answer each time. It describes the browser’s privacy settings, so it is kept out of the identifiers and is never treated as a sign of tampering.

What it reads

Three known-answer probes, each read twice. The value has the form canvas=<state>,webgl=<state>,audio=<state>:

  • canvas: a 16x16 2D canvas, left half rgb(17, 34, 51) and right half rgb(204, 153, 102), read with getImageData(). Every pixel must come back with exactly those bytes and alpha 255.
  • webgl: the collection’s shared 32x32 WebGL drawing buffer, cleared to (51, 102, 153, 255) and read with readPixels(). Every pixel must come back with those four bytes.
  • audio: an OfflineAudioContext (1 channel, 1024 frames at 44100 Hz) rendering a ConstantSourceNode at 0.5, read with getChannelData(0). Every sample must be exactly 0.5. Nothing is played and no audio device is opened.

How the technique works

  1. Each probe produces its known answer and reads it back twice.
  2. Both reads exact gives exact. The same wrong answer twice gives seeded. Two different answers give per_read. A probe that cannot run (no canvas, no WebGL, no offline audio, or an error) gives na.
  3. The canvas and WebGL probes run once per collection, before the collectors, because their result picks the firefox_fpp and safari_afp browser classes. The audio probe runs beside the collectors; noise_profile waits at most 800 ms for it and reports audio=na after that.
  4. The same results are used by canvas, webgl_image and audio: when their own render looks clean but the probe of the same API is seeded or per_read, they report noisy with ruleId seeded_noise.

The probes run for every collection except an aborted one, also when you exclude the components that use them.

Why it helps

Seeded noise is the same on every read within a session, so drawing the same scene twice cannot see it; only a comparison with a known answer can. Reporting which probes failed tells your server that a browser is privacy-hardened (Brave, Firefox Fingerprinting Protection, Safari Advanced Fingerprinting Protection, or a noise extension) and why some graphics or audio components are noisy.

Why it is not in the id

It describes the browser’s privacy settings and extensions, which users change. It is a browser trait, not an integrity flag: noise is a privacy choice, not tampering. Changing it never changes the visitorId or the structuredId.

Stability

Stable for a given browser and its settings. It changes when a protection mode or a noise extension is switched on or off, when a private window is opened (several browsers add noise only there), and audio can move between a state and na on a slow or busy device that misses the 800 ms wait.

Browser support and what blocks it

Privacy

It reveals only whether the three reads are altered, which suggests a privacy setting or an extension. The test patterns are fixed and contain nothing about the page or the user. WhiskerJS does not try to work around the noise.

How WhiskerJS handles noise and failures

Status ruleId When
ok the three probe states, for example canvas=exact,webgl=na,audio=exact
excluded caller_excluded you excluded it (the probes still run for the class and the other components)
timed_out timeout, aborted the 1000 ms inner timeout, the overall budget or your abort signal

A probe that fails reports na inside the value instead of a non-ok status. Never hashed.

Example value

A stock browser with WebGL and Web Audio:

"noise_profile": { "status": "ok", "value": "canvas=exact,webgl=exact,audio=exact" }

Questions and answers

What do exact, seeded, per_read and na mean?

exact: both reads gave the known answer. seeded: both reads gave the same wrong answer, which is noise seeded per session or per site (Brave, Firefox Fingerprinting Protection, Safari Advanced Fingerprinting Protection). per_read: the two reads differed, noise drawn on every read. na: the probe could not run here; audio is also na when its probe takes longer than 800 ms.

Is seeded noise a sign of fraud?

No. Noise is a privacy choice made by the browser or the user, not tampering, so it is reported here and never as an integrity flag. Read it as a trait of the browser's settings.

Why is noise_profile not in the visitorId?

It follows privacy settings and extensions, which users switch on and off. The components the noise affects (canvas, webgl_image, audio) turn noisy instead, which keeps the id the same from session to session.