feat(analyzer): detect untrusted container image pull as SC7#224
feat(analyzer): detect untrusted container image pull as SC7#224CharmingGroot wants to merge 2 commits into
Conversation
supply_chain (SC1-SC6) covers package dependencies but not the container-image supply chain. A skill pulling images with verification disabled (--disable-content-trust, DOCKER_CONTENT_TRUST=0, --insecure-registry) accepts tampered images but scored 9/SAFE (NVIDIA#223). Add SC7_PATTERNS to the supply_chain analyzer (is_code_example filter) with pattern_defaults entries and 5 tests. --tls-verify=false is excluded since TM3's verify=False already covers it. Signed-off-by: CharmingGroot <ohyes9711@gmail.com>
rng1995
left a comment
There was a problem hiding this comment.
The SC7 patterns and metadata are otherwise well integrated, but the new module-level example filter lets executable code evade the rule with a nearby marker. Please rely on the runner's file-type-aware handling, or only suppress non-executable content, and add an executable-file evasion regression.
| for pattern, confidence in SC7_PATTERNS: | ||
| for match in re.finditer(pattern, content, re.IGNORECASE | re.MULTILINE): | ||
| context_text = ctx(match.start()) | ||
| if is_code_example(context_text): |
There was a problem hiding this comment.
Blocking: this unconditional skip creates an attacker-controlled bypass in executable files. is_code_example() returns true for any nearby 'for example', code fence, and similar marker, so a shell script with '# for example' within three lines of 'docker pull --disable-content-trust ...' produces no SC7 finding. The shared runner already filters examples in non-executable docs and only downweights them in executable files. Remove or scope this early continue and add an executable evasion regression.
There was a problem hiding this comment.
Good catch — my mistake. The runner already applies is_code_example (filtering non-executable docs and only downweighting executables), so calling it again in the SC7 loop with an unconditional continue is redundant and opens exactly the executable-file bypass you flagged: a # for example within a few lines of docker pull --disable-content-trust suppresses the finding entirely.
Fix incoming: drop the is_code_example call from SC7 and rely on the runner's file-type-aware handling, plus a regression test asserting a content-trust bypass in a .sh still fires with an example marker nearby.
…utable bypass SC7 called is_code_example() with an unconditional continue, letting a nearby example marker (e.g. a '# for example' comment a few lines from a content-trust bypass) suppress the rule in executable files. The shared runner already filters examples in non-executable docs and only downweights executables, so the analyzer-level call was redundant and created an attacker-controlled bypass. Drop it and rely on the runner's file-type-aware handling; add an executable-file evasion regression test. Addresses review feedback on NVIDIA#224. Signed-off-by: CharmingGroot <ohyes9711@gmail.com>
E5 (NVIDIA#218) and TM4 (NVIDIA#220) called is_code_example() with an unconditional continue, letting a nearby example marker (e.g. "# for example") suppress findings in executable files. The shared runner already filters examples in non-executable docs and only downweights executables, so the analyzer-level call was redundant and created an attacker-controlled bypass — the same issue fixed for SC7 in NVIDIA#224. Remove it from both analyzers; replace TM4's analyze-level doc-exclusion test with an executable-evasion test and add the equivalent E5 regression. Signed-off-by: CharmingGroot <ohyes9711@gmail.com>
…utable bypass SC7 called is_code_example() with an unconditional continue, letting a nearby example marker (e.g. a '# for example' comment a few lines from a content-trust bypass) suppress the rule in executable files. The shared runner already filters examples in non-executable docs and only downweights executables, so the analyzer-level call was redundant and created an attacker-controlled bypass. Drop it and rely on the runner's file-type-aware handling; add an executable-file evasion regression test. Addresses review feedback on NVIDIA#224. Signed-off-by: CharmingGroot <ohyes9711@gmail.com>
033fbe6 to
9526734
Compare
Summary
The
supply_chainanalyzer (SC1–SC6) covers package dependencies (PyPI/npm) but has no detection for the container-image supply chain. A skill that pulls images with verification turned off —--disable-content-trust,DOCKER_CONTENT_TRUST=0,--insecure-registry— accepts tampered or unverified images yet scored 9/100 SAFE (#223). This adds SC7, the image-layer counterpart of SC1 (unpinned) / SC6 (typosquatting).Changes
static_patterns_supply_chain.pygainsSC7_PATTERNS(three image-trust bypass flags) and an SC7 pass filtered through the sharedis_code_example()helper.pattern_defaults.pyregisters the SC7 explanation, category, message, and remediation alongside SC1–SC6.Before / After
A "fast image loader" skill that sets
DOCKER_CONTENT_TRUST=0and pulls with--disable-content-trust/--insecure-registry:9/100 SAFE— only the unrelated--tls-verify=falseline is caught (as a generic TM3verify=False); the image-trust bypass is invisible57/100 HIGH, SC7 ×3 on the content-trust and insecure-registry linesWith the LLM layer (Qwen3.6-35B-A3B-FP8 via vLLM) the same skill scores
78/HIGH(SDI-1: "disables Docker Content Trust, TLS verification …"), so--no-llm/ air-gapped deployments were the exposed surface this closes.Design Decisions
supply_chain(not new)--tls-verify=falseexcludedverify=Falsepattern already catches it. SC7 targets only the image-specific bypasses TM3 cannot see (--disable-content-trust,DOCKER_CONTENT_TRUST=0,--insecure-registry) — avoids duplicate findings on the same line.docker pull nginx:1.25does not fire.Testing
5 new tests: detection of
--disable-content-trust,DOCKER_CONTENT_TRUST=0, and--insecure-registry; a documentation-example exclusion (is_code_example); and a benign-pull negative.make formatandmake lintpass;uv run pytest -m "not integration and not provider"reports 1003 passed, 0 failed.Closes #223