Summary
remoteResolver.download() saves, sets and restores the process-global GIT_TERMINAL_PROMPT environment variable on every call:
// pkg/iac/scanners/terraform/parser/resolvers/remote.go:88-93
terminalPrompt := os.Getenv("GIT_TERMINAL_PROMPT")
os.Setenv("GIT_TERMINAL_PROMPT", "0")
defer os.Setenv("GIT_TERMINAL_PROMPT", terminalPrompt)
The variable is process-global, so concurrent download() calls create a TOCTOU window. This is not a memory data race (Go serializes environment access internally) but a logical one.
- Lost original value. Goroutine B reads
"0" (set by A) as the original, then restores to "0" on exit. The user's original value is lost for the rest of the process, affecting later git operations including pkg/downloader.
- Prompt re-enabled mid-clone. Goroutine A's deferred restore turns the prompt back on while B's
git clone is still running, so git blocks waiting for interactive credentials on a non-interactive server instead of failing fast (hang / soft DoS).
Reachability
trivy config / trivy fs: module resolution is sequential — not affected.
trivy image / trivy vm: per-layer PostAnalyze runs concurrently (--parallel, default 5), so two layers can invoke the Terraform scanner and download() at the same time. Reachable within a single CLI process.
- Trivy embedded as a library with concurrent Terraform scans.
Open question
Setting GIT_TERMINAL_PROMPT=0 once makes it process-wide, visible to embedders. This is acceptable in practice — the variable only controls whether git prompts for credentials interactively, which no application embedding a scanner relies on, and pkg/downloader already runs without restoring it. Confirm this is acceptable before implementing.
Summary
remoteResolver.download()saves, sets and restores the process-globalGIT_TERMINAL_PROMPTenvironment variable on every call:The variable is process-global, so concurrent
download()calls create a TOCTOU window. This is not a memory data race (Go serializes environment access internally) but a logical one."0"(set by A) as the original, then restores to"0"on exit. The user's original value is lost for the rest of the process, affecting later git operations includingpkg/downloader.git cloneis still running, so git blocks waiting for interactive credentials on a non-interactive server instead of failing fast (hang / soft DoS).Reachability
trivy config/trivy fs: module resolution is sequential — not affected.trivy image/trivy vm: per-layerPostAnalyzeruns concurrently (--parallel, default 5), so two layers can invoke the Terraform scanner anddownload()at the same time. Reachable within a single CLI process.Open question
Setting
GIT_TERMINAL_PROMPT=0once makes it process-wide, visible to embedders. This is acceptable in practice — the variable only controls whether git prompts for credentials interactively, which no application embedding a scanner relies on, andpkg/downloaderalready runs without restoring it. Confirm this is acceptable before implementing.