Skip to content

Commit 8f0b201

Browse files
authored
Improve the gitleaks test coverage (#58015)
Signed-off-by: Matt Moore <mattmoor@chainguard.dev>
1 parent 9a71fe0 commit 8f0b201

File tree

2 files changed

+226
-2
lines changed

2 files changed

+226
-2
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,4 @@ repos:
4343
- id: check-merge-conflict
4444
- id: check-symlinks
4545
- id: detect-private-key
46-
exclude: ^ruby-3\.0/0001-ruby-3\.0\.6-openssl-patch\.patch$
46+
exclude: ^(ruby-3\.0/0001-ruby-3\.0\.6-openssl-patch\.patch|gitleaks\.yaml)$

gitleaks.yaml

Lines changed: 225 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
package:
22
name: gitleaks
33
version: "8.27.2"
4-
epoch: 0
4+
epoch: 1
55
description: SAST tool for detecting and preventing hardcoded secrets like passwords, api keys, and tokens in git repos
66
copyright:
77
- license: MIT
8+
dependencies:
9+
runtime:
10+
- git # Required for scanning git repositories and using protect mode
11+
- openssh-client # Required for git operations over SSH (e.g., git@github.com:... URLs)
812

913
environment:
1014
contents:
@@ -43,8 +47,228 @@ update:
4347
tag-filter: v
4448

4549
test:
50+
environment:
51+
contents:
52+
packages:
53+
- jq # For validating JSON report format
4654
pipeline:
4755
- runs: |
4856
gitleaks version
4957
gitleaks --version
5058
gitleaks --help
59+
- name: Test secret detection in files
60+
runs: |
61+
# Create test directory with sample secrets
62+
mkdir -p test-secrets
63+
cd test-secrets
64+
65+
# Create files with different types of secrets
66+
echo 'aws_access_key_id = AKIAIOSFODNN7EXAMPLE' > aws_config.txt
67+
echo 'private_key = "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEA..."' > private_key.txt
68+
echo 'github_token = ghp_wWPw5k4aXcaajCqbDsLRnJZZzVLgLO0M' > github_secrets.txt
69+
echo 'stripe_key = sk_test_4eC39HqLyjWDarjtT1zdp7dc' > payment.conf
70+
echo 'password = "supersecret123!"' > db_config.yml
71+
72+
# Test directory scanning - gitleaks should find secrets and exit with code 1
73+
gitleaks detect --source . --no-git --exit-code 1 || true
74+
75+
# Verify gitleaks found secrets
76+
OUTPUT=$(gitleaks detect --source . --no-git 2>&1 || true)
77+
if ! echo "$OUTPUT" | grep -q "leaks found"; then
78+
echo "ERROR: Gitleaks should have reported finding leaks"
79+
exit 1
80+
fi
81+
82+
cd ..
83+
rm -rf test-secrets
84+
- name: Test stdin detection
85+
runs: |
86+
# Test secret detection via stdin
87+
echo 'api_key = "sk_live_abcdef123456"' | gitleaks detect --source - --no-git || EXIT_CODE=$?
88+
if [ "$EXIT_CODE" != "1" ]; then
89+
echo "ERROR: Expected gitleaks to detect secret in stdin and exit with code 1"
90+
exit 1
91+
fi
92+
93+
# Test with multiple secrets via stdin
94+
cat << 'EOF' | gitleaks detect --source - --no-git || EXIT_CODE=$?
95+
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
96+
github_token = ghp_wWPw5k4aXcaajCqbDsLRnJZZzVLgLO0M
97+
EOF
98+
if [ "$EXIT_CODE" != "1" ]; then
99+
echo "ERROR: Expected gitleaks to detect secrets in stdin"
100+
exit 1
101+
fi
102+
- name: Test git repository scanning
103+
runs: |
104+
# Create a test git repository with secrets
105+
mkdir -p test-repo
106+
cd test-repo
107+
git init
108+
git config user.email "test@example.com"
109+
git config user.name "Test User"
110+
111+
# Initial commit without secrets
112+
echo "# Test Repository" > README.md
113+
git add README.md
114+
git commit -m "Initial commit"
115+
116+
# Commit with secrets
117+
echo 'slack_webhook = "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX"' > config.json
118+
git add config.json
119+
git commit -m "Add configuration"
120+
121+
# Test git repository scanning
122+
gitleaks detect --exit-code 1 || EXIT_CODE=$?
123+
if [ "$EXIT_CODE" != "1" ]; then
124+
echo "ERROR: Expected gitleaks to find secrets in git history"
125+
exit 1
126+
fi
127+
128+
cd ..
129+
rm -rf test-repo
130+
- name: Test configuration options
131+
runs: |
132+
# Create custom config
133+
cat > test-config.toml << 'EOF'
134+
title = "test config"
135+
136+
[[rules]]
137+
id = "test-rule"
138+
description = "Test rule for API keys"
139+
regex = '''test_api_key\s*=\s*['"]?([A-Za-z0-9]{32})['"]?'''
140+
keywords = ["test_api_key"]
141+
EOF
142+
143+
# Create file with custom secret pattern
144+
echo 'test_api_key = "abcdef1234567890abcdef1234567890"' > test_secret.txt
145+
146+
# Test with custom config
147+
gitleaks detect --source test_secret.txt --config test-config.toml --no-git --exit-code 1 || EXIT_CODE=$?
148+
if [ "$EXIT_CODE" != "1" ]; then
149+
echo "ERROR: Custom rule should have detected the secret"
150+
exit 1
151+
fi
152+
153+
rm -f test-config.toml test_secret.txt
154+
- name: Test report formats
155+
runs: |
156+
# Create test file with known secret that will be detected
157+
echo 'github_token = ghp_wWPw5k4aXcaajCqbDsLRnJZZzVLgLO0M' > test_secret.txt
158+
159+
# Test JSON report
160+
gitleaks detect --source test_secret.txt --no-git --report-format json --report-path report.json --exit-code 1 || true
161+
if [ ! -f report.json ]; then
162+
echo "ERROR: JSON report was not created"
163+
exit 1
164+
fi
165+
166+
# Validate JSON format
167+
if ! jq . report.json > /dev/null 2>&1; then
168+
echo "ERROR: JSON report is not valid JSON"
169+
exit 1
170+
fi
171+
172+
# Verify JSON contains expected fields
173+
if ! jq -e '.[0] | has("Description") and has("File") and has("Secret")' report.json > /dev/null; then
174+
echo "ERROR: JSON report missing expected fields"
175+
exit 1
176+
fi
177+
178+
# Test CSV report
179+
gitleaks detect --source test_secret.txt --no-git --report-format csv --report-path report.csv --exit-code 1 || true
180+
if [ ! -f report.csv ]; then
181+
echo "ERROR: CSV report was not created"
182+
exit 1
183+
fi
184+
185+
# Validate CSV has header and data
186+
LINE_COUNT=$(wc -l < report.csv)
187+
if [ "$LINE_COUNT" -lt 2 ]; then
188+
echo "ERROR: CSV report should have header and at least one data row"
189+
exit 1
190+
fi
191+
192+
# Check CSV header contains expected columns
193+
HEADER=$(head -n1 report.csv)
194+
if ! echo "$HEADER" | grep -q "RuleID"; then
195+
echo "ERROR: CSV header missing RuleID column"
196+
exit 1
197+
fi
198+
if ! echo "$HEADER" | grep -q "Secret"; then
199+
echo "ERROR: CSV header missing Secret column"
200+
exit 1
201+
fi
202+
if ! echo "$HEADER" | grep -q "File"; then
203+
echo "ERROR: CSV header missing File column"
204+
exit 1
205+
fi
206+
207+
# Test SARIF report
208+
gitleaks detect --source test_secret.txt --no-git --report-format sarif --report-path report.sarif --exit-code 1 || true
209+
if [ ! -f report.sarif ]; then
210+
echo "ERROR: SARIF report was not created"
211+
exit 1
212+
fi
213+
214+
# Validate SARIF format
215+
if ! jq . report.sarif > /dev/null 2>&1; then
216+
echo "ERROR: SARIF report is not valid JSON"
217+
exit 1
218+
fi
219+
220+
# Verify SARIF schema version and structure
221+
if ! jq -e '.version == "2.1.0" and has("runs")' report.sarif > /dev/null; then
222+
echo "ERROR: SARIF report does not match expected schema"
223+
exit 1
224+
fi
225+
226+
rm -f test_secret.txt report.json report.csv report.sarif
227+
- name: Test allowlist functionality
228+
runs: |
229+
# Create file with secret
230+
echo 'api_key = "AKIAIOSFODNN7EXAMPLE" # gitleaks:allow' > allowed_secret.txt
231+
232+
# This should pass because of the gitleaks:allow comment
233+
gitleaks detect --source allowed_secret.txt --no-git
234+
235+
# Create .gitleaksignore file
236+
echo 'allowed_secret2.txt' > .gitleaksignore
237+
echo 'aws_key = "AKIAIOSFODNN7EXAMPLE"' > allowed_secret2.txt
238+
239+
# This should pass because file is in .gitleaksignore
240+
gitleaks detect --source . --no-git
241+
242+
rm -f allowed_secret.txt allowed_secret2.txt .gitleaksignore
243+
- name: Test baseline functionality
244+
runs: |
245+
# Create initial scan with secrets
246+
echo 'token = "ghp_1234567890abcdef"' > baseline_test.txt
247+
gitleaks detect --source baseline_test.txt --no-git --report-path baseline.json --report-format json --exit-code 1 || true
248+
249+
# Using baseline should not report the same findings
250+
gitleaks detect --source baseline_test.txt --no-git --baseline-path baseline.json
251+
252+
rm -f baseline_test.txt baseline.json
253+
- name: Test protect mode
254+
runs: |
255+
# Create a git repo for testing protect mode
256+
mkdir -p protect-test
257+
cd protect-test
258+
git init
259+
git config user.email "test@example.com"
260+
git config user.name "Test User"
261+
262+
# Stage a file with secrets
263+
echo 'github_token = ghp_wWPw5k4aXcaajCqbDsLRnJZZzVLgLO0M' > staged_secret.txt
264+
git add staged_secret.txt
265+
266+
# Protect mode should detect staged secrets
267+
gitleaks protect --staged --exit-code 1 || EXIT_CODE=$?
268+
if [ "$EXIT_CODE" != "1" ]; then
269+
echo "ERROR: Protect mode should have detected staged secret"
270+
exit 1
271+
fi
272+
273+
cd ..
274+
rm -rf protect-test

0 commit comments

Comments
 (0)