X-Runtime Header Timing Attacks
The X-Runtime HTTP response header is used to provide the time (in seconds) an application takes to process each request. This behavior can be exploited in harvesting attacks where the value can be used to confirm whether a piece of information such as a username is valid or not.
During a penetration test an engineer notices that a login page takes approximately 400ms longer to process login failures for valid usernames as opposed to invalid usernames. Below shows a login request with a known valid username and an invalid password:
POST /api/v1/login HTTP/1.1 [..] username=admin&password=test HTTP/1.1 200 OK X-Runtime: 0.615905
The same request is then made with an invalid username:
POST /api/v1/login HTTP/1.1 [..] username=admin937380&password=test HTTP/1.1 200 OK X-Runtime: 0.203115
The X-Runtime value is consistently higher than accounts which are known to be invalid. The engineer believes that the application checks if the username exists, and if so, validates the password with a function such as bcrypt. If the username does not exist, no password lookup is necessary, and the application returns. The workflow creates an observable difference between the X-Runtime values of valid vs invalid usernames.
It is recommended the X-Runtime header be removed from pages which may be susceptible to harvesting attacks. The X-Runtime header most commonly originates in Rails applications via the Rack library.
Method 1 (recommended)
The header can be unset from Rack with an initializer file containing the following:
For environments where Rails config files cannot be modified, web server software may also be used to remove this header from the response. For Apache systems the following can be used to strip the header from responses:
First enable mod_headers:
$ sudo a2enmod headers
Unset the X-Runtime header:
Header unset X-Runtime