Protecting git Credentials Used in Automated Scripts
Prevent writing git credentials to disk and limit the time stored in memory with git credential.helper cache options
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
⚙️ Part of my series on Automating Cybersecurity Metrics. The Code.
🔒 Related Stories: GitHub Security | Application Security | Secure Code | Ubuntu on AWS
💻 Free Content on Jobs in Cybersecurity | ✉️ Sign up for the Email List
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Related to my posts on application security. I am testing this code on Ubuntu but I presume it will work on any OS.
Free Content on Jobs in Cybersecurity | Sign up for the Email List
I try to avoid storing credentials for any length of time on a system if I can help it. I typically enter user names and passwords to run git commands and don’t store them at all.
Why do I bother with all that? I explained how data you think you may have delete is not truly deleted sometimes here:
Caching credentials in environment variables or even leaving them hanging around in memory can lead to potential compromise. If you can use the credentials during a particular process and immediately remove all trace of the credentials that is best.
However, I was recently revisiting this issue because when you’re cloning a whole bunch of repos at once, this gets old. How can I enter the user name and token once for all repos, and yet avoid having them hang around on disk or in memory afterwards.
This led me to the git credential helper cache information.
git config credential.helper 'cache --timeout=<timeout>'
This sounds great:
This command caches credentials for use by future Git programs. The stored credentials are kept in memory of the cache-daemon process (instead of written to a file) and are forgotten after a configurable timeout. Credentials are forgotten sooner if the cache-daemon dies, for example if the system restarts. The cache is accessible over a Unix domain socket, restricted to the current user by filesystem permissions.
This line is curious…
You probably don’t want to invoke this command directly; it is meant to be used as a credential helper by other parts of Git.
Why? Not sure. I’m going to try using it and see what happens. Because I’m just like that. :-)
This is also helpful — if you want to force the cache to clear:
git credential-cache exit
Here’s the sample code:
$ git config credential.helper cache
$ git push http://example.com/repo.git
Username: <type your username>
Password: <type your password>
[work for 5 more minutes]
$ git push http://example.com/repo.git
[your credentials are used automatically]
Or if you want to set the timeout to an hour:
git config credential.helper 'cache --timeout=3600'
Testing the commands
Well, I can create a script like this to set the credentials, use them, and then exit the cache when the script completes.
That’s fine and dandy. However when I ran it, the script failed.
usage: git config [<options>]
![](https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*v_VOokBFB6D5n0KWtEghvQ.png)
The reason it failed initially was that I forgot to put the single quotes around my options — like this (note the correct version with quotes above).
git config credential.helper cache --timeout=3600
After completing that step, I ran the command and I got this error:
fatal: not in a git directory
What I noticed was that if I ran the git config command without the cache option it ran without errors. I am not sure if it actually did anything.
My problem here is that I want to and set the cache login prior to cloning a git directory. So I’ll never be in a git directory in that scenario. The directory doesn’t exist until after I run the command that apparently requires the directory if I add the cache options.
I’ve got a dilemma now. However, perhaps I just wasn’t running the command correctly.
I figured out that it works when I specify a file location. But the thing is — I don’t want the file. That’s kind of the whole point of what I’m doing. Perhaps the description of “file location” below is kind of a misnomer? Or I guess you could have files in memory? Anyway.
![](https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*RUop_Dc0cRad6G_5lYvphA.png)
You can read more about he above options here:
So are the credentials written to disk with the global option\?
Let’s find out.
I noticed that when I added this option a git config file appeared:
git config --global credential.helper cache
![](https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*hgRXwd2MGeTZD1MDqCZr4g.png)
Let’s add the timeout and see what happens. The config file is updated:
![](https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*2UhZPXv7OJHy4vGJCPJwmA.png)
This looks good. We’ll continue testing this with my script but first…
~~~
Side note: that the fact that 'git config --glob' appears after my prompt and before the command I’m running in the screen shot above (I did not type that there) is due to some kind of bug on AWS EC2 instances.
![](https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*CRaJmH2nimKzBiq0-rkVeA.png)
I reported this in my Bugs That Bite blog.
The fact that this same bug appears in Ubuntu as well as AWS Linux seems to indicate it might be something other than the OS in the AWS environment that causes the problem. I do not have the same problem in a shell on a Mac — but it’s also a different shell (zsh not bash.) So maybe it’s a bash issue. IDK.
🤷🏼♀️
~~~
Back to my script.
I created a script to loop through a series of git repository names. This presumes
#!/bin/bash -e
#replace the following with the path where you want to clone the repos
gitdir='/path/to/clone/dir'
if [ ! -d "$gitdir" ]; then
c="mkdir $gitdir"
($c)
fi
#replace with the owner of the repo
#in my case https://github.com/tradichel, the owner is tradichel
owner='your-repo-owner-name'
#replace the repos below with your repo names
#for this example: https://github.com/tradichel/SecurityMetricsAutomation
#the repo name is SecurityMetricsAutomation
declare -a repos=('repo1' 'repo2' 'repo3')
function sync(){
repo=$1
cd $gitdir
git clone https://github.com/$owner/$repo.git
cd $repo
git remote set-url origin https://github.com/$owner/$repo.git
}
git config --global credential.helper 'cache --timeout 120'
for repo in "${repos[@]}"
do
echo "clone repo $repo"
sync $repo
done
#clear the credentials from cache
git credential-cache exit
#clear anything in bash history
history -c
I ran my script with the correct credentials and I was only prompted for the credentials once. Prior to this change I would be prompted for the credentials for every single repository.
I then searched for the credentials being stored to disk. I didn’t find them. I did not search through memory like I did in my prior post. I’ll leave that as an exercise to the reader for the moment as I have to complete a penetration test. All these things I’m writing about have an immediate purpose as I’m continuously improving the efficiency and security of my work environment.
About the Github CLI
I don’t see a way to do this with the GitHub CLI. There’s a cache option, but it is related to caching API requests.
#githubwishlist
It looks like the CLI does use Credential Manager:
I wonder what would happen if you configure credential manager with caching and then run the command to clear the credential manager cache afterwards. That might work. A test for another day.
Secrets Managers
By the way, I could also pull the secrets from AWS Secrets Manager or similar potentially, but then you have to make sure that is encrypted and locked down so only the appropriate users or processes can access it. And unfortunately, at the time of this writing, there is no way to incorporate MFA into the git clone process with an access token, but you could use AWS IAM to enforce MFA to retrieve the secret using methods I’ve demonstrated in prior posts:
Follow for updates.
Teri Radichel | © 2nd Sight Lab 2023
About Teri Radichel:
~~~~~~~~~~~~~~~~~~~~
⭐️ Author: Cybersecurity Books
⭐️ Presentations: Presentations by Teri Radichel
⭐️ Recognition: SANS Award, AWS Security Hero, IANS Faculty
⭐️ Certifications: SANS ~ GSE 240
⭐️ Education: BA Business, Master of Software Engineering, Master of Infosec
⭐️ Company: Penetration Tests, Assessments, Phone Consulting ~ 2nd Sight Lab
Need Help With Cybersecurity, Cloud, or Application Security?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
🔒 Request a penetration test or security assessment
🔒 Schedule a consulting call
🔒 Cybersecurity Speaker for Presentation
Follow for more stories like this:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
❤️ Sign Up my Medium Email List
❤️ Twitter: @teriradichel
❤️ LinkedIn: https://www.linkedin.com/in/teriradichel
❤️ Mastodon: @teriradichel@infosec.exchange
❤️ Facebook: 2nd Sight Lab
❤️ YouTube: @2ndsightlab
![](https://cdn-images-1.readmedium.com/v2/resize:fit:800/0*H9Ew1KCl-29nZiPR.jpeg)