A timing attack is a rather sophisticated way to circumvent the security mechanisms of an application. In a timing attack, the attacker gains information that is indirectly leaked by the application. This information is then used for malicious purposes, such as guessing the password of a user.
The only information needed the attacker is the timing information that is revealed by the algorithms of the application. By supplying various inputs to the application, timing the processing and statistically analyzing this information, the attacker can guess the valid input.
In this example, we are examining a web-based document storage application that allows users to access their data through an HTTP-based API.
The application uses a separate subdomain for each customer. The customer that
we are interested in is BigCorp, who uses the following address to access
The API is secured using a unique API key for each customer. BigCorp has the
following API key:
This is the authentication function that is called for each API request:
def authenticate(subdomain, api_key) customer = Customer.find_by_subdomain(subdomain) if customer if api_key == customer.api_key # Timing attack vector return customer else raise 'Invalid API key' end else raise 'No customer was found' end end
The attacker first needs to know which subdomain their target, BigCorp,
is using. If they do not already have this information, a quick survey
of likely subdomains will reveal the login page of BigCorp at
bigcorp.sampleapp.com; no sophisticated techniques required yet.
authenticate function uses a regular non-constant time string comparison
function to verify the API key, which will allow the attacker to guess BigCorp’s
API key, one character at a time. Most string comparison functions check each
byte of the string and stops execution when it meets the first difference. Thus,
with a 32-byte API key, the string comparison will take 31 times longer to run
when the strings are equal, than when their first characters are different.
By incrementally constructing API keys and measuring sample response times, which are then fed into statistical models, a pattern emerges:
# String comparison time: 15ns 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' == 'V1cHt2S67DADJIm9sX9yzCc272EkSCto' # String comparison time: 15ns 'baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' == 'V1cHt2S67DADJIm9sX9yzCc272EkSCto' # ... # String comparison time: 30ns 'Vaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' == 'V1cHt2S67DADJIm9sX9yzCc272EkSCto' # ... # String comparison time: 45ns 'V1aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' == 'V1cHt2S67DADJIm9sX9yzCc272EkSCto' # ... # String comparison time: 480ns 'V1cHt2S67DADJIm9sX9yzCc272EkSCto' == 'V1cHt2S67DADJIm9sX9yzCc272EkSCto'
As seen above, once the first character in the input string matches the API key, the string comparison takes twice as long, and the attacker now knows the first character of the API key.
Obviously, the difference in time is minuscule compared to the hundreds of milliseconds spent on communicating over the network, performing database queries etc. Filtering out the signal among what is mostly noise, makes this type of attack very difficult and time consuming.
However, the attacker may take steps to reduce the noise, such as running the attack through the same cloud provider as the application, in order to reduce network latency. The possibility of timing attacks over the web has been proven, making timing attacks a vector that should be considered, especially they are typically easily mitigated.
In this case, using
would have prevented the timing attack.
The defence against timing attacks involves identifying the security critical sections of the software. For those sections, the code should be using constant-time functions for string comparison and generally making the number of computations needed for processing a request independent of the input.
If a constant-time alternative for the security critical operation, manually inserting an input-dependent delay or clamping the operation to take a minimum time are alternative ways to prevent an attacker from gaining timing information.
Finally, monitoring user activity and blocking brute-force attacks through rate limiting help identify this type of attack and is generally advisable.
These are some useful language-specific articles on the subject:
We provide code security reviews as a service. Based on our extensive experience in the field of sofware engineering and IT security, we know how to efficiently review entire code bases and identify security critical parts of the software.
This enables us to provide our security code review service at a fixed rate per review, providing our customers a transparent, efficient and reliable process.
Fixed Price per Review
Our code security review service is in popular demand.
Next spots are available in July 2019.