Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix(analyzer): cover indirect shell truthiness across Python execution surfaces - #497

Open
chrisknvidia wants to merge 5 commits into
NVIDIA:mainfrom
chrisknvidia:feat/christopherk/issue-475-shell-truthiness
Open

fix(analyzer): cover indirect shell truthiness across Python execution surfaces#497
chrisknvidia wants to merge 5 commits into
NVIDIA:mainfrom
chrisknvidia:feat/christopherk/issue-475-shell-truthiness

Conversation

@chrisknvidia

@chrisknvidia chrisknvidia commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Summary

  • fix shell=True detection can be bypassed through variable assignment (malicious skill example that bypasses this static detection model) #475 across Python execution surfaces, including .py, .pyw, trusted extensionless Python shebangs, nested artifacts, and transitive scans
  • resolve definitely truthy indirect shell= values while preserving conservative behavior for dynamic, ambiguous, or effectful code
  • share one bounded tri-state Python source classifier and strict PEP 263 decoder across AST prewarm, static analyzers, artifact inventory, and reporting
  • model CPython and env launch forms that can execute the scanned artifact, including explicit -i, PYTHONINSPECT, bare -c path execution, bare -m, GNU/Darwin option differences, and clear-environment ordering
  • fail closed when source intent, decoding, traversal, or a child scan is incomplete; preserve exact fatal/risk facts under output caps and keep JSON/SARIF/Markdown stdout parseable and secret-safe

Supported contract

The AST companion follows bounded, source-ordered facts for direct subprocess receivers and imported callables. It handles straight-line assignments, safe protocol/finalizer cases, relevant function/class binding effects, and repeated trusted calls. Imports, arbitrary calls, mutation, rebinding, deletion, and other effects invalidate facts when safety cannot be proved.

Python source eligibility is no longer extension-only. Definite Python sources are analyzed; definite non-Python sources stay out of the Python AST path; runtime-dependent sources are still analyzed conservatively but publish python_source_ambiguous and incomplete status. Invalid source encodings similarly fail closed with python_source_decode_error.

Recursive aggregation now distinguishes work that was not scanned from scanned results omitted only for bounded output. Child failures remain fatal at ledger caps 1 and 2, aggregate risk survives record/serialization caps in every format, and machine-readable stdout is report-only.

Verification

Candidate: c986c3e4da2e7f6cee623ca2eac298a61a99a107

  • final repository-wide run excluding only the environment-blocked stdio timing test: 5,223 passed, 14 skipped, 39 deselected, 4 expected xfails
  • broad changed-surface matrix: 1,836 passed, 1 skipped
  • full CLI suite: 169 passed; related CLI/MCP/completeness/deadline matrix: 220 passed
  • build-context/transitive/input integration: 151 passed, 1 skipped
  • isolated Python 3.13 and Python 3.14 parser/TM1 matrices: 1,060 passed on each interpreter
  • fresh source and installed-wheel matrices: 35/35 each, with semantic parity after removing only generated IDs and timestamps
  • recursive CLI: 18/18 source/wheel runs across terminal, JSON, Markdown, and SARIF; stdout/file destinations and strict incomplete mode passed
  • installed-wheel MCP public surface: 8 real static scans across all four formats; complete and partial verdict contracts passed
  • real Darwin and GNU env execution matrices: 25/25 each; native and Docker PTY, explicit -i, PYTHONINSPECT, and exact bare -c/-m execution probes passed
  • real-root transitive fault probe: caps 1 and 2 invoked the child and retained the fatal failure; CLI exited 2; no private exception payload or unaccounted_work
  • sdist/wheel build, twine check, isolated Python 3.14 install, 82-package dependency check, compileall, and import/version checks passed
  • no-cache arm64 Docker build plus representative scanner, PTY, and relative-exec runtime matrices passed
  • Ruff, format, and git diff --check passed; multiple independent review passes found no remaining actionable finding
  • fresh GitHub CI on the exact head passed: changes, lint, test-unit, DCO, and Docker smoke

Remaining verification limits

  • No live LLM/provider request was made and no credentials were inspected; all runtime scans used --no-llm / use_llm=False.
  • No live FreeBSD host was available. FreeBSD-only parsing is regression-tested and bounded by live GNU/Darwin differentials. Local GNU coreutils 9.1 also cannot live-prove newer --env0-from behavior.
  • The transitive root scan was real, while the child transport failure was deterministically injected rather than produced by a live remote clone failure.
  • The real MCP stdio handshake test could not complete locally within its fixed 15-second timeout under severe endpoint-security and unrelated-workload I/O starvation. A simultaneous clean origin/main control timed out identically (60.193s versus 60.178s for the branch), while all other MCP server tests, direct public MCP scans, and server construction passed. The exact-head GitHub test-unit job passed on its clean runner.
  • Docker verification was arm64-only locally.

Fixes #475

@chrisknvidia
chrisknvidia marked this pull request as ready for review September 8, 2026 08:11
@chrisknvidia
chrisknvidia marked this pull request as draft September 8, 2026 08:28
@chrisknvidia
chrisknvidia marked this pull request as ready for review September 8, 2026 23:30
@chrisknvidia
chrisknvidia marked this pull request as draft September 9, 2026 00:00
@chrisknvidia
chrisknvidia marked this pull request as ready for review September 9, 2026 06:44
@chrisknvidia chrisknvidia changed the title fix(analyzer): resolve indirect subprocess shell values fix(analyzer): cover indirect shell truthiness across Python execution surfaces Sep 10, 2026

@rng1995 rng1995 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[SkillSpector Review]

Manual Review Needed at head c986c3e4da2e7f6cee623ca2eac298a61a99a107.

The current PR is too large and cross-cutting for a reliable approval in this review run: it adds 16,613 lines across 25 files, including new ~1,900-line Python dataflow and source-decoding implementations, and changes artifact classification, scan budgets/completeness, CLI/reporting behavior, and multiple analyzers. Green CI is not a substitute for a complete architectural and security review.

Please split the original shell-truthiness fix from (1) Python encoding/shebang and platform-command parsing, and (2) scan-budget/output/reporting changes, with each change independently documented and tested. No approval should be inferred from this comment. Observable CI is green, but the PR is currently BEHIND and an authorized full current-head review remains required before merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

shell=True detection can be bypassed through variable assignment (malicious skill example that bypasses this static detection model)

3 participants