secret-management-best-practices

23 May 2024

Leveraging our extensive Cloud security expertise, we have compiled a collection of valuable articles on crucial security best practices across various topics. In today's article, we will present five best practices for effectively managing your secrets.

What are the challenges related to human and machine secrets?

It is crucial to distinguish between human secrets and machine secrets. Human secrets refer to passwords used by humans. Humans tend to choose short, easy-to-remember passwords that can potentially be predictable, making them vulnerable to dictionary attacks or brute force attacks.

On the other hand, machine secrets are keys used by servers. They are randomly generated, long, and complex.

Therefore, it's essential to understand that these two types of secrets should not be treated the same way as they pose different security challenges.

Human secrets (passwords) typically involve enforcing strong password policies and educating users on best practices for creating and protecting their passwords.

For machine secrets (server keys), you should focus on regular key rotation, secure storage practices, and access controls to limit exposure to unauthorized users.

This article discusses the lifecycle of these two types of secrets, from their generation to expiration. It will also address the risks associated with secret leakage. A previous article covers best practices for authentication and for defining rights and accesses in IAM.

How do I manage my secrets securely?

In short, you should use unique, non-shared, temporary credentials to access your services. These credentials should be stored in a dedicated system. You should enforce a strong password policy and use a password manager regarding your users' passwords.

Here are more details on each best practice.

My Services Are Accessible Through Unique Credentials

Our Recommendation: We suggest generating a different secret for each specific use, whether the credentials used by humans to access a resource or those used by a “machine” to connect to a service.

Risk addressed by this recommendation:

Reusing secrets is an issue often encountered in projects. This happens when the same secret is used for authentication across different environments or applications or by multiple users. If one secret leaks, it jeopardizes all the environments or applications using it. This means a single security incident can compromise the entire system.

Additionally, if your secret leaks and corrective measures need to be taken, you'll have to identify all the uses of that secret to invalidate it. This can be extremely time-consuming!

For example, it took us three months to invalidate just two secrets on a project. They were challenging to find because they were used across different applications and environments. They were also stored in password managers, Vault, or even in GitHub secrets.

To make things even more complicated, they were stored in different formats: sometimes in plain text, sometimes in base64. This makes it difficult to locate and invalidate them! Using unique secrets avoids this painful work when a secret needs to be invalidated.

My Services Are Accessible Through Non-shared Credentials

Our Recommendation: We strongly recommend not sharing credentials used to connect to resources between humans. To help users avoid sharing passwords, you can use Boundary. This open-source tool provides a way to access systems based on user identity.

Risk addressed by this recommendation:

In some cases, users tend to share passwords, for example, to access databases for which identity-based control access is not always manageable. This practice raises some of the following security risks:

  • Privilege escalation: If different users use the same password, it will probably not follow the principle of least privileges. This means that access is too wide for each user. For example, a group of developers and administrators sharing admin access to a database is dangerous, as any user can potentially delete some data.
  • Password leakage: Passwords can be shared in clear text between users and not through a secure channel. Therefore, the risk of having credentials leak is more important. Furthermore, as explained above, these shared credentials are often highly privileged.

My Services Are Accessible Through Temporary Credentials

Our Recommendation:

  • Use password rotation tools like Vault for both human and machine secrets. These tools can generate short-term secrets and automatically update them at regular intervals. This ensures that secrets are changed regularly while avoiding reusing predictable patterns.
  • Use cloud IAM roles that allow temporary and specific privileges to be assigned to applications, reducing the validity period of secrets. The article on IAM best practices provides more details on IAM role management.

Risk addressed by this recommendation:

For human secrets, the risk of not using tools for password rotation is that your users might use predictable secrets.

The traditional approach to addressing this problem with human secrets is to encourage regular password rotation, requiring individuals to change them frequently. However, be cautious, as this practice can backfire. Instead of having a strong and unique password, people tend to use predictable patterns when forced to change their passwords regularly.

For instance, it's very common to observe passwords like "January2023!" in companies that require password changes every 3 months. This significantly reduces the effectiveness of password rotation.

Therefore, these best practices will help you to prevent password breaches.

My Secrets Are Stored in a Dedicated Service

Our Recommendation: Instead of using secrets in plain code, we recommend injecting them at runtime as environment variables. You should store them in dedicated services for this purpose: GitHub Secrets for GitHub or secrets managers in Cloud providers. Ideally, you should have a centralized service to list all uses of the same secret. For this, you can use tools like Vault or ArgoCD.

Risk addressed by this recommendation:

Secrets in plain code are vulnerable to leaks or compromise. If a secret leaks and is stored in several services, it is difficult to locate and invalidate it.

Note: If you notice a secret has been published in the code of one of your repositories, simply erasing it from the code won't solve the problem. The secret has already leaked, so the risk exists. Furthermore, even if you remove it from the code, it will still be in your repository's history! Therefore, remember to invalidate it.

I Have a Strong Password Policy Enforced

A problem with passwords chosen by humans is that they are often weak because they need to be memorable. Defining a password policy to compel strong passwords is essential, but it should not be too demanding for your users.

We can't reasonably ask people to choose passwords that are both very long and very complex because they won't be able to remember them. So, what should be the preferred password policy: long or complex passwords?

Our Recommendation: We recommend using a password policy that requires your users to have long passwords, a minimum of 12 characters. It adds some complexity without making it too demanding: requiring an uppercase letter, a number, and a unique character is reasonable. It's also a good idea to prohibit the use of certain basic passwords, like "Password1!" by using a blacklist.

Risk addressed by this recommendation: Let's examine some concepts to clarify the recommendation: Why is the length of a password more important than its complexity? First, let’s define what a hash is.

The password hash is a cryptographic digest, meaning it's a representation obtained from the password. It's easy to calculate but mathematically impossible to reverse-engineer the password from the hash.

reverse-function

Hashes of passwords are often stored in databases rather than the actual passwords. This is a good practice because if the database is breached, theoretically, retrieving the passwords from the hashes is impossible.

database-hash

There are two types of attacks to find a password: online attacks and offline attacks.

In an online attack, an attacker tries passwords individually on a login page. In this case, the attacker is limited in their attempts because if the login page is well-secured, they can't try many passwords before getting locked out of the system.

In an offline attack, the attacker has obtained the hash of a password, for example, during a database leak. As seen before, they can't directly calculate the password from the hash.

However, they can find it through a brute-force method. A hash is deterministic, meaning you'll always get the same result if you calculate the hash of the same password.

To find the password, an attacker can calculate the hash of all possible passwords on their machine (offline) until they match the hash they obtained. They then know they've found the password. This attack has no limit on the number of attempts except for the attacker's computing power, making it more dangerous!

leaked-hashes

For example, in the image above, an attacker has obtained a hash and wants to find the associated password. They calculate the hash for all combinations of letters, numbers, and special characters with 8 characters.

Eventually, they find a hash that matches the one they obtained. They now know the password is "M2y3!q?3"!

In the case of an offline attack, the shorter the password, the quicker it can be discovered. For instance, for Windows password hashes, it's possible to calculate the hashes of all 8-character passwords in just 24 hours, but if you increase it to 12 characters, it will take about a year! Therefore, a password must be extended to be secure.

Of course, a simply long password isn't enough. It’s obvious that "secretsecret" or “Password123!” aren’t good passwords, even if they are 12 characters long. An attacker could find them using a dictionary attack, which involves using a list of common or predictable words.

So, you need to enforce the use of long passwords that aren’t too predictable. You don't need to make them overly complex with lots of random numbers and special characters, as that would make them hard to remember. You need to add some complexity to make it memorable while not being too easy to guess and to blacklist the use of common passwords.

My Employees Share a Common Password Manager

Our Recommendation: We recommend using a password manager to allow your employees to manage their many passwords and maintain the imposed password policy. A unified password manager within your company also enables the secure sharing of secrets among your users. For example, Dashlane or Bitwarden offer this feature.

Risk addressed by this recommendation:

Given the large number of services used in a company, if you don't provide a password manager to your employees, they may end up reusing the same password multiple times or using personal passwords used on services external to your company. This could lead to the compromise of your infrastructure due to a breach of an external service.

Moreover, while it's not recommended to share secrets, there may be instances where secrets need to be shared. For example, to initialize a service that requires an initial configuration token that needs to be shared.

In such cases, it's important to share a secret securely. Using a common password manager has its advantages in this regard. It protects you from password leaks during these exchanges.

Conclusion

Efficient secret management is essential to enhance the security of your infrastructure. By following the best practices presented in this article, you can significantly reduce the risk of compromise and improve the overall security of your infrastructure.