4 ms·
This is very interesting if it was done for fun. However, this is very likely unsuitable for real world usage. A couple of issues I could see with a quick glanc
by susam 6y ago
This is very interesting if it was done for fun. However, this is very likely unsuitable for real world usage. A couple of issues I could see with a quick glance:
- Using '=' for comparing TOTPs in the totp.verify function[1] is not safe from timing attacks.
- The function random() used in the totp.random_base32 function[2] is not a cryptographically secure random number generator.
[1]: https://github.com/pyramation/totp/blob/7ec3104/packages/totp/sql/launchql-totp--0.0.3.sql#L111 https://github.com/pyramation/totp/blob/7ec3104/packages/tot...
[2]: https://github.com/pyramation/totp/blob/7ec3104/packages/totp/sql/launchql-totp--0.0.3.sql#L121 https://github.com/pyramation/totp/blob/7ec3104/packages/tot...
- namibj 6y agoYeah, timing attacks on string comparison are surprisingly easy, at least if the token/MAC has password-like entropy, not passphrase-like. To clarify: The boundary is somewhere around 70 bits where a significant financial incentive or considerable discretionary spending will be required to mount a successful attack.
- pyramation 6y agoThanks of the tips! the random() seems easily addressable with pgcrypto, but do you have any information or practical examples of how a timing attack would be mitigated here? It seems that speakeasy (a JS lib) or any TOTP that uses '=' to compare would have this issue... what else are you supposed to do?
- susam 6y agoYes, using '=' for comparing secrets is a common mistake in many implementations. The right thing to do would be to implement a string comparison function that always takes the same amount of time to complete regardless of whether the two input strings match or do not match or where they mismatch. See https://security.stackexchange.com/a/83671 https://security.stackexchange.com/a/83671 for some code examples that accomplish this by using the bitwise XOR operator to compare two corresponding bytes from both inputs and bitwise OR operator to accumulate the comparison results. As per my professional experience, this is a common pattern used in security-related code.
- pyramation 6y agook thank you! I just saw this. Adding a reference to the issue. Thanks ;)
- pyramation 6y agoI'm not an expert in timing attacks, but isn't this if we were doing equality on something like the secret? Not the TOTP value (which changes every interval)?
- susam 6y agoThe TOTP too is a secret between the client (usually a human user) and the server. After all, it is used to gain access to another system, so if an attacker can guess the TOTP then the security of the system is compromised. Consider the following example. The TOTP value to log into a system at a given time is 27182. Only the client and the server know this because they share the same secret key from which the TOTP values are generated. Now assume an attacker that can send arbitrary TOTPs to the system and has access to reliable timing information about how long it takes the server to compare the received TOTP value with the expected TOTP value. Now in practice, it is hard to get access to reliable timing information, especially when the communication is over a network where random network latency can make any timing measurements reliable. Regardless, good security requires that an attacker should not be able to deduce any information about the secret or the TOTP value despite the possibility of having reliable timing information. With the assumption of reliable timing information being available to the attacker, here is how an attacker would carry out the attack. Brute force the first digit of the TOTP by sending TOTP values 100000, 200000, etc. The observation that it takes slightly longer for the validation to fail for 200000 helps the attacker deduce that the first digit is 2. The attacker can perform this recursively for other digits and deduce all the digits within a maximum of 60 attempts. This is a great reduction in the security of the scheme which required 1000000 attempts originally. Of course, one can mitigate an attack like this by locking out the user's account after 5 failed attempts or so but that would be an additional layer of security. Each layer of security should be sound on its own. Therefore even if there is an account lockout facility, the TOTP validation algorithm should be secure on its own and should not be vulnerable to timing attacks.
- pyramation 6y agoThanks for the in depth explanation. So it seems that, during the interval (which defaults to 30s) they could possibly determine the TOTP value. It seems possible to brute force, however as soon as the interval changes, by default every 30 seconds, the TOTP is now new because time has passed. But assuming they could do some crazy thing like attempt 10,000 times within that interval, I suppose it's arguable that it should still be secure... So upon research looks like it's quite easily fixed by comparing all digits individually, and then aggregating if all all true, but continuing the iteration and checks even if a false value has been found. I suppose that would cover this case. Thanks for pointing this out! Will be adding an issue ;)