Safeguard
Application Security•

CWE-1254 Incorrect Comparison Logic Granularity: Timing Attacks

Comparing secrets one byte at a time and stopping at the first mismatch leaks the answer through timing. CWE-1254 shows the bug and the constant-time fix.

Safeguard Security Team
4 min read

CWE-1254 is the weakness of comparing a secret in a series of small steps and quitting at the first failure. Passwords, message authentication codes and challenge responses are all checked this way in the wild. The time the check takes tells an attacker how much of their guess was right. It hits anyone who writes authentication, signature or token verification code, in software or in hardware.

How it happens

A comparison of two strings can be done in one operation across the whole value, or in steps. The stepwise version, byte by byte, usually breaks out of the loop as soon as a byte differs. That is natural and fast, and it is the problem.

If the first byte is wrong, the check ends almost at once. If the first byte is right and the second is wrong, it takes slightly longer. Over many attempts, an attacker who can measure those differences learns the correct value one position at a time and can work up to the full password or signature.

MITRE lists three real cases. CVE-2019-10071 is a Java framework that compared HMAC signatures with String.equals() instead of a constant-time algorithm, producing timing differences (Gold page). CVE-2019-10482 describes a smartphone OS whose comparison functions are not constant time, allowing side channels (Gold page). CVE-2014-0984 is a router password check that stops validating at the first incorrect character, so remote attackers can recover passwords by brute force (Gold page).

What an attacker gains

The record lists confidentiality and authorization: bypassing a protection mechanism. With enough attempts the attacker can guess the correct password or challenge response and gain elevated privileges. A forged MAC means forged messages that the system accepts as authentic.

How to find it

The record lists no detection methods. These checks work well in code review:

  • Search for equality operators or standard string comparisons applied to secrets, tokens, MACs, signatures and password hashes.
  • Look for loops that compare element by element and return or break on the first difference.
  • Review any custom comparison routine in authentication code.

A starting grep for Python code:

grep -rnE "(signature|digest|mac|token|hmac)[a-z_]* *(==|!=)" --include="*.py" .

It will produce false positives. Each hit is worth a quick look.

How to fix it

MITRE's mitigation, for the implementation phase: compare in one operation instead of in smaller chunks. For software, the usual meaning is a constant-time comparison function provided by the language or a cryptography library, so the time taken does not depend on where the first difference sits.

Python:

# Vulnerable: stops at the first differing byte
if provided_mac == expected_mac:
    accept()
# Fix: constant-time comparison from the standard library
import hmac
if hmac.compare_digest(provided_mac, expected_mac):
    accept()

Java:

// Vulnerable: String.equals can return early
if (providedSig.equals(expectedSig)) { accept(); }
// Fix: MessageDigest.isEqual compares in constant time
import java.security.MessageDigest;
import java.nio.charset.StandardCharsets;

if (MessageDigest.isEqual(
        providedSig.getBytes(StandardCharsets.UTF_8),
        expectedSig.getBytes(StandardCharsets.UTF_8))) { accept(); }

Also put a limit on failed attempts. Timing attacks need many tries, and a lockout or rate limit raises their cost sharply.

Try it yourself

Timing leaks like this are the kind of pattern a static scan can flag. Walk through a code scan to see how findings are reported.

Click through it at your own pace, or open it full screen.

If a vulnerable comparison sits in a library you depend on, reachability analysis tells you whether your code actually calls the affected function. You can check your dependency list for free with the in-browser scan at gold.safeguard.sh/scan. No login is required, and the file stays on your machine.

Quick check

Why does an early exit leak information?

The comparison takes longer the more leading bytes match. By measuring time over many attempts, an attacker learns the secret one position at a time.

What is the fix?

Compare the whole value in a single operation that takes the same time regardless of where a difference occurs, such as hmac.compare_digest in Python.

Does it only matter in software?

No. The MITRE description covers hardware designers too, and the router example CVE-2014-0984 is a device password check.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.