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. When dealing with password storage security, best practices recommend relying on a slow hashing algorithm, that will make brute force attacks more difficult. Using a hashing function with adaptable computation and memory complexity also is recommended to be able to increase the security level with time.
	
Adding a salt to the digest computation is also recommended to prevent pre-computed table attacks (see rule S2053).
	
In general, relying on an algorithm with no known weaknesses is also a requirement. This prevents the use of the MD5 or SHA-1 algorithms.

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

==== Noncompliant code example

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]
----
@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

[source,java,diff-id=1,diff-type=compliant]
----
@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

* OWASP - https://owasp.org/Top10/A02_2021-Cryptographic_Failures/[Top 10 2021 Category A2 - Cryptographic Failures]
* OWASP - https://owasp.org/Top10/A04_2021-Insecure_Design/[Top 10 2021 Category A4 - Insecure Design]
* OWASP - https://owasp.org/www-project-top-ten/2017/A3_2017-Sensitive_Data_Exposure[Top 10 2017 Category A3 - Sensitive Data Exposure]
* CWE - https://cwe.mitre.org/data/definitions/256[CWE-256 - Plaintext Storage of a Password]
* CWE - https://cwe.mitre.org/data/definitions/916[CWE-916 - Use of Password Hash With Insufficient Computational Effort]


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[]
