Skip to content

[Security][Low] Timing oracle in download token verification — early length exit before constant-time compare #72

@bmersereau

Description

@bmersereau

Severity: Low

File: backend/src/lib/downloadTokens.ts:39-41
CWE: CWE-208 — Observable Timing Discrepancy
OWASP: A02:2021 — Cryptographic Failures

Description

The HMAC comparison function exits early if the string lengths differ, before reaching the constant-time comparison:

function timingSafeEqStr(a: string, b: string): boolean {
    if (a.length !== b.length) return false;  // early exit — timing leak
    return crypto.timingSafeEqual(Buffer.from(a), Buffer.from(b));
}

Impact

A network-positioned attacker can distinguish "wrong length" responses from "correct length but wrong value" responses by measuring timing. In practice, SHA-256 always produces 32 bytes → 43-char base64url, so this leaks no useful information for standard token forgery attempts. The risk is low and theoretical, but the pattern violates the contract of a constant-time comparison and should be corrected.

Fix

Remove the early length check. Perform the comparison unconditionally, padding to equal length:

function timingSafeEqStr(a: string, b: string): boolean {
    const aBuf = Buffer.from(a);
    const bBuf = Buffer.alloc(aBuf.length);
    Buffer.from(b).copy(bBuf);
    // Compare in constant time; also verify lengths match
    return crypto.timingSafeEqual(aBuf, bBuf) && a.length === b.length;
}

Remediation tier: Backlog — low priority, no immediate exploit path.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions