Christoforos Ntantogian, Stefanos Malliaros, and Christos Xenakis from the Department of Digital Systems in the University of Piraeus (Greece) conducted research on password hashing in open-source web platforms including the most popular content management systems (CMS) and web application frameworks. The results published in their paper were very disappointing from the security point of view.
Many popular CMSs use insecure hashing by default. This means that if a criminal manages to get access to the database and download account information, they may relatively easily guess passwords and then perform privilege escalation, sell the passwords, or attempt to use them to compromise more websites (due to users often reusing passwords).
Password Hash Security Considerations
There are several elements that influence how safe the password hashing scheme is. The first element is the hash function. The MD5 function is now considered very insecure: it is easy to reverse with current processing power. The SHA1, SHA256, and SHA512 functions are no longer considered secure, either, and PBKDF2 is considered acceptable. The most secure current hash functions are BCRYPT, SCRYPT, and Argon2.
In addition to the hash function, the scheme should always use a salt. A salt is a random element included during hashing which guarantees that every hash for the same password is different. MD5, SHA1, SHA256, and SHA512 functions do not include a salt and a separate function must be used to add the salt. On the other hand, PBKDF2, BCRYPT, SCRYPT, and Argon2 functions have integrated salts.
The more times the hash function is applied, the more resources it requires to be reversed. MD5, SHA1, SHA256, and SHA512 must be iterated manually while PBKDF2, BCRYPT, SCRYPT, and Argon2 have iteration functionality built-in.
The researchers examined 49 CMSs and 47 web application frameworks for these default settings (hash function, salt, iterations). Additionally, they examined other elements such as password length and complexity requirements.
WordPress Leading the Bad Flock
According to the researchers, WordPress is used for 31.3 percent of websites worldwide (59.8 CMS market share). WordPress (as of version 4.9.1) by default uses the least secure hashing function: MD5. Although the hash is applied with 8192 iterations and with a salt, there is no minimum password length being enforced, so WordPress passwords may be trivial to break.
On the other hand, WordPress’s biggest competitors are safer (but only slightly). Drupal (as of version 8.4.4) uses the insecure SHA512 hash function but applied with 65,536 iterations and a salt. There is no minimum password length. Joomla (as of version 3.8.3) uses a secure BCRYPT hash function with default 1024 iterations, a salt, and a minimum password length of 4 (not long enough).
Among less popular open-source systems there are some very good examples and some very bad ones. One of the top examples is the NodeBB forum system with BCRYPT, 4096 iterations, salt, and a minimum password length of 6. On the other hand, for example, Phorum 5.2.23 uses MD5, no iterations, no salt, and no minimum password length. The entire list of CMSs and frameworks is available in the research paper.
The authors of the paper recommend the use of BCRYPT, SCRYPT, or Argon2 as the default hash functions. BCRYPT and Argon2 are implemented by default in PHP but Argon2 support was added in PHP v7.2 (very recent) and therefore very few solutions use it yet. SCRYPT is not yet implemented in PHP and most CMSs are written in PHP. The PBKDF2(SHA512) function is acceptable with at least 10,000 iterations (as recommended by NIST) and other functions (MD5, SHA1, SHA256, SHA512) are not acceptable as defaults.
At the same time, the authors recommend the default use of a salt, an increased minimum number of iterations, and a minimum password length of 8. For example, PHP uses BCRYPT with 1024 iterations by default but the authors believe it can be increased to 16,384 iterations with no risk of regular login delays.
Denial of Service Risks
All hash functions except MD5 can introduce a Denial of Service (DoS) risk. Even 20 logins per second using BCRYPT with 1024 iterations can cause the server to reach 100% CPU utilization. To protect the CMS against such attacks, rate limiting must be introduced, for example, an hourly lock-out after 3 unsuccessful login attempts for the same account in 30 seconds. There are third-party plugins for many CMSs that offer such functionality, for example, WP Limit Login Attempts for WordPress.
On the other hand, many CMSs introduce a maximum password length because older hash functions (MD5, SHA1, SHA256, SHA512, and PBKDF2) are susceptible to DoS attacks using very long passwords. BCRYPT and SCRYPT are not – the length of the password has next to no effect on hash function processing time. Therefore, CMSs do not need any length limits for passwords.
Protect Your Passwords
Unfortunately, many CMS users do not even realize that the hash function that they use is insecure. If your CMS uses a weak scheme by default, updating your installation will not help. Your best choice is to contact your CMS administrator or someone with programming skills and ask them to search how to change the default hashing scheme. In the case of WordPress it’s as easy as installing a plugin (for example, PHP Native password hash).
When you change your default hash, current passwords are still stored using the old hash. However, when the user logs in, the CMS re-hashes the user password using the new scheme. Therefore, to secure all your user accounts, you must only ask all your users to log in. They do not need to change their passwords, just enter the current one.