This bug is an example of ​http://cwe.mitre.org/data/definitions/208.html and very similar to ​https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2004-1602 .



Description



When attempting to authenticate using django.contrib.auth, if a user does not exist the authenticate() function returns None nearly instantaneously, while when a user exists it takes much longer as the attempted password gets hashed and compared with the stored password. This allows for an attacker to infer whether or not a given account exists based upon the response time of an authentication attempt.



This can be seen much more clearly when the number of rounds on the password hasher is set to something high like 100000.



Mitigation



In authenticate(), create a dummy user and set its password. If no user is returned from the database query, check a password which is guaranteed not to match against the dummy.



Note



This mitigation strategy does not entirely mitigate a timing attack of this fashion. It does, however, greatly increase the amount of work required to gain usable information from it. For example, with a smaller variation between the two cases (user exists, user does not exist), the differences in lengths of time become much harder to distinguish from network transit times.

