blob: 1ac82eeac44b6b1d8f94e12b0c6c5b960a7fa577 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
#!/usr/bin/env bats
#
# Tests for languages/python/githooks/pre-commit — the secret scan plus
# syntax/lint gate that runs on staged Python files.
#
# The secret scan is the security-critical half and is language-independent, so
# it gets the same coverage here as in the bash bundle: a real key blocks, a
# clean diff passes, and the case-sensitivity split that keeps base64 blobs from
# false-positiving is exercised directly.
#
# Each test builds a throwaway git repo, stages content, and runs the hook from
# inside it — the hook reads `git diff --cached`, so a real index is required.
HOOK="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)/githooks/pre-commit"
setup() {
TEST_DIR="$(mktemp -d -t pre-commit-py-bats.XXXXXX)"
cd "$TEST_DIR" || exit 1
git init -q .
git config user.email t@example.com
git config user.name Test
# A base commit so `git diff --cached` has a parent to diff against.
echo "seed" > seed.txt
git add seed.txt
git commit -qm seed
}
teardown() {
cd / || true
rm -rf "$TEST_DIR"
}
# ---- Normal ----------------------------------------------------------
@test "pre-commit(py): a clean staged Python file passes (exit 0)" {
printf 'def f(x):\n return x + 1\n' > ok.py
git add ok.py
run bash "$HOOK"
[ "$status" -eq 0 ]
}
@test "pre-commit(py): an empty staging area passes (exit 0)" {
run bash "$HOOK"
[ "$status" -eq 0 ]
}
# ---- Error: the secret scan ------------------------------------------
@test "pre-commit(py): an AWS key in a staged file blocks (exit 1)" {
printf 'KEY = "AKIAIOSFODNN7EXAMPLE"\n' > conf.py
git add conf.py
run bash "$HOOK"
[ "$status" -eq 1 ]
[[ "$output" == *"potential secret"* ]]
}
@test "pre-commit(py): an sk- style token blocks (exit 1)" {
printf 'TOKEN = "sk-abcdefghijklmnopqrstuvwxyz0123"\n' > conf.py
git add conf.py
run bash "$HOOK"
[ "$status" -eq 1 ]
}
@test "pre-commit(py): a quoted api_key assignment blocks (exit 1)" {
printf 'api_key = "abcdefghijklmnopqrstuvwxyz"\n' > conf.py
git add conf.py
run bash "$HOOK"
[ "$status" -eq 1 ]
}
@test "pre-commit(py): a private-key header blocks (exit 1)" {
printf 'PEM = """-----BEGIN RSA PRIVATE KEY-----"""\n' > conf.py
git add conf.py
run bash "$HOOK"
[ "$status" -eq 1 ]
}
# ---- Boundary: the case-sensitivity split ----------------------------
@test "pre-commit(py): a mixed-case base64 blob does NOT false-positive" {
# The AWS pattern is uppercase-only by design. Under -i it would match any
# 20-char mixed-case run, which random base64 hits often enough to block
# real commits. This is the regression test for that split.
printf 'BLOB = "AKIAbcdefGHIJklmnOPqr0123456789abcdefGHIJ"\n' > data.py
git add data.py
run bash "$HOOK"
[ "$status" -eq 0 ]
}
@test "pre-commit(py): a short quoted password value does NOT block" {
# The keyword patterns require 16+ chars, so a placeholder stays quiet.
printf 'password = "short"\n' > conf.py
git add conf.py
run bash "$HOOK"
[ "$status" -eq 0 ]
}
@test "pre-commit(py): a secret only in a REMOVED line does not block" {
printf 'KEY = "AKIAIOSFODNN7EXAMPLE"\n' > conf.py
git add conf.py
git commit -qm "add key"
rm conf.py
git add -A
run bash "$HOOK"
[ "$status" -eq 0 ]
}
# ---- Error: the syntax gate ------------------------------------------
@test "pre-commit(py): a staged Python syntax error blocks (exit 1)" {
printf 'def f(:\n return 1\n' > bad.py
git add bad.py
run bash "$HOOK"
[ "$status" -eq 1 ]
[[ "$output" == *"syntax"* ]]
}
@test "pre-commit(py): a .pyi stub with a syntax error blocks (exit 1)" {
printf 'def f( -> int: ...\n' > bad.pyi
git add bad.pyi
run bash "$HOOK"
[ "$status" -eq 1 ]
}
@test "pre-commit(py): a broken NON-Python file does not trip the syntax gate" {
printf 'this is (((not python\n' > notes.txt
git add notes.txt
run bash "$HOOK"
[ "$status" -eq 0 ]
}
@test "pre-commit(py): the syntax gate leaves no __pycache__ in the repo" {
printf 'def f():\n return 1\n' > ok.py
git add ok.py
run bash "$HOOK"
[ "$status" -eq 0 ]
[ ! -d __pycache__ ]
}
|