The reset token is randomized, but it is compared to user input with === which short circuits on the first mismatch. This means that timing the response allows an attacker to determine how many characters of user input match the stored secret value. Since the secret value doesn't reset on incorrect attempts, you can just keep making guesses and taking timing measurements, and you can keep determining how many leading characters are correct in your guess because each new correct character will result in the function taking slightly longer to return, because it does more computation prior to short circuiting. So the randomized reset token isn't actually as helpful as it appears to be, it can be determined by an attacker as previously described. However, it doesn't let you pick a password, rather it randomly generates one and E-mails it to you. This means that you can't use this flaw to take over a targets account, because passwords are done like
$password_hash = hash("password");
$password_hash === "6b3a55e0261b0304143f805a24924d0c1c44524821305f31d9277843b8a10f4e"
$password_hash is put in the database. When you go to login you send in plaintext (well, link encrypted with tls)
$password = "password";
at this point $password is hashed
6b3a55e0261b0304143f805a24924d0c1c44524821305f31d9277843b8a10f4e
and compared to the string in the database
6b3a55e0261b0304143f805a24924d0c1c44524821305f31d9277843b8a10f4e === 6b3a55e0261b0304143f805a24924d0c1c44524821305f31d9277843b8a10f4e
Although it still short circuits on mismatches, I can't directly control the value because it is the hash value of a password, it doesn't directly use the password, so even if I find a password with collisions like
6baaaaaaaaaaa0304143f805a24924d0c1c44524821305f31d9277843b8a10f4e
and it short circuits on the first mismatch, well, I can't easily pick a new password that hashes to everything that I know is a match + an arbitrary character after that to continue testing. So passwords using a system like this are not weak to timing attacks like this.
However, the session cookie isn't using that logic:
$rememberKey is user provided, and $this->prepareRememberKeyForCookie() returns a hash value from a static database value.
This means that I can keep brute forcing the $rememberKey value and taking timing measurements, and each time it takes statistically slightly longer than before, I can assume I got another character correct and then move on to the next character just like with the password reset token, eventually this will allow me to grab the session key.
It looks like IP checks will fuck me on this though, but actually kiwifarms.net doesn't have IP checks enabled so I don't need to worry about that. I'm still not confident enough to say I'm sure, but due to IP checks on sessions not being enabled, I think this may be enough to hijack sessions when users set a remember me cookie.