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.