On 20 August 2026 a developer writing under the handle m-c-tech published a short investigation that has been sitting near the top of Hacker News ever since. The complaint that started it was almost comically mundane: an open AliExpress tab was stopping their Bluetooth headphones from switching cleanly between devices. No video was playing. No audio element existed on the page. Multipoint switching simply refused to work until the tab was closed.
The cause turned out to be two obfuscated scripts from Alibaba’s anti-abuse stack, collina.js and fireyejs.js, quietly constructing Web Audio graphs for device fingerprinting. That is an interesting privacy story on its own. The reason it matters to anyone shipping a commercial website is broader, and less comfortable: a third-party script nobody on the product team had ever read was consuming a real hardware resource on the user’s machine, in a way no browser control surfaced and no monitoring would have caught.
TL;DR
- Two Alibaba anti-fraud scripts on AliExpress build a hidden Web Audio graph (sawtooth oscillator into an analyser, through a zero-gain node, connected to the audio destination) to fingerprint the device.
- Zero gain means silence, but connecting to
AudioContext.destinationstill holds the system audio path open, which is what breaks Bluetooth multipoint switching. - The behaviour is invisible: no media element, no tab audio indicator, so browser mute controls do nothing and the page looks idle.
- Under ePrivacy Article 5(3) and EDPB guidance, fingerprinting is access to terminal equipment and needs consent regardless of whether you call it fraud prevention.
- If a vendor script runs on your domain, it is your consent record, your Core Web Vitals and your reputational problem. Audit what your third parties actually execute at runtime, not what their sales deck says they do.
What the script actually does
The graph is small and, from a signal-processing point of view, elegant. A sawtooth oscillator generates a predictable waveform. That waveform passes through an AnalyserNode and a ScriptProcessorNode, then a GainNode set to zero, then out to AudioContext.destination. The analyser reads back the frequency characteristics of the processed signal.
The trick is that identical input does not produce identical output across machines. Different browser builds, operating system audio stacks, resampling libraries and hardware introduce tiny, stable variations. Measure them precisely enough and you have a high-entropy identifier that survives cookie clearing, private browsing and, in many cases, a change of IP address. Combine it with the rest of what these scripts collected (canvas and WebGL rendering signatures, screen geometry, hardware concurrency, device memory, plugin inventory, WebRTC behaviour, performance timing, interaction patterns, motion and orientation sensors) and you have a device identity that is considerably more durable than anything the user can see or delete. The results were serialised, encrypted and sent back via fetch() and sendBeacon().
None of that is new. Web Audio fingerprinting has been documented for the better part of a decade. What makes this case instructive is the side effect.
Why silence is not the same as inactive
Setting gain to zero means nothing is audible. It does not mean nothing is happening. Connecting the graph to AudioContext.destination puts the context into a running state and registers the page as an active audio consumer with the operating system. The Bluetooth stack sees a device that is playing, so it keeps the audio link warm and declines to hand the connection over to the second paired device.
The user experiences this as their headphones being broken. There is no media element, so Chrome shows no audio indicator on the tab and the per-tab mute control has nothing to mute. The author only found it by instrumenting the AudioContext constructor and wrapping AudioNode.connect() before loading the page, at which point two contexts appeared in a running state with no play() call anywhere in sight.
Blocking the scripts with uBlock Origin filters stops it, but only for new page loads. As the author notes, blocking a script does not tear down an audio context it has already created, so existing tabs have to be closed.
The pattern, not the incident
We have written before about the client-side supply chain, usually in the context of an outright compromise. This is a different failure mode and in some ways a more awkward one, because nothing here was hacked. The vendor script did exactly what the vendor built it to do. The harm was a side effect the vendor either did not test for or did not consider their problem.
That pattern generalises well beyond audio. Third-party scripts routinely hold wake locks, poll sensors, keep WebSocket connections open, run requestAnimationFrame loops on hidden tabs and schedule background sync. Each of those consumes battery, bandwidth or a hardware resource that belongs to the user, not to you or your vendor. Your synthetic monitoring will not see it, because synthetic monitoring measures load performance, not what the page does at minute forty of an idle session. Your real user monitoring will not see it either, unless you built it to.
The commercial exposure is real. If a fraud vendor, session-replay tool or ad tag on your checkout page is fingerprinting users, that is your processing activity under GDPR and your consent obligation under ePrivacy. The EDPB’s guidance on tracking technologies is explicit that Article 5(3) covers any access to information stored in terminal equipment, which includes reading device characteristics, not just setting cookies. “Our fraud vendor does it” is not a lawful basis, and “it is necessary for security” is a defence that gets thinner the moment the same identifier is also used for analytics or attribution.
What to do about it
Five things, in rough order of how quickly you can do them.
Inventory what actually executes. Not the tag manager’s list of configured tags, the network waterfall on a real production page load, including scripts loaded by other scripts. Most teams find at least one thing they cannot account for. If a third party can inject further third parties, your inventory is a snapshot, not a control.
Instrument the APIs you care about. The technique that cracked this case takes about fifteen lines. Wrap AudioContext, navigator.geolocation, getUserMedia, WakeLock and the sensor constructors in a staging build, log the call with a stack trace, and load your own site. You will learn more in an afternoon than in a quarter of vendor questionnaires.
Put a Content Security Policy in front of it. An allowlisted script-src with report-uri turns “some vendor added a new CDN host” from an invisible event into an alert. Subresource integrity is worth having but will not save you here, because vendors legitimately update these files and you will end up pinning a hash you have to bump weekly. The policy is the useful lever; the report endpoint is the useful signal.
Make it contractual. Your data processing agreement should name the specific device signals a vendor may collect and require notice before that list changes. If a vendor will not tell you what their obfuscated bundle reads from the device, that is an answer.
Add a long-session idle test. Load a page, leave it for thirty minutes, and check CPU, network and audio state. It is a five-minute manual test that almost nobody runs, and it catches an entire category of third-party misbehaviour that page-load metrics are structurally blind to.
The uncomfortable bit
Anti-fraud fingerprinting exists because fraud exists, and the vendors selling it are solving a genuine problem for merchants who would otherwise eat the chargebacks. We are not going to pretend that is illegitimate. But the deal being struck is that a user visiting a shopping site has their device silently and durably identified, and in this case has their headphones degraded, so that the merchant can reduce a cost the user never knew about. When that trade-off is made invisibly by a script the site operator has never read, nobody is meaningfully consenting to anything.
The teams that will handle this well are the ones treating third-party runtime behaviour as part of their own product surface, because legally and reputationally it already is. When a user’s headphones stop working on your site, they do not file a bug against your fraud vendor. They just leave.
At REPTILEHAUS we run client-side supply chain audits as part of our security and DevOps work, covering script inventory, CSP rollout, runtime API instrumentation and the consent architecture that has to sit underneath all of it. If you have never actually looked at what your third-party tags do after the page finishes loading, that is a good place to start. Get in touch and we will take a look.
📷 Photo by C D-X (@cdx2) on Unsplash


