Security Enhancements
-
Replay attack protection: new
verifyCodeOnce(string $secret, string $code, int $lastAcceptedSlice, int $discrepancy = 1): ?intmethod. Returns the matched time slice on success, so callers can persist it and block reuse of the same code. -
Secret security audit: new
auditSecret(string $secret): arraymethod. Returnslength_bytes,is_strong, andwarningsfor a given secret without throwing exceptions. Useful for validating user-supplied or legacy secrets at onboarding time. -
Discrepancy bounds enforcement:
verifyCode()andverifyCodeOnce()now throwTotpExceptionifdiscrepancy < 0ordiscrepancy > max_discrepancy(default: 10). This prevents an unbounded verification window from being set accidentally or maliciously. -
Configurable discrepancy ceiling: pass
['max_discrepancy' => N]to theTotpconstructor to tighten or relax the upper bound for your application's risk profile. -
Weak secret logging:
validateSecret()now callserror_log()with a warning when the decoded secret is shorter than 20 bytes. No exception is thrown; existing behaviour is preserved. -
64-bit time slice packing:
packTimeSlice()now usespack('J', $timeSlice)(native 64-bit big-endian unsigned integer) instead of the previous 32-bit workaround. Output is byte-for-byte identical for all current timestamps; this future-proofs the library for timestamps beyond 2038.
Quality
- Test suite expanded from 60 to 76 tests covering all new code paths.
Upgrade Notes
No changes to existing method signatures or default values. All existing code continues to work without modification. The only observable behaviour change is that verifyCode() now throws TotpException for discrepancy > 10, which was not a supported use case in prior versions.