CWE-187, Partial String Comparison, is a comparison that looks at only part of a value, such as a substring, before deciding there is a match. Authentication, path checks, certificate checks and command parsers are the places it bites.
How it happens
A developer wants to compare two strings and picks a function that checks a prefix, or a function that stops after the length of one operand. The check passes on a short or related value.
MITRE's extended description gives the clearest picture: an attacker might authenticate by supplying a small password that matches the associated portion of the larger, correct password.
The record's examples cover several shapes:
- CVE-2002-1374: a one character password checked only against the first character of the real password.
- CVE-2014-6394: access to restricted directories was not prevented because of a partial string comparison with a public directory.
- CVE-2004-0765: a web browser checked only the hostname portion of a certificate when the hostname in the URI was not a fully qualified domain name, which let attackers spoof trusted certificates.
- CVE-2004-1012: an IMAP server's argument parser treated the partial command "body[p" as "body.peek", causing an index error and out of bounds corruption.
# Vulnerable: prefix test lets /srv/public-secrets through
def allowed(path):
return path.startswith("/srv/public")
# Fixed: compare whole path components
import os
def allowed(path):
real = os.path.realpath(path)
return os.path.commonpath([real, "/srv/public"]) == "/srv/public"
What an attacker gains
MITRE lists integrity and access control impacts: altering execution logic and bypassing a protection mechanism.
How to find it
No detection methods are listed. Review comparisons that use prefix, substring or length limited functions in security decisions, such as startswith, strncmp, or comparing only up to the shorter length. Test with short inputs, empty inputs and values that merely begin with a trusted value.
How to fix it
General steps, since the record lists none.
- Compare complete values. Check lengths as well as content.
- For paths, compare resolved components, not text prefixes.
- For secrets, use a constant time comparison function from your language's library.
- For certificates, validate the full chain and the full hostname.
Quick check
Why does startswith fail for directory checks?
A name like public-secrets starts with public. The text matches, but it is a different directory.