Introduction
In the previous article, we explored how to monitor GitHub Gists for leaked secrets. In this article, we’ll implement a similar system, but with a focus on GitLab Snippets. We’ll configure TruffleHog to detect sensitive information, such as API keys and passwords, that might have been inadvertently exposed in public Snippets.
Table of contents
Open Table of contents
Snippets
GitLab Snippets are a feature in GitLab that allows users to share small pieces of code, configuration files, or any other text content. Similar to GitHub Gists, GitLab Snippets are a lightweight way to share code or text with others, whether for collaboration, documentation, or quick sharing.
Snippets API
The GitLab Snippets API allows developers to programmatically interact with GitLab Snippets, enabling the creation, retrieval, updating, and deletion of snippets through HTTP requests. With the API, users can automate the management of both personal and project snippets, access specific snippet content, and integrate snippet operations into their applications or workflows. The snippets API documentation can be found here. Similar to Github Gists you will need to create an access token.
TruffleHog
TruffleHog, developed by Truffle Security, is a powerful security tool designed to detect and prevent the leakage of sensitive information in code repositories. By scanning the entire commit history of Git repositories, TruffleHog identifies secrets such as API keys, passwords, and other confidential data using entropy analysis and regex matching. It integrates seamlessly into CI/CD pipelines, helping developers catch and eliminate potential security risks before they are pushed to production. Ideal for security audits and incident response, TruffleHog is an essential tool for safeguarding codebases against inadvertent exposure of sensitive credentials.
Monitoring script
We’ll create a simple shell script that queries the public Snippets API, retrieves each repository URL, and scans them with TruffleHog. This script is similar to the one used for monitoring Gists. First, we’ll define variables for file names, API tokens, and other essential configurations.
SNIPPETS_DOWNLOADED=downloaded-snippets.tmp
SNIPPETS_URLS=snippets-urls.tmp
PREV_SNIPPETS_URLS=downloaded-snippets-urls.log
NUM=100
TRUFFLE_LOG="trufflehog.log"
SNIPPETS_LOG="snippets.log"
TIMESTAMP=""
TOKEN="glpat-XXXXXXXXXXXXXXXXXXXX"
Next, we’ll continuously query the Snippets API in an infinite loop to extract the Git pull URL for each Snippet. These URLs will be stored in a sorted text file, with duplicates removed:
while true; do
url="https://gitlab.com/api/v4/snippets/public?per_page=$NUM&created_after=$TIMESTAMP"
echo "URL: $url"
curl -L \
-H "PRIVATE-TOKEN: $TOKEN" \
-s \
-o $SNIPPETS_DOWNLOADED $url
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
cat $SNIPPETS_DOWNLOADED >> $SNIPPETS_LOG
cat $SNIPPETS_DOWNLOADED | jq -r '.[].http_url_to_repo' | sort -u > $SNIPPETS_URLS
echo "Downloaded $(wc -l $SNIPPETS_URLS)"
cat $SNIPPETS_URLS >> $PREV_SNIPPETS_URLS
sort -o $PREV_SNIPPETS_URLS -u $PREV_SNIPPETS_URLS
rm $SNIPPETS_URLS
rm $SNIPPETS_DOWNLOADED
echo "[*] All snippets done, sleeping..."
echo
sleep 900
done
The final step is to run TruffleHog on each repository URL:
for snippet in $(cat $SNIPPETS_URLS); do
if [[ $(grep -c "$snippet" $PREV_SNIPPETS_URLS) -eq 0 ]]; then
echo "[+] Snippet: ${snippet}"
trufflehog git --no-update --concurrency=3 -j $snippet --only-verified | tee -a $TRUFFLE_LOG
fi
done
TruffleHog will download the Git repository and scan it for secrets. All detected secrets will be verified and logged to a file.
The complete script can be found below:
#!/bin/bash
SNIPPETS_DOWNLOADED=downloaded-snippets.tmp
SNIPPETS_URLS=snippets-urls.tmp
PREV_SNIPPETS_URLS=downloaded-snippets-urls.log
NUM=100
TRUFFLE_LOG="trufflehog.log"
SNIPPETS_LOG="snippets.log"
TIMESTAMP=""
TOKEN="glpat-XXXXXXXXXXXXXXXXXXXX"
while true; do
url="https://gitlab.com/api/v4/snippets/public?per_page=$NUM&created_after=$TIMESTAMP"
echo "URL: $url"
curl -L \
-H "PRIVATE-TOKEN: $TOKEN" \
-s \
-o $SNIPPETS_DOWNLOADED $url
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
cat $SNIPPETS_DOWNLOADED >> $SNIPPETS_LOG
cat $SNIPPETS_DOWNLOADED | jq -r '.[].http_url_to_repo' | sort -u > $SNIPPETS_URLS
echo "Downloaded $(wc -l $SNIPPETS_URLS)"
for snippet in $(cat $SNIPPETS_URLS); do
if [[ $(grep -c "$snippet" $PREV_SNIPPETS_URLS) -eq 0 ]]; then
echo "[+] Snippet: ${snippet}"
trufflehog git --no-update --concurrency=3 -j $snippet --only-verified | tee -a $TRUFFLE_LOG
fi
done
cat $SNIPPETS_URLS >> $PREV_SNIPPETS_URLS
sort -o $PREV_SNIPPETS_URLS -u $PREV_SNIPPETS_URLS
rm $SNIPPETS_URLS
rm $SNIPPETS_DOWNLOADED
echo "[*] All snippets done, sleeping..."
echo
sleep 900
done
Displaying results
TruffleHog saves its results in JSON format. To format the output and extract the most important information, you can use the jq
command. An example of how to do this is provided below:
cat trufflehog.log | jq 'select(.Verified == true) | {DetectorName: .DetectorName, verified: .Verified, Raw: .Raw, RawV2: .RawV2, email: .SourceMetadata.Data.Git.email, repo: .SourceMetadata.Data.Git.repository}'
Conclusion
Utilizing TruffleHog allows you to automate the detection of sensitive information, such as API keys and passwords, that might have been unintentionally exposed in public Snippets.