rspec/rules/S5344/java/rule.adoc

102 lines
5.1 KiB
Plaintext
Raw Normal View History

The improper storage of passwords poses a significant security risk to software applications. This vulnerability arises when passwords are stored in plain-text or with a fast hashing algorithm. To exploit this vulnerability, an attacker typically requires access to the stored passwords.
== Why is this an issue?
Attackers who would get access to the stored passwords could reuse them without further attacks or with little additional effort. Obtaining the clear-text passwords, they could then gain unauthorized access to user accounts, potentially leading to various malicious activities.
=== What is the potential impact?
Plain-text or weakly hashed password storage poses a significant security risk to software applications.
==== Unauthorized Access
When passwords are stored in plain-text or with weak hashing algorithms, an attacker who gains access to the password database can easily retrieve and use the passwords to gain unauthorized access to user accounts. This can lead to various malicious activities, such as unauthorized data access, identity theft, or even financial fraud.
==== Credential Reuse
Many users tend to reuse passwords across multiple platforms. If an attacker obtains plain-text or weakly hashed passwords, they can potentially use these credentials to gain unauthorized access to other accounts held by the same user. This can have far-reaching consequences, as sensitive personal information or critical systems may be compromised.
==== Regulatory Compliance
Many industries and jurisdictions have specific regulations and standards to protect user data and ensure its confidentiality. Storing passwords in plain-text or with weak hashing algorithms can lead to non-compliance with these regulations, potentially resulting in legal consequences, financial penalties, and damage to the reputation of the software application and its developers.
== How to fix it in Spring
A user password should never be stored in clear text. Instead, a hash should be produced from it using a secure algorithm:
* not vulnerable to brute force attacks.
* not vulnerable to first preimage or second preimage attacks: If a hash is leaked, it should be difficut to find a password produding this same hash. It should also be difficult to find a password that has the same hash than another password.
* and a salt should be added to the password to lower the risk of rainbow table attacks (see rule S2053).
While considered strong for some use cases, some algorithms, like SHA-family functions, are too fast to compute and therefore susceptible to brute force attacks, especially with attack-dedicated hardware. Modern, slow, password hashing algorithms such as bcrypt, PBKDF2 or argon2 are recommended.
=== Code examples
2021-02-23 01:11:03 +00:00
==== Noncompliant code example
2021-02-23 01:11:03 +00:00
The following code is vulnerable because it uses a legacy digest-based password encoding that is not considered secure.
[source,java,diff-id=1,diff-type=noncompliant]
2021-02-23 01:11:03 +00:00
----
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth, DataSource dataSource) throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource)
.usersByUsernameQuery("SELECT * FROM users WHERE username = ?")
.passwordEncoder(new StandardPasswordEncoder()); // Noncompliant
}
----
==== Compliant solution
2021-02-23 01:11:03 +00:00
[source,java,diff-id=1,diff-type=compliant]
2021-02-23 01:11:03 +00:00
----
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth, DataSource dataSource) throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource)
.usersByUsernameQuery("Select * from users where username=?")
.passwordEncoder(new BCryptPasswordEncoder());
}
----
=== How does this work?
The ``BCryptPasswordEncoder`` is a password hashing function in Java that is designed to be secure and resistant to various types of attacks, including brute-force and rainbow table attacks. It is slow, adaptative, and automatically implements a salt.
== Resources
=== Documentation
* Spring Framework Security Documentation - https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/crypto/bcrypt/BCryptPasswordEncoder.html[Class BCryptPasswordEncoder]
* https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html[OWASP CheatSheet] - Password Storage Cheat Sheet
=== Standards
* https://owasp.org/Top10/A02_2021-Cryptographic_Failures/[OWASP Top 10 2021 Category A2] - Cryptographic Failures
* https://owasp.org/Top10/A04_2021-Insecure_Design/[OWASP Top 10 2021 Category A4] - Insecure Design
* https://owasp.org/www-project-top-ten/2017/A3_2017-Sensitive_Data_Exposure[OWASP Top 10 2017 Category A3] - Sensitive Data Exposure
* https://cwe.mitre.org/data/definitions/256[MITRE, CWE-256] - Plaintext Storage of a Password
* https://cwe.mitre.org/data/definitions/916[MITRE, CWE-916] - Use of Password Hash With Insufficient Computational Effort
* https://www.sans.org/top25-software-errors/#cat3[SANS Top 25] - Porous Defenses
ifdef::env-github,rspecator-view[]
'''
== Implementation Specification
(visible only on this page)
=== Message
Use a secure password hashing algorithm.
'''
== Comments And Links
(visible only on this page)
include::../comments-and-links.adoc[]
endif::env-github,rspecator-view[]