As the web becomes more and more capable, developers can make a richer online experience. However, there are times when some new network features may not work as expected due to usability, security, and privacy.

I have come across situations like this. Like lazy download to html. It’s easy to drop an attribute on a pixel just to understand … it actually needs more than anything to do its job. You’ll get to that in a moment when we look at a few other features that may not work exactly as you might expect.

This restriction has been in place for some time, but it shows how the features of the browser can be exploited. One possible exploitation is the anchor :visited link style in CSS and is placed off-screen. An off-screen anchor allows the anchor to be changed using JavaScript href value and see if certain href makes the link look visitor – by reconstructing the user’s history in the process.

Known as CSS history leak, this was at once so extensive that the U.S. Consumer Protection Agency had the Federal Trade Commission imposed severe fines for its exploitation.

Nowadays trying to use getComputedStyle a :visited the link returns the style :unvisited instead of a link. It’s just one of the things you need to know because it’s different from how it should intuitively work.

But we can work around this in two ways:

  1. make the style of the link you are visiting trigger a side effect (e.g. a change in layout) or
  2. take advantage of the sibling (~ or +) or a child (>) CSS options to render another style.

As for the side effects, even if there are some smart but fragile ways to do this, the options we have design :visited links are restricted and some styles (such as background-color) only works if they are used for unvisited links. Sibling or child use, execution getComputedStyle these restore the style as if the link was not used initially.

Browsers no longer cache sites

One advantage of CDN was that they made a certain resource (like Google Fonts) cached in a browser for use on different websites. While this offers a high performance profit, it has serious implications for privacy.

Given that content that is already cached takes longer to load than content that the site can download, the site may run timing attack seeing not only your site history but also revealing both who you are and your online activities. Jeff Kaufman gives an example:

Unfortunately, shared caching allows for data leakage. Summary of the simplest version:

  • I want to know if you are a Moderator at www.forum.example.
  • I know only the pages below charge www.forum.example/moderators/header.css.
  • When you visit my page, I upload www.forum.example/moderators/header.css and see if it came from the cache.

As a result, browsers no longer offer this.

performance.now() may be inaccurate

A scary vulnerability group emerged a few years ago, one of which was called Specter. See a full explanation on Google leaking.page (works best in chrome) as proof of the concept. But in this article, just know that recovery is based on getting very accurate timing, which is something performance.now() provides, attempts to map sensitive CPU information.

Text from the demo on the left side of the page and two black Germaine-looking code blocks on the right side with a black background and green text.
Presentation at leaking.page

To mitigate the spectrum, browsers have reduced its accuracy and may increase noise. These range from 20 μs to 1 ms and can be changed based on various conditions such as HTTP headers and browser settings.

Lazy loading loading the attribute will not work without JavaScript

Lazy loading is a technology in which resources are loaded into the browser only when it scrolls through a viewport. Until recently, we can only do this using JavaScript IntersectionObserver or onscroll. With the exception of Safari, we can use loading attribute for images and iframes (in Chromium) and the browser handles lazy loading.

Please note that lazy loading cannot be polyfill because the image will probably load by the time you check loading attribute support.

Doing this in HTML makes it sound like the attribute doesn’t require JavaScript at all, but it does. From WHATWG specifications:

  1. If scripts are disabled for the element, return false.

    Entry
    This is an anti-tracking measure because if a user agent supports lazy loading when scripts are disabled, the site could still track the user’s approximate scrolling position throughout the session by strategically placing images in page annotations so that the server can track how many images are requested and when.

I’ve seen articles mention that this feature supports how lazy you load “without JavaScript,” which isn’t true, though true, you don’t have to type anything.

Browsers may restrict features based on user settings

Some users may want to restrict browser functionality to improve security and privacy. Firefox and Tor are the two browsers that do this opposes the fingerprint setting which makes, for example, Decreasing the accuracy of certain variables (dimensions and time), omitting certain variables altogether, restricting or disabling some web APIs, and never answering media queries. WebKit has an outline document how browsers can approach fingerprint resistance.

Note that this goes beyond the usual tracking blocking features that browsers implement. It is unlikely that the user will implement this because they need a very accurate threat model for it. Some of this can be counteracted by progressive improvement, digestible deterioration, and user understanding. This limitation is a big problem when you really need to take fingerprints, such as detecting fraud. So, if it is absolutely necessary, look for alternative ways.

Screen readers may not care about the semantics of certain elements

Semantic HTML is great for many reasons, especially because it conveys the significance of the notation that software, such as screen readers, interprets and notifies users who trust them to navigate the Internet. It is essential for creating accessible websites. But sometimes these semantics are not conveyed – at least how you can expect. Something may be available, but it still has usability issues.

An example is habit deleting characters in a list removes its semantic meaning In WebKit when VoiceOver is enabled. It is a very common model, especially for site navigation. James Craig, Director of Apple Accessibility Standards explain why however, it is a question of usability W3C Design Principle for Priority Substances:

In case of conflict, consider users over authors with respect to implementers in terms of theoretical purity. In other words the weight or difficulty of the user should be given more weight than the cost to the perpetrators;

Another case where semantics may not be conveyed is the focus. Take internal elements such as strong, em, mark, ins, deland dataall elements which have a semantic meaning but which are barely read because they can become noisy. This can be changed in the user’s screen reader settings, but if you really want it to read, you can report it visually hidden that content either a :before or :after pseudo-element.

To illustrate this, I did a short example to see how NVDA in Firefox 89 and VoiceOver Safari 14.6 read semantic elements.

Unlike VoiceOver, NVDA reads some semantic elements (del, ins and mark) and tries to emphasize the text by gradually increasing the amount of highlighted text. Both have no difficulty reading :before/:after psudoelements. VoiceOver also read the tag brackets (greater than less), although both screen readers have the ability to change the way punctuation is read.

Make sure you emphasize emphasis, testing users and seeing what they need. I didn’t focus on the visual aspect, but the default format of highlighting elements can be inconsistent in all browsers, so make sure you give the appropriate style along with it.

Network storage may not be permanent

WHATWG network storage configuration contains a section on privacy it outlines possible ways to prevent storage space from being a tracking vector. One such way is to make the data obsolete. That is why Safari is controversial limits the script’s writable storage space to seven days. Note that this does not apply to “installed” websites added to the Home screen.

Conclusion

Interesting, isn’t it? Some network features that can be expected to work in a certain way just don’t work. This does not mean that the properties are incorrect and need to be corrected, but more attention when writing code.

It is worth examining your own assumptions during development. Critically examine what users need and consider it when making your site. You’re certainly welcome to get around these when you encounter them, but if you can’t, make sure you find and offer a reasonable incremental improvement and smooth digestion. That’s ok if users do not experience the website in exactly the same way in every browser as long as they are able to do what they need.

It’s a list of things that don’t work as expected. What’s on your list? I’m sure you have some and would love to see them in the comments!

LEAVE A REPLY

Please enter your comment!
Please enter your name here