DEV Community

Hussein Al Hammad
Hussein Al Hammad

Posted on

The privacy concerns of the noscript land

I have recently learned that deferred loading of <img>s with the loading attribute only works if JavaScript is enabled.

<img loading="lazy" src="/image.jpg" alt="" />
Enter fullscreen mode Exit fullscreen mode

The MDN documentation notes that this is an anti-tracking measure:

Loading is only deferred when JavaScript is enabled. This is an anti-tracking measure, because if a user agent supported lazy loading when scripting is disabled, it would still be possible for a site to track a user's approximate scroll position throughout a session, by strategically placing images in a page's markup such that a server can track how many images are requested and when.

While the purpose of this behaviour seems reasonable on the surface, it made me thinks about two things:

1. The goal of disabling JS

This anti-tracking measure assumes that a user's goal of disabling JS is to prevent websites from tracking them and their actions on pages. This assumption justifies loading more resources on the user's device even if they do not scroll far enough down a page to need them.

I can't personally speak of the intention of disabling JS, but I am unsure how I feel about disabling the feature when JS is disabled in order to prevent tracking. After all, web features get maliciously used all the time.

Disabling deferred loading on img[loading=lazy] can have a direct impact on the user. I can see a user disabling JS in the browser to save on mobile data while browsing. They may not need to scroll all the way down to all pages. That is; they may not need to download all the images on all pages they visit. In this case, the anti-tracking measure backfires.

2. The noscript tracking paths

There are plenty of user-behaviour tracking approaches that work without JS.

The loading attribute on iframe

The loading attribute also works on <iframe>s. The current implementation of the loading attribute on <iframe> works even when JS is disabled. iFrame tracking pixels can be used to workaround the anti-tracking measure on images.

The ping attribute on anchor tags

The ping attribute on an anchor tag is typically used for tracking. It accepts a space-separated list of URLs to which the browser sends POST requests when the link is followed:

  Contact Us
Enter fullscreen mode Exit fullscreen mode

The ping attribute works even when JS is disabled. It is disabled by default in Firefox though.

The noscript tag

The <noscript> element can be used to conditionally load different/additional tracking pixels when JS is disabled:

  <!-- add tracking pixels here -->
Enter fullscreen mode Exit fullscreen mode

The CSS approach

CSS provides a number of ways to conditionally apply styles. It also provides a number of ways to load external resources such as images. So it is entirely possible to make use of this to track users without the need of JS.

Using media queries:

@media (prefers-color-scheme: dark) {
  #tracker {
    background-image: url(/my-tracker.png);
Enter fullscreen mode Exit fullscreen mode

Using feature queries and browser-specific prefixed CSS properties:

@supports (-webkit-overflow-scrolling: touch) {
  #tracker {
    background-image: url(/my-tracker.png);
Enter fullscreen mode Exit fullscreen mode

CSS also provides a number of ways to apply styles based on user interactions. For example, you can track some user actions in a similar manner to the above using pseudo-classes. And I'm sure there are more novel ways to make use of other CSS features for tracking.

Final thoughts

Built-in anti-tracking measures is a very nice goal in theory, but it seems very hard to implement without sacrificing something else in return.

So this begs the question: is "whether JS is enabled in the browser" the right criterion for enforcing built-in anti-tracking measures?

This article was first published on on 20 February 2021

Top comments (0)