otphp
otphp copied to clipboard
TOTP -> verify doesn't seem to be correctly implemented to include leeway
Version(s) affected
11.0
Description
Hi, We've noticed that the latest implementation of the verify method in TOTP.php seems to be completely off. It should compare all possible otps between now and each period increment up to leeway. The current implementation only compares the current otp, the one +leeway and -leeway. The presumably buggy code seems to appear in the 15Feb commit.
Apologies if I've missed something and thanks for the great work!
How to reproduce
Leeway = 4 used to work as +-4 periods before and after, now it works as +-4 seconds before and after. PS: this makes it impossible to use a period of 30seconds and have a window of 1 minute extra.
Possible Solution
Bring back the old implementation.
Additional Context
No response
Hi,
Leeway = 4 used to work as +-4 periods before and after, now it works as +-4 seconds before and after.
This is correct. The behavior of the leeway parameter changed in v11. This has been introduced by https://github.com/Spomky-Labs/otphp/pull/152.
PS: this makes it impossible to use a period of 30seconds and have a window of 1 minute extra. This is right. This is actually the expected protection induced by this PR. The problem with the previous version is that it is easy to reduce the security of the OTP. With a window of 4, you divide by 9 the number of possibilities (4 periods before and after + the current period).
If you still need such flexibility, you have to implement it explicitly:
$window = abs($window);
for ($i = 0; $i <= $window; ++$i) {
$next = $i * $this->getPeriod() + $timestamp;
$previous = -$i * $this->getPeriod() + $timestamp;
$valid = $this->compareOTP($this->at($next), $otp) ||
$this->compareOTP($this->at($previous), $otp);
if ($valid) {
return true;
}
}
return false;