Skip to content

Commit caca37d

Browse files
cmraible9larsons
andauthored
Added secret scanning pre-commit hook (#27609)
ref https://linear.app/tryghost/issue/NY-1247/add-a-git-pre-commit-hook-to-check-for-secrets-in-staged - Added secret lint dependency & configuration - Added pre-commit hook that scans staged changes for secrets, blocking commits that fail the check --------- Co-authored-by: Steve Larson <9larsons@gmail.com>
1 parent 0c16fef commit caca37d

4 files changed

Lines changed: 504 additions & 6 deletions

File tree

.github/hooks/pre-commit.bash

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33

44
[ -n "$CI" ] && exit 0
55

6+
green='\033[0;32m'
7+
no_color='\033[0m'
8+
grey='\033[0;90m'
9+
red='\033[0;31m'
10+
611
pnpm lint-staged --relative
712
lintStatus=$?
813

@@ -11,13 +16,62 @@ if [ $lintStatus -ne 0 ]; then
1116
exit 1
1217
fi
1318

14-
green='\033[0;32m'
15-
no_color='\033[0m'
16-
grey='\033[0;90m'
17-
red='\033[0;31m'
19+
##
20+
## 1) Scan staged text files for secrets
21+
##
22+
23+
scan_staged_secrets() {
24+
local file
25+
local files_scanned=0
26+
local scan_status=0
27+
local tmpfile
28+
29+
if ! pnpm exec secretlint --version >/dev/null 2>&1; then
30+
echo -e "${red}secretlint is not available. Run pnpm install from the repository root.${no_color}"
31+
return 1
32+
fi
33+
34+
if ! tmpfile=$(mktemp); then
35+
echo -e "${red}Could not create temp file for secret scanning${no_color}"
36+
return 1
37+
fi
38+
39+
echo -e "Scanning staged files for secrets ${grey}(pre-commit hook)${no_color} "
40+
41+
while IFS= read -r -d '' file; do
42+
if ! git show ":$file" > "$tmpfile"; then
43+
scan_status=1
44+
continue
45+
fi
46+
47+
if LC_ALL=C grep -Iq . "$tmpfile"; then
48+
files_scanned=$((files_scanned + 1))
49+
50+
if ! pnpm exec secretlint --format=compact --stdinFileName="$file" < "$tmpfile"; then
51+
scan_status=1
52+
fi
53+
fi
54+
done < <(git diff --cached --name-only --diff-filter=ACMR -z)
55+
56+
if [ $files_scanned -eq 0 ]; then
57+
echo "No staged text files to scan, continuing..."
58+
fi
59+
60+
rm -f "$tmpfile"
61+
62+
return $scan_status
63+
}
64+
65+
scan_staged_secrets
66+
secretScanStatus=$?
67+
68+
if [ $secretScanStatus -ne 0 ]; then
69+
echo -e "${red}❌ Secret scanning failed${no_color}"
70+
exit 1
71+
fi
1872

1973
##
20-
## 1) Check and remove submodules before committing
74+
## 2) Check and remove submodules before committing
2175
##
2276

2377
ROOT_DIR=$(git rev-parse --show-cdup)
@@ -47,7 +101,7 @@ else
47101
fi
48102

49103
##
50-
## 2) Suggest shipping a new version of @tryghost/activitypub when changes are detected
104+
## 3) Suggest shipping a new version of @tryghost/activitypub when changes are detected
51105
## The intent is to ship smaller changes more frequently to production
52106
##
53107

.secretlintrc.json

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"rules": [
3+
{
4+
"id": "@secretlint/secretlint-rule-preset-recommend"
5+
},
6+
{
7+
"id": "@secretlint/secretlint-rule-pattern",
8+
"options": {
9+
"patterns": [
10+
{
11+
"name": "Tinybird token",
12+
"patterns": [
13+
"/\\b(?<CREDENTIAL>p\\.eyJ[A-Za-z0-9_-]{15,}\\.[A-Za-z0-9_-]{20,})\\b/"
14+
]
15+
},
16+
{
17+
"name": "credential in URL query string",
18+
"patterns": [
19+
"/[?&](?:token|api[_-]?key|access[_-]?token|auth[_-]?token|client[_-]?secret|secret|password)=(?<CREDENTIAL>(?!p\\.)[^&\\s\"'<>]{16,})/i"
20+
]
21+
},
22+
{
23+
"name": "credential assignment",
24+
"patterns": [
25+
"/(?:^|[\\s{\"',])\\b(?:api[_-]?key|access[_-]?token|auth[_-]?token|client[_-]?secret|secret[_-]?key|private[_-]?key|password)\\b\\s*[:=]\\s*[\"']?(?<CREDENTIAL>[A-Za-z0-9_./+=:-]{20,})[\"']?/i"
26+
]
27+
},
28+
{
29+
"name": "authorization header",
30+
"patterns": [
31+
"/\\bAuthorization\\s*:\\s*(?:Bearer|Basic)\\s+(?<CREDENTIAL>[A-Za-z0-9_./+=:-]{20,})/i"
32+
]
33+
}
34+
]
35+
}
36+
}
37+
]
38+
}

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@
119119
"devDependencies": {
120120
"@actions/core": "3.0.0",
121121
"@playwright/test": "1.59.1",
122+
"@secretlint/secretlint-rule-pattern": "12.3.1",
123+
"@secretlint/secretlint-rule-preset-recommend": "12.3.1",
122124
"chalk": "4.1.2",
123125
"chokidar": "3.6.0",
124126
"eslint": "catalog:",
@@ -130,6 +132,7 @@
130132
"lint-staged": "16.4.0",
131133
"nx": "22.0.4",
132134
"rimraf": "6.1.3",
135+
"secretlint": "12.3.1",
133136
"semver": "7.7.4",
134137
"typescript": "5.9.3"
135138
},

0 commit comments

Comments
 (0)