Bash · 2523 bytes Raw Blame History
1 #!/usr/bin/env bash
2 # SPDX-License-Identifier: AGPL-3.0-or-later
3 #
4 # Fail when source code emits log lines containing token-prefix
5 # patterns that would leak credentials into operator logs. The
6 # canonical bad shape:
7 #
8 # logger.Info("got authorization header", "auth", r.Header.Get("Authorization"))
9 #
10 # Even when the value happens to be empty, the format string itself
11 # is a smell — anyone who edits the line to format the value back in
12 # will silently start logging the secret.
13 #
14 # Patterns we reject (case-insensitive substring match in *.go):
15 # - "shithub_pat_" — PAT token prefix
16 # - "otpauth://" — TOTP URI containing the secret
17 # - "Authorization:" — header literal that suggests dumping headers
18 #
19 # Carve-outs (whitelisted paths) live in EXEMPTS below. The S08 PAT
20 # redactor for git-clone URLs and the auth-flow tests are the legit
21 # call sites; everything else is suspicious.
22 #
23 # Run as part of `make ci`.
24
25 set -euo pipefail
26
27 cd "$(git rev-parse --show-toplevel)"
28
29 EXEMPTS=(
30 # S08 redactor explicitly handles the prefix to strip it from URLs.
31 "internal/auth/pat/"
32 # Log redactor IS the canonical handler for the secret patterns.
33 "internal/infra/log/log.go"
34 # TOTP package builds the otpauth:// URI for the QR provisioning
35 # code — never logs it, just constructs.
36 "internal/auth/totp/totp.go"
37 # PAT middleware parses (not logs) the Authorization header.
38 "internal/web/middleware/pat.go"
39 # Git-HTTP auth handler mentions the prefix in doc comments.
40 "internal/web/handlers/githttp/auth.go"
41 # Tests legitimately mention these strings in fixtures.
42 "_test.go"
43 # The lint script itself documents the patterns.
44 "scripts/lint-secret-logs.sh"
45 )
46
47 RE='shithub_pat_|otpauth://|Authorization:'
48
49 # grep -EIn: extended regex, ignore binary, show line numbers.
50 # Search only shithub-owned trees — .refs/ vendored repos are docs.
51 matches=$(grep -RIEn --include='*.go' "$RE" cmd internal scripts 2>/dev/null || true)
52
53 filtered=""
54 while IFS= read -r line; do
55 [ -z "$line" ] && continue
56 skip=false
57 for pat in "${EXEMPTS[@]}"; do
58 if [[ "$line" == *"$pat"* ]]; then
59 skip=true
60 break
61 fi
62 done
63 $skip || filtered="${filtered}${line}"$'\n'
64 done <<< "$matches"
65
66 if [ -n "${filtered// /}" ]; then
67 echo "lint-secret-logs: token-prefix patterns found in non-exempt source:" >&2
68 echo "$filtered" >&2
69 echo >&2
70 echo "If this is a legitimate use, add the file to EXEMPTS in scripts/lint-secret-logs.sh." >&2
71 exit 1
72 fi
73
74 echo "lint-secret-logs: ok"