Don't share your SECRETS!
Why you shouldn't commit secrets into code repositories (even private ones)
From personal projects to enterprise grade source code, leaked secrets such as API Keys, OAuth tokens, certificates, and credentials, despite being sensitive pieces of data, are all too often committed to repositories.
For many of us, git is how we are able to collaborate and share our code when working on it with others, so why shouldn't you share secrets in there too? Git seems like the perfect place to store secrets so that every collaborator can have access to them and ensure they're accurate and up to date. However, that is not the case.
I'll cover some methods that we can use to make sure our secrets don't end up in source code repositories and better alternatives to sharing secrets, but first...
Why we shouldn't put secrets in git in the first place
Code can be copied. Code can be shared. Git makes it even easier to do that, even promoting open code. Every time you clone, fork, or distribute a repository, it not only shares the current code that is in the repository, but all the change history that's happened as well. Essentially, once you put a secret into git, its in there forever.
Now you're probably thinking, "what about private repositories?" Even private repositories aren't safe for secrets. Just like public repositories, anyone can clone, fork, or copy that repository, they just need to be given access. Once someone has your code with your secrets, it's really out of your control what they can do with it.
Once it's there, it's there forever
One thing I really need to emphasize is that once a secret reaches git, it is in that git repository forever. Even if you push a change to remove a secret, all someone would need to do is go through your commit history and find the commit that removed the secret.
Searching "removed api key" in GitHub returns nearly 1 million results containing commits where someone is trying to remove their API key from their git repository.
Looking at one of the commits, you can see that even though their change removed the API key from their current repository. Just by finding the change they made, you can see the API key in plain text.
What can you do?
My go to option to unsure that my secrets stay secret is to use both a .env file and a .gitignore file. Practically every language supports the use of .env files and .gitignore files are native to git, so there's really no reason you aren't able to use both.
.env - Short for environment, the .env file is a configuration file that allows you to have a centralized location for settings or configuration variables for your program. This is a great location to store your secrets.
.gitignore - Pronounced git - ignore, the .gitignore file is a configuration file that tells git what files it should not track and commit to the git repository, AKA ignore.
With the .env file, you're able to store any secrets and easily reference them in your code. For example, you're .env file may look something like this:
API_KEY=your_api_key
DATABASE_URL=your_database_url
DEBUG=true
USERNAME=your_username
PASSWORD=your_password
Essentially, you can treat the .env file as a dictionary data structure, when you reference the value on the left of the equals sign (=) it returns the value on the right. This file never gets committed and is usually replaced with a .env.example file which contains all the values on the left, but not the right. Preventing the .env file from being committed is where the .gitignore file comes into play.
As mentioned earlier, the .gitignore file lists what files and file paths should not be committed to git, allowing git to automatically ignore those files. For example, your .gitignore file may look like this:
# Dependency directories
lib/
vendor/
# Environment files
.env
# IDE files
.vscode/
.idea/
# OS-specific files
Thumbs.db
.DS_Store
In this case, we specify that the .env file should not be committed along with some other files and file paths that we don't want in our git repository.
Conclusion
In conclusion, please be mindful of what you share in git. You've seen how easy it is for someone to go through git history and find previously stored API keys. Once something is in git, it really is easy to find it, no matter how many revisions you make to try and hide it. Attackers always have the advantage and are always on the lookout for their next easy victim, please don't be one of them.