You already know it by now, at GitGuardian our passion is to detect secrets wherever they appear. We observe many of them, all the time. Since I started writing this, we have detected 468 new secrets on the public GitHub scope that we continuously monitor, and are still counting.
But not all secret leaks are created equal. Some are very common. This OpenWeatherMap API you just leaked is nothing to worry about. But others are a bit more strange and obscure. They rise from the very darker depths of the open internet to challenge the limits of your imagination.
Today, for this spooky season, we want to introduce you to some of those terrifying leaks. Before you ask, yes, they are real-world case studies and nothing we took from a horror movie. The horror is already here, on Github, and many more data sources.
Now let us open the book of those forbidden leaks: the Necronoleakon!
The doomed key
If you have read our recent post, you know Docker images’ layers can contain secrets. Sometimes, those secrets are worse than the average.
This Docker file for example:
FROM debian:latest
ARG NODE_VERSION=16.11.1
# prepare .ssh dir
RUN mkdir -p /root/.ssh/
COPY id_rsa /root/.ssh/id_rsa
It is clear it copies an authentication secret to the image. Would it then be pushed to a public registry, it would leak the key. But that's a very well-known story no one is afraid of anymore, or are you?
Can you imagine a worse situation? Can you imagine a leak that would be so ugly and unbelievable that it would question everything you thought was true about code security? Brace yourselves and fear the doomed plain copied key!
Don’t try to understand why this happens. Normal mortal minds can’t grasp the dark intricacies of forbidden leaks. All we can say is this key is then used to clone a private repository. 🙈
The one hiding in plain light
This is a classical horror story, the one children tell each other around a campfire at night. Let me introduce it to you.
Once upon a time in a very new git repository.
$ ls
main.py README.md requirements.txt
$ git add .
$ git commit -m "Initial commit" && git push
Does this look right to you? Would you fall into this horrible trap and forever live in regrets? Well, a lot of people do.
Look at this initial commit. Why would it contain 21 000 changed files? This user must have gone insane. The actual reason is much more frightening.
You see it right. The commit embeds a ton of hidden files that git add . has sneaked into the commit. And for sure, this hosts a whole army of terrible secrets.
$ cat .bash_history
[...]
ls
helm ls --all-namespaces
ls
git clone <https://a******t:ghp_Q**********************************Z@github.com/REDACTED.git>
git clone <https://a******t:ghp_Q**********************************Z@github.com/REDACTED.git>
ls
[...]
Please, reader, remember not to summon the cursed git add .
. 👹
The one hiding in the dark
Docker images are sometimes not obvious to everyone. The way they organize into layers that all contribute to the final image is obscure to some people. As obscure as the secrets they end up leaking.
Let’s inspect a nice-looking Docker image.
$ docker run -it c******/******-production /bin/bash
bash-5.1$ ls -la
total 2044
drwxr-xr-x 1 node node 4096 Apr 23 2024 .
drwxr-xr-x 1 root root 4096 Feb 21 2022 ..
-rwxrwxrwx 1 node node 35019 Apr 23 2024 LICENSE.md
drwxr-xr-x 1 node node 4096 Apr 23 2024 node_modules
-rwxrwxrwx 1 node node 2016779 Apr 23 2024 package-lock.json
-rwxrwxrwx 1 node node 9784 Apr 23 2024 package.json
-rwxrwxrwx 1 node node 2601 Apr 23 2024 plugins.json
drwxr-xr-x 5 node node 4096 Apr 23 2024 public
drwxr-xr-x 2 node node 4096 Apr 23 2024 src
Everything looks right here, no skeleton in the closet. Or is there? The image history might give you some shivers.
$ docker history -H --no-trunc c******/******-production
[...]
<missing> 6 months ago /bin/bash -o pipefail -o errexit -u -c rm -f .npmrc || : 0B
<missing> 6 months ago /bin/bash -o pipefail -o errexit -u -c npm ci --only=prod --ignore-scripts 330MB
<missing> 6 months ago /bin/bash -o pipefail -o errexit -u -c #(nop) COPY --chown=node:nodedir:9d[...] in ./src 12.1kB
<missing> 6 months ago /bin/bash -o pipefail -o errexit -u -c #(nop) COPY --chown=node:nodemulti:3d[...] in ./ 2.05MB
<missing> 6 months ago /bin/bash -o pipefail -o errexit -u -c #(nop) COPY --chown=node:nodefile:4d[...] in ./ 9.78kB
rm -f npmrc
? There was a secret in there at build time. Frightening. But it’s gone now, right? What if we explored the inside of the image?
$ docker save c******/******-production -o img.tar
$ tar f img.tar --list
blobs/
blobs/sha256/
blobs/sha256/15[...]
[...]
blobs/sha256/ff[...]
index.json
manifest.json
oci-layout
repositories
All the layers can be listed. And by reading the right one
$ tar xf a8a4395e5fa4849798da6439b53e2376c230b7f123d8508b3fd449c581fc53af -O usr/local/src/app/.npmrc
//npm.pkg.github.com/:_authToken=ghp_6e******
******:registry = <https://npm.pkg.github.com/>
always-auth=true
lockfile-version=2
Like a zombie, this secret was killed but raised again. It will come back to haunt you! 🧟
What is this? A leak !?
Have you ever had this nightmare where you arrive at work or school and suddenly notice you are bare-naked? Well, this is not just a nightmare for everyone. Look at this commit on GitHub:
This looks like a perfectly sane commit without any sensitive data. This is the commit you could blindly trust. But what if I told you there is a critical secret lurking in there? One that can only be seen if you look in the hidden parts of this commit: its metadata.
$ curl https://api.github.com/repos/m******/s******/commits/fe11116eabd916d818c7f1cb07d0f08eccc761cb
{
"sha": "fe11116eabd916d818c7f1cb07d0f08eccc761cb",
"node_id": "allworkandnoplaymakesjackadullboy",
"commit": {
"author": {
"name": "******",
"email": "3lGzQ/JdFkdyb!",
"date": "2024-01-01T06:66:66Z"
},
"committer": {
"name": "******",
"email": "3lGzQ/JdFkdyb!",
"date": "2024-01-01T06:66:66Z"
},
[...]
}
Does this e-mail address look unusual? That’s only because it’s not an e-mail. It’s a password—the password of the Github account that pushed this commit.
No need to say this password was valid. 😱
The aftermath
Are you scared? Are you breaking out in cold sweat after seeing those terrible forbidden leaks? Well, you should be.
But remember! You don’t have to live the nightmare! GitGuardian can help you protect against those bad leaks. All it takes is a few steps to get GitGuardian deployed to your repositories. You can also follow our blog for good practice advice and recommendations.
Watch your back! There might be an ugly secret lurking.