Fix timingSafeEqStr to run the comparison before checking length

The `timingSafeEqStr` helper guarding download tokens was short-circuiting on length mismatch before invoking the constant-time comparison underneath. That early return undermines the whole contract: an attacker with timing access could distinguish a length mismatch from a content mismatch.

securityinfrastructure

The fix is an order-of-operations change. The comparison now always runs against zero-padded buffers of equal length first, then the length equality is checked and folded into the result. The helper is also exported so it can be unit-tested directly. The PR ships tests for equal strings, same-length mismatches, different-length mismatches, and empty inputs.

bmersereau is explicit about the practical severity: every SHA-256 base64url signature in the system is 43 characters, so no attacker-controlled length variation reaches this code path for standard tokens. The value is making the primitive correct on its own terms, so future callers that pass variable-length inputs inherit a helper that actually honors its constant-time contract.

No other changes. This is a targeted correctness fix on a single utility function.

So what Low cost to adopt. If you've built anything on top of this helper or plan to use it for variable-length comparisons in the future, the fix is worth taking. Skip if the only caller is the standard 43-character token path and you're comfortable leaving a technically incorrect primitive in place.

View this fork on GitHub →

Spotted something wrong? Or know the PR text has fresher detail than the writeup above?