BackgroundIn order to optimize a web application for speed, it's crucial to be able to accurately measure the performance characteristics of the web application. JavaScript-based mechanisms have existed for a long time. They are, however, unable to provide a complete or detailed end-to-end latency picture. For example, the following JavaScript shows a naive attempt to measure the time it takes to fully load a web page:

HTML

<html>

<head>

<scripttype="text/javascript">

var start = new Date().getTime();

function onLoad() {

var now = new Date().getTime();

var latency = now - start;

alert("page loading time: " + latency);

}

</script>

</head>

<bodyonload="onLoad()">

<!- Main page body goes from here. -->

</body>

</html>

The script above correctly calculates the time it takes to load the page after the first bit of JavaScript in the head is executed, however it does not provide any information about the time it takes to get the page from the server, or the initialization lifecycle of the page. Latency measurements, which is a single element of a broader range of performance elements, can be useful as a device fingerprint.

How It WorksLatency can be used to determine how far away a user is from the web server. If you know the client IP, the latency should be within a certain range. This data point is very useful for detecting miscreants on proxy servers, that may be proxing through your client machines and connecting to your system as the client. In cases where a proxy is deployed between the user agent and the web server, the time interval between the connectStart and the connectEnd attributes indicates the delay between the user agent and the proxy instead of the web server. With that, the web server can potentially infer the existence of the proxy. For SOCKS proxy, this time interval includes the proxy authentication time and the time the proxy takes to connect to the web server, which obfuscate the proxy detection. In case of an HTTP proxy, the user agent might not have any knowledge about the proxy server at all so it's not always feasible to mitigate this attack.The following figure illustrates the timing attributes defined by the PerformanceTiming interface and the PerformanceNavigation interface with or without redirect, respectively. Attributes underlined may not be available in navigation involving documents from different origins. User agents may perform internal processing in between timings, which allow for non-normative intervals between timings.

Entropy Estimate: 4.3 bits

CodeThe javascript function below fingerprints the browser languages. You may also download this code here: fp_latency.zip

Code

function fingerprint_latency() {

"use strict";

var strOnError, perfData, networkLatency;

strOnError = "Error";

perfData = null;

networkLatency = null;

try {

// supported by a number of modern browsers

perfData = window.performance.timing;

networkLatency = perfData.ConnectEnd - perfData.ConnectStart;

return networkLatency;

} catch (err) {

return strOnError;

}

}

ValidationUnlike other code on the Internet we do everything possible to verify our code for you. In order to minimize problems and maximize compatibility this code has been verified with JSLint and has been extensively tested with over 1100 OS/Browser combinations using BrowserStack.