How the Web Audio API is used for browser fingerprinting

When generating a browser identifier, we can read browser attributes directly or use attribute processing techniques first. One of the creative techniques that we’ll discuss today is audio fingerprinting.

Using an Oscillator and a Compressor they can basically calculate a specific number that identifies you.

Every browser we have on our testing laptops generate a different value. This value is very stable and remains the same in incognito mode.

And this only takes a few ms to calculate! 🤯

How the Web Audio API is used for browser fingerprinting →

Firefox State Partitioning

State Partitioning is an interesting privacy feature shipping with Firefox 86.

With State Partitioning, shared state such as cookies, localStorage, etc. will be partitioned (isolated) by the top-level website you’re visiting. In other words, every first party and its embedded third-party contexts will be put into a self-contained bucket.

Applies to every embedded third-party resource (regardless of whether it is a tracker or not), but some exceptions for Single Sign-On purposes have been made.

Firefox State Partitioning →

As of version 85 a similar feature landed in Chromium. Safari introduced partitioning for Cookies with its Intelligent Tracking Prevention 1.0. Can’t find any mention whether Safari also partitions other 3rd-party content, but I think they do.

☝️ Without these protections, ads follow you around the internet.

How ads follow you around the internet

A video-version of How tracking pixels work by Vox:

In this video, we explain how cookies work and what you should know about how they’re being used. And we get a little help from the man who invented them.

Spot on “Finding Dory” analogy. One thing where they do go off a bit is that they somewhat imply that all data (such as shopping cart contents) is stored in the cookies themselves. That’s not the case: the cart contents are – or at least they should be – stored on the server. Only the cart’s ID (or your visitor/session ID) is stored in the cookie. The serverside code will then use that ID to get your card contents.

Also: would have loved to see a few examples with actual mentions of domain names to have it more clear.

Stealing Usernames, Passwords, and other (Personal) Data via Browsers and NPM Packages

👋 This post also got published on Medium. If you like it, please give it some love a clap over there.

Late 2016, Stoyan Stefanov published “Oversharing with the browser’s autofill”. It’s an article on stealing personal data using the browsers their form autofill feature. The attack works by leveraging abusing the fact that autocompletion will also complete fields which are visually hidden.

Note: it was only in January 2017 that this type of exploit gained traction, and was accredited to the wrong person (see this ZDNet article for example). As Stoyan points out in his article: it’s been warned about as early since 2013.

If it’s a comfort: it’s not until you enter data in one field and successively choose to autocomplete, that you’re leaking data.


Fast forward to late 2017: In “No boundaries for user identities: Web trackers exploit browser login managers” the autocomplete feature of password managers is abused by rogue advertising scripts.

Since your password manager (and your browser itself) will prefill usernames and passwords, any script loaded can read these out and do whatever they want to with it. Unlike the autocomplete above this kind of leak will happen automatically .At least two advertising scripts have been identified to using this technique to collect usernames.

The only way to prevent this is that browsers return empty strings for autocompleted values when reading them in via input.value,
or at least present a confirm dialog (and pause the JS runtime) until approved.


In “I’m harvesting credit card numbers and passwords from your site. Here’s how.” David Gilbertson notched it up a little:

I can’t believe people spend so much time messing around with cross-site scripting to get code into a single site. It’s so easy to ship malicious code to thousands of websites, with a little help from my web developer friends.

I know, the previous attacks mentioned weren’t XSS attacks, yet one could perform them through after injecting a remote script 😉

All you have to do is write a successful NPM package which others will use. Popular ones are things like logging libraries (*), which have many many downloads. If you then release a version with some rogue code …

(*) Speaking of: my Colored Line Formatter for Monolog has surpassed 250K downloads this week!

Would this kind of hack code be detected easily? Not really. The versions that get published on NPM are compiled and minified versions which are nowhere to be found in the source repo. Above that the compiled code can be obfuscated, so that words like fetch don’t appear in it. And requests performed via dynamically injected links that have a rel="prefetch" attribute set can bypass Content Security Policies.


Yesterday evening there was a small debacle on the NPM front as several packages had gone missing … it was left-pad chaos all over again, albeit for only a short period of time.

One of the packages missing – namely pinkie-promise – is used in eslint, which itself is used just about everywhere. Installing dependencies in React-based apps didn’t work anymore because of this.

By now the issue has been resolved (postmortem here), yet the window between Jan 06, 2018 - 19:45 UTC (identified) and Jan 06, 2018 - 21:58 UTC (resolved) was a very dangerous one. In said window any developer could release (and have released!) packages with the same name. Mostly they were re-publishes of the actual thing, yet one could’ve also published rogue versions such as the ones described above.

NPM is already fighting name squatters by disallowing variants with punctuations and promoting the use of username-scoped packages, but I personally think an extra feat is missing: upon unpublishing of a package (be it by accident or not), its name should be quarantined for 30 days. In that 30 day window no NPM user other than the original one should be able to republish a package having the same name. Additionally there should be an option for the original author to release or transfer a package name to another NPM user.


Did this help you out? Like what you see?
Consider donating.

I don’t run ads on my blog nor do I do this for profit. A donation however would always put a smile on my face though. Thanks!

☕️ Buy me a Coffee ($3)

Stealing your browser history with the W3C Ambient Light Sensor API

A few years ago window.getComputedStyle and the like where adjusted to return the default color of links, instead of the actual color on screen.

Security and privacy were the driving factors behind that decision: by styling :visited links with a different color than their non-visited counterparts, a hacker could easily determine which sites a user has visited by simply checking the color of each link.

// @ref
var links = document.links;
for (var i = 0; i < links.length; ++i) {
    var link = links[i];
    if (getComputedStyle(link, "").color == "rgb(0, 0, 128)") {
        // we know link.href has not been visited
    } else {
        // we know link.href has been visited

With that hole now plugged for quite some time, Lukasz Olejnik turned towards the Ambient Light Sensor API to perform a likewise hack:

Since a website can apply different styles to visited and unvisited links, but cannot detect how the links are displayed to the user, we use the sensor to identify its true color:

  1. Set link styles: visited (white), unvisited (black).
  2. Calibrate: display a white background, then follow with a black background to identify the light levels in the user’s environment; this is also possible, but more difficult, if sensor readings fluctuate significantly.
  3. Iterate through a list of links, one by one, displaying each of them in turn as a large rectangle which fills the entire screen. Visited links will show up as white, unvisited as black.
  4. Log the light levels in response to displaying each link, identifying its color. Since we calibrated the screen in step #2, we know which color each reading represents.

At the end the attacker obtains a list of links for which the screen was white and knows that the user had previously visited the given pages.

Using the same technique it's also possible read out QR codes.

Stealing sensitive browser data with the W3C Ambient Light Sensor API →

favicon.ico and redirect links as a privacy leak


Without your consent most major web platforms leak whether you are logged in. This allows any website to detect on which platforms you’re signed up. Since there are lots of platforms with specific demographics an attacker could reason about your personality, too.

The attack works by loading in a website’s redirect script, with its favicon (hosted on the same domain) set as the page to redirect to. When logged in, the redirect script will return the favicon. When not logged in, the redirect script will return the login page.

Knowing this you can set that URL as the source of an Image. That image’s onload/onerror will then give away if one is logged in or not:

<img src=""
     onload="alert('logged in to fb')"
     onerror="alert('not logged in to fb')" />

Your Social Media Fingerprint →

How you can use Facebook to track your friends’ sleeping habits

"lastActiveTimes": {
 "3443534": 1456065265,
 "675631492": 1456066386,
 "8657643": 1456062331,
 "255277634": 1456052450,
 "6423324": 1456065173,
 "235323452": 1456065096,
 "3265233223": 1456066381,
 "2432885644": 1456064016,
 "7464340313": 1456062500

In the HTML source code of you can find an object containing userids associated with timestamps of last activity – as shown above. Given this it’s really easy to scrape and combine this data in order to get to know each user his/her sleeping pattern.

How you can use Facebook to track your friends’ sleeping habits →

Your Face is Big Data



Interesting project by Russian photographer Egor Tsvetkov in which he took photos of random, anonymous, people riding the subway, and then running them through a face recognition app named FindFace. The result: 70% of those photographed could be linked to one or social network profiles of ‘m, thus un-anonymizing them.

End of anonymity: Identification of random passengers (Russian) →