|
74 | 74 | |NODE_TLS_REJECT_UNAUTHORIZED\W{0,3}0 |
75 | 75 | |sslmode=disable |
76 | 76 | |SSL_VERIFYPEER\W{1,4}(false|0))"""), False), |
| 77 | + # env-var lookup falling back to a literal default secret (the classic |
| 78 | + # `process.env.JWT_SECRET || 'your-secret-key'`) — the placeholder filter |
| 79 | + # doesn't apply here: a placeholder USED as the runtime default is the bug |
| 80 | + ("default secret fallback", "A.5.17 Authentication information", |
| 81 | + re.compile(r"""(?ix)\benv(?:\.|\[["'])\w*(secret|token|key|passw)\w*(?:["'\]])? |
| 82 | + \s*(?:\|\||\?\?)\s*["'][^"']{6,}["']"""), True), |
77 | 83 | ] |
78 | 84 | _DEBUG_TRUE = re.compile(r"^\s*DEBUG\s*=\s*True\b") # Django settings*.py only |
| 85 | +# comment leaders — advice-like patterns (TLS/crypto/config) in comments are |
| 86 | +# docs, not deviations; secrets stay flagged even in comments (commented-out |
| 87 | +# creds are still a leak) |
| 88 | +_COMMENT = re.compile(r"^\s*(#|//|--|\*|<!--|;)") |
| 89 | +# generic secret-named assignments in test code are fixtures, not leaks; |
| 90 | +# fixed-prefix vendor tokens still flag everywhere (a real key in a test IS a leak) |
| 91 | +_TEST_PATH = re.compile(r"(?i)(^|/)(tests?|__tests__|fixtures)/|\.(test|spec)\.|(^|/)test_|_test\.") |
79 | 92 |
|
80 | 93 |
|
81 | 94 | @dataclass |
@@ -122,10 +135,16 @@ def check(root: str | Path) -> IsmsResult: |
122 | 135 | continue |
123 | 136 | result.files_scanned += 1 |
124 | 137 | is_settings = name.startswith("settings") and p.suffix == ".py" |
| 138 | + is_test = bool(_TEST_PATH.search(rel)) |
125 | 139 | for n, line in enumerate(p.read_text(errors="replace").splitlines(), 1): |
126 | 140 | if "privcheck-ignore" in line: |
127 | 141 | continue |
| 142 | + in_comment = bool(_COMMENT.match(line)) |
128 | 143 | for issue, control, rx, redact in RULES: |
| 144 | + if in_comment and not redact: |
| 145 | + continue # advice patterns in comments are docs, not code |
| 146 | + if issue == "hardcoded secret" and is_test: |
| 147 | + continue # test fixtures; vendor-token rules still apply |
129 | 148 | if m := rx.search(line): |
130 | 149 | if issue == "hardcoded secret" and _PLACEHOLDER.match(m.group(2)): |
131 | 150 | continue |
|
0 commit comments