Assuming that the server takes actions based on a certain condition, let’s analyze a scenario where the server performs computations depending on the result of that condition and then returns a response to the user. In both cases, whether the computations are performed or not, the server returns a response to the user. It is worth noting that when the server performs computations, it consumes a certain amount of resources, which leads to an increase in server response time. Usually, these differences in response times are so small that they are not noticeable to the end user. However, revealing these subtle differences in response times can lead to unintended data leaks.
Let’s now consider a practical example of this situation, based on the login process to an application. Assume that the provided login is correct, but the password is incorrect: in such a case, the server may decide to perform computations, such as verifying the password. If the server performs these computations, it may require additional resources and result in a longer response time compared to a scenario where computations are not performed. Although the differences in response times are usually small, they are present and can be measured by an attacker.
The same process, but also when the login is incorrect:
In cases of such subtle differences in response times, an attacker may attempt to use this information to infer the correctness of a login. For example, an attacker can perform a timing attack by analyzing the time it takes for the server to respond to requests with different logins. By comparing response times, the attacker can infer which request took more time, suggesting that the login was correct. Revealing the user’s login allows attackers to conduct a brute force attack to guess the password. In some cases, it may also mean disclosing sensitive information, especially when the login is an email address associated with a specific person and the tested application is a portal with controversial content.
Testing with Burp Suite – Request Timer
When searching for this type of vulnerability, the Burp plugin called Request Timer will be helpful. This plugin will allow us to examine the server’s response time for specific requests we send.
The first step is to capture the request responsible for user login and send it to the Intruder module:
Next, we change the password to a long string to increase the server load during password hash generation. We indicate where the user’s login is located. For the tested application, it is also necessary to add the “X-Forwarded-For” header and assign it a random IP address to bypass the login attempt block from the same IP address. Consequently, we need to change the attack type to “Pitchfork.”
We add a list of logins to check:
In the Request Timer plugin, we define it to listen to the Intruder module:
After running the test, the generated requests along with the response times will appear in the tab. As you can see, the response time is significantly longer for a valid login. This way, we’ve demonstrated that the application is vulnerable to user login enumeration by analyzing server response times.
What to do, how to live?
One solution to this type of problem is to add a function responsible for randomly delaying the server’s response:
Nevertheless, the problem with this type of solution is that we still do not have control over situations such as network latency during an attempt to connect to the database or differences that arise when the database grows significantly.
A better solution seems to be to perform the operations of verifying the data provided by the user asynchronously in the background and immediately notify the user of the login attempt. In such a case, the computations and associated delays remain invisible to the attacker.