1587
high computing overhead. Finally, since computing power gets faster and cheaper over time, the
technique can be reconfigured to increase the workload without forcing an entire replacement
of the algorithm in use. Some hash functions that have one or more of these desired properties
include bcrypt [REF-291], scrypt [REF-292], and PBKDF2 [REF-293]. While there is active
debate about which of these is the most effective, they are all stronger than using salts with
hash functions with very little computing overhead. Note that using these functions can have an
impact on performance, so they require special consideration to avoid denial-of-service attacks.
However, their configurability provides finer control over how much CPU and memory is used, so
it could be adjusted to suit the environment's needs.
Effectiveness = High
Phase: Architecture and Design
If a technique that requires extra computational effort can not be implemented, then for each
password that is processed, generate a new random salt using a strong random number
generator with unpredictable seeds. Add the salt to the plaintext password before hashing it.
When storing the hash, also store the salt. Do not use the same salt for every password.
Effectiveness = Limited
Be aware that salts will not reduce the workload of a targeted attack against an individual hash
(such as the password for a critical person), and in general they are less effective than other
hashing techniques such as increasing the computation time or memory overhead. Without a
built-in workload, modern attacks can compute large numbers of hashes, or even exhaust the
entire space of all possible passwords, within a very short amount of time, using massivelyparallel
computing and GPU, ASIC, or FPGA hardware.
Phase: Implementation
Phase: Architecture and Design
When using industry-approved techniques, use them correctly. Don't cut corners by skipping
resource-intensive steps (CWE-325). These steps are often essential for preventing common
attacks.
Demonstrative Examples
Example 1:
In both of these examples, a user is logged in if their given password matches a stored password:
Example Language: C (Bad)
unsigned char *check_passwd(char *plaintext) {
ctext = simple_digest("sha1",plaintext,strlen(plaintext), ... );
//Login if hash matches stored hash
if (equal(ctext, secret_password())) {
login_user();
}
}
Example Language: Java (Bad)
String plainText = new String(plainTextIn);
MessageDigest encer = MessageDigest.getInstance("SHA");
encer.update(plainTextIn);
byte[] digest = password.digest();
//Login if hash matches stored hash
if (equal(digest,secret_password())) {
login_user();
}
This code relies exclusively on a password mechanism (CWE-309) using only one factor of
authentication (CWE-308). If an attacker can steal or guess a user's password, they are given full
CWE Version 4.14
CWE-759: Use of a One-Way Hash without a Salt
CWE-759: Use of a One-Way Hash without a Salt