Keep passwords out of source code — why and how

Falk Tandetzky
NEW IT Engineering
Published in
5 min readJul 2, 2021
Photo by Ian Tuck on Unsplash

Introduction

A very common security misbehavior I see in my daily work is that credentials are checked into source code control (like git). This is often referred to as hard-coded credentials. This article provides an overview about why this should be avoided and how this can be achieved in different situations. As the solution depends a lot on the situation, I will mostly provide a rough overview about a topic and then provide links to sources where things are explained in depth.

Throughout the article I will use terms like passwords, credentials or secrets interchangeably. The latter two are the broadest terms. They include passwords used by users or technical users, API keys, certificates, ssh keys and really any other data that is secret.

Why not store passwords in source code?

Oftentimes, when code is developed for a company, this company owns this code and keeps it secret. This can lead to the impression, that also credentials can be stored with the code without problems. Probably anyone who is allowed to access the code is also allowed to access the credentials. So why bother?

The issue is, that access to code and who should have access to the credentials often changes over time. Once a project becomes more mature there are usually some developers who do not need to know and hence should not know certain credentials. In addition code may be reused for slightly different purposes or even become open source.

In addition, as the code base grows more complex, it becomes very tedious to identify credentials being buried somewhere in the middle of the code. So at some point people might not even be aware of credentials being distributed with the code. Finally, it can become difficult to find out in which places the same credentials are used, making it difficult to ever change credentials.

I did not find a compiled list of security breaches caused by clear-text passwords, but it seems safe to say that hundreds of millions of users have already been affected by issues caused by hard-coded credentials. Here is an article with some examples.

How to store your passwords

Injecting credentials into a container

There are countless ways to host an application. To have some specific examples in mind, think of AWS, Azure, GCP or Heroku as platforms where you can host a web application.

Oftentimes your web-application needs to access some data source. This may be a database (managed by yourself or someone else) or another API, which may be protected by a password or API-key. Either way, you need to make it possible that your app can somehow prove that it is permitted to access the resource.

As we do not want to put credentials into the source code of the app, the process for this needs two steps.

  1. Credentials need to be provided to your application.
  2. Your application should find the correct credential and use it

Credential provider

Probably the most common approach for providing credentials is to inject them in the environment when starting the service. This can for instance be the operating system environment of a Linux server or of a docker container in which your application is running.

For AWS there are plenty of ways how to do this. Sometimes you can avoid passing credentials explicitly altogether by using instance roles and authorization via IAM. In the case of third party APIs you need to pass the credentials more explicitly. Once again there are several ways. See e.g. AWS: passing credentials to a docker container using AWS Fargate.

To add another example here is how you can inject credentials on Heroku.

A noteworthy trick to manage multiple credentials is to just have one real secret passed to the container by the methods mentioned above and then use this secret to retrieve other secrets. This limits the number of parameters and credentials that need to be passed to the container through above methods while allowing to manage many parameters and secrets in a central place. Examples of tools that help with this approach are

Credential consumer

If your credentials are provided in the environment you can easily access them. However, managing parameters and credentials throughout various environments can become challenging. To simplify this process there are some tools to make accessing the correct credentials in the appropriate environment smoother. Here are some examples for such tools

Build Pipelines:

Any reasonable CI/CD tool provides functionality that allows you to avoid putting credentials in the pipeline definition itself. Instead you configure credentials independent of the pipeline definition. This allows you to access them via special variables in the pipeline definition. Here are some examples

Handling User Passwords on a Server:

A common pattern of how to grant access to an application is to require a user to provide a password. First of all there are sometimes better alternatives to this approach, like single-sign-on or OIDC. Even if this approach is used, user passwords should never be hard coded and usually also not be stored on the server or a database.

A good approach is to not even store the password at all. Instead one should use so-called salt and hashing and only store the hash in a database. Of course make sure access to this DB is as limited as possible.

Here are some articles about how this works

Summary

There are many scenarios where credentials are needed in an application. Putting them directly into source code poses a security risk, as it makes it impossible to provide access to the source code without also providing access to those credentials.

For all steps of implementing an application, deploying it with automation tools and running them on a platform there are mechanisms to handle credentials in a save way.

Pretty much any platform and any build automation tool has its own specifics of how credentials are handled. However, with awareness that credentials need to be treated with care, it is often not difficult to find appropriate documentation.

Further Reading

--

--

Falk Tandetzky
NEW IT Engineering

Software and cloud architect and machine learning engineer at TwoDigits / Accenture. PhD in quantum physics. www.github.com/falktan www.twitter.com/falk_tan