fix(detect): keep .tfvars out of the graph under the sensitive-dir carve-out (follow-up to #1955)

The #1943 carve-out rescues genuine source under secrets/ / credentials/, but
.tfvars sits in CODE_EXTENSIONS while being Terraform's canonical values store
(routinely real secrets), so it would now be indexed. Add .tfvars to
_SECRET_PRONE_DATA_EXTS so the shared graphable-source predicate drops it in
both Stage 1 and Stage 3; .tf/.hcl stay graphable as genuine infra source.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
safishamsi
2026-07-17 11:28:52 +01:00
co-authored by Claude Opus 4.8
parent 9ee151d826
commit 431dd18169
2 changed files with 14 additions and 0 deletions
+4
View File
@@ -144,6 +144,10 @@ _GENERIC_KEYWORD_PATTERNS = [
_SECRET_PRONE_DATA_EXTS = frozenset({
".json", ".yaml", ".yml", ".toml", ".ini", ".cfg", ".conf", ".config",
".xml", ".properties", ".env", ".txt",
# .tfvars is Terraform's canonical VALUES store (routinely holds real
# secrets), not source — keep it out of the graph even though it sits in
# CODE_EXTENSIONS. .tf/.hcl are genuine infra source and stay graphable.
".tfvars",
})
# Word separators for the load-bearing check (underscore intentionally included;
+10
View File
@@ -1108,6 +1108,16 @@ def test_sensitive_dir_carveout_does_not_bypass_name_screens():
assert _is_sensitive(Path("credentials/id_rsa")) # extensionless key
def test_sensitive_dir_carveout_still_drops_tfvars_values_store():
# #1943 follow-up: genuine source under secrets/ is rescued, but .tfvars is
# Terraform's canonical values store (real secrets), not source — it stays
# dropped, while the real code file beside it is kept.
assert _is_sensitive(Path("secrets/prod.tfvars"))
assert not _is_sensitive(Path("secrets/loader.py"))
# .tf / .hcl are genuine infra source and remain graphable under secrets/.
assert not _is_sensitive(Path("secrets/main.tf"))
# ── Generic keywords must be load-bearing: topic slugs are not secret stores ──
# A keyword buried mid-phrase in a >=3-word descriptive name is a note ABOUT
# the topic, not a credential file. It must not be silently dropped.