I love learning new things, especially in a tool I’ve used for a long time. In this case, that tool is Git. If you’re not familiar with it, Git is a source code versioning system typically used by developers to keep track of their codebase.
This is NOT a tutorial on Git, though; instead, we’ll take a quick look at how you can reverse one of the seven worst horrors known to humankind: accidentally committing an API key to your code repository.
I’ve actually used this type of technique on penetration tests, and it’s a decently bad thing. You absolutely do not want API keys stored in a public repository system like GitHub. It goes like this: You prowl around github.com searching for committed API strings–especially to things like AWS or Azure–and you will always find them, always.
Fortunately, this common mistake is reversible, which is something I just learned how to do this week after years of using Git. In fact, I learned three things yesterday, which is a lot, so I went home early. Anyway, on with our show.
Our Oops! Scenario
One of our developers–not me, not this time–accidentally committed an API key to our internal Git repository (no external exposure).
Now, the problem here is I couldn’t simply regenerate the API key because it also happened to be our license key for this specific API–which is another problem, but not one I’ll dwell on here. So, we needed to remove it.
Enter, after some Googling, git-filter-branch. There are a ton of warnings there, and they should be read before you use this method–which is likely why I had never heard of it before, because I always obey all the rules. Important safety tip, make sure to rebase or restart your original local repository because you won’t be able to merge it after this. This, fortunately, is a small project, so we had no such concerns.
Here are the commands that were run with some things removed to protect the innocent code:
$ mkdir repo_cleanup $ cd repo_cleanup $ git clone https://github.com/YOUR-USERNAME/YOUR-REPOSITORY . $ git filter-branch --force --index-filter \ "git rm --cached --ignore-unmatch key.txt" \ --prune-empty --tag-name-filter cat -- --all $ echo "key.txt" >> .gitignore $ git add .gitignore $ git commit -m "Add key.txt to .gitignore" $ git push origin --force --all $ git push origin --force --tags
Basically, that is nine or so commands that say to Git, “Hey, you see the stuff in key.txt here? Yeah, nuke it from orbit wherever you find it.”
- Make a new directory
- Change into that directory
- Clone your repository locally
- Introduce filter-branch magic that removes the naughty information (key.txt in our case)
- Make sure you add key.txt to your .gitignore file
- Commit your changes
- Push your code (with the --force option) to your central repository
- Enjoy your new keyless life
***I have to stress that this is ABSOLUTELY A LAST RESORT. Please don’t use it without considering all the consequences.***
Hopefully, this undiscovered–by me anyway–method that worked really well for us will be helpful when you’re dealing with a similar situation. The best option is to revoke the old key and create a new one; the method I’ve shared here is for when you don’t have that option.
Thank you for coming to my Ted Talk.