Network Timing

Network Timing

October 1, 2020
Abuse iframes
Category Attack
Defenses Fetch Metadata, SameSite Cookies, COOP, Framing Protections

Network Timing side-channels have been present on the web since its beginning 1 2. These attacks have had different levels of impact over time, gaining new attention when browsers started shipping high precision timers like performance.now().

To obtain timing measurements attackers must use a clock, either an implicit or explicit one. These clocks are usually interchangeable for the purposes of XS-Leaks and only vary in accuracy and availability. For simplicity, this article will assume use of the performance.now() API, an explicit clock present in all modern browsers.

This side-channel allows attackers to infer information from a cross-site request based on how much time it takes to complete that request 3. The network timing measurement may vary based on a user state and it’s usually connected to:

  • The resource size.
  • The computation time in the backend.
  • The number and size of sub-resources.
  • Cache status.

tip

Learn more about the different types of clocks in the Clocks Article.

Modern Web Timing Attacks #

The performance.now() API can be used to measure how much time it takes to perform a request.

// Start the clock
var start = performance.now()

// Measure how long it takes to complete the fetch requests
fetch('https://example.org', {
  mode: 'no-cors',
  credentials: 'include'
}).then(() => {
  // When fetch finishes, calculate the difference
  var time = performance.now() - start;
  console.log("The request took %d ms.", time);
});

Onload events #

A similar process can be used to measure how long it takes to fetch a resource by simply watching for an onload event.

// Create a script element pointing to the page we want to time
var script = document.createElement('script');
script.src = "https://example.org";
document.body.appendChild(script);

// Start the clock
var start = performance.now();

// When script loads, caculate the time it took to finish the request
script.onload = () => {
  var time = performance.now() - start;
  console.log("The request took %d ms.", time)
}

tip

A similar technique can be used for other HTML elements, e.g. <img>, <link>, <iframe> which could be used in scenarios where other techniques fail. For example, if Fetch Metadata blocked loading of a resource into a script tag it may allow it into an image tag.

Sandboxed Frame Timing Attacks #

If a page doesn’t have any Framing Protections implemented, an attacker can time how long it takes for the page and all subresources to load over the network. By default, the onload handler for an iframe will be invoked after all the resources have been loaded and all Javascript has finished executing. But, an attacker can eliminate the noise of script execution by including the sandbox attribute in the <iframe>. This attribute will block a lot of features including Javascript execution, which results in almost pure network measurement.

var iframe = document.createElement('iframe');
// Set the URL of the destination website
iframe.src = "https://example.org";
// Set sandbox attribute to block script execution
iframe.sandbox = "";
document.body.appendChild(iframe);

// Measure the time before the request was initiated
var start = performance.now();

iframe.onload = () => {
  // When iframe loads, calculate the time difference
  var time = performance.now() - start;
  console.log("The iframe and subresources took %d ms to load.", time)
}

Cross-window Timing Attacks #

An attacker can also measure the network timing of a page by opening a new window with window.open and waiting for the window to start loading. The snippet below shows how to make this measurement.

// Open a new window to measure when the iframe starts loading
var win = window.open('https://example.org');
// Measure the initial time
var start = performance.now();
// Define the loop
function measure(){
  try{
    // If the page has loaded, then it will be on a different origin
    // so `win.origin` will throw an exception
    win.origin;
    // If the window is still same-origin, immediately repeat the loop but
    // without blocking the event loop
    setTimeout(measure, 0);
  }catch(e){
    // Once the window has loaded, calculate the time difference
    var time = performance.now() - start;
    console.log('It took %d ms to load the window', time);
  }
}
// Initiate the loop that breaks when the window switches origins
measure();

note

Note that this POC uses setTimeout in order to create the rough equivalent of a while(true) loop. It is necessary to implement this way in order to avoid blocking the JS event loop.

tip

This technique can also be adapted to measure the Execution Timing of a page by making the event loop busy.

Timeless Timing Attacks #

Other attacks do not consider the notion of time to perform a timing attack 4. Timeless attacks consist of fitting two HTTP requests in a single packet, the baseline and the attacked request, to guarantee they arrive at the same time to the server. The server will process the requests concurrently, and return a response based on their execution time as soon as possible. One of the two requests will arrive first, allowing the attacker to get the timing difference by comparing the order in which the requests arrived.

The advantage of this technique is the independence on network jitter and uncertain delays, something that is always present in the remaining techniques.

note

The original research needs to be adapted to work in a browser since it handles all network-specific tasks.

important

This attack is limited to specific versions of HTTP and joint scenarios. It makes certain assumptions and has requirements regarding server behaviors.

Defense #

Attack Alternative SameSite Cookies (Lax) COOP Framing Protections Isolation Policies
Modern Timing Attacks ✔️ RIP 🔗 NIP
Frame Timing (Network) ✔️ FIP
Frame Timing (Sandbox) ✔️ FIP
Cross-window Timing ✔️ NIP
Timeless Timing ✔️ ✔️

🔗 – Defense mechanisms must be combined to be effective against different scenarios.

References #


  1. Exposing Private Information by Timing Web Applications, link ↩︎

  2. Cross-domain search timing, link ↩︎

  3. The Clock is Still Ticking: Timing Attacks in the Modern Web - Section 4.3.3, link ↩︎

  4. Timeless Timing Attacks: Exploiting Concurrency to Leak Secrets over Remote Connections, link ↩︎