Analyze python -c inline code (based on #134, alignment fixed) - #149
Merged
Conversation
- Statically analyze python -c inline code using the existing SafetyAnalyzer AST visitor. Safe code (no I/O, no dangerous imports) is auto-approved. - Track per-word bash expansion flags (word_has_expansions) through HandlerContext so the python handler can detect when -c code contains $VAR or $(cmd) expansions and fall back to ask. - Config module overrides (python-allow-module / python-deny-module) apply to inline code analysis as well.
word_has_expansions was built over the full word list but the python handler indexes it against env-stripped tokens, so a leading FOO=bar shifted every flag and the -c expansion guard read the wrong token. Wrapper recursion (time/timeout/...) dropped the flags entirely. Re-slice the flags in lockstep with tokens at both points. Without this the guard silently no-ops and only the analyzer's syntax-error on $ saves it; with it, FOO=bar python -c "$VAR" and time python -c "$VAR" report a bash-expansion ask directly. (The env handler's delegation path is a separate re-parse round-trip, tracked in #116, and stays out of scope here.)
Closed
ldayton
added a commit
to nickdavies/Dippy
that referenced
this pull request
Jun 8, 2026
ldayton#149 landed word_has_expansions (per-token: was the word built from a bash expansion), which already does what this PR's opaque_positions needed and a bit more — it also flags multi-expansion words like a$X$Y, and it's aligned to the handler's tokens through env prefixes and wrapper recursion. Resolve the conflict by dropping opaque_positions and pointing the kubectl secret-exposure checks at word_has_expansions, so there's a single expansion-tracking mechanism in the analyzer's security path instead of two parallel ones. Behavior is equivalent-or-stricter; the kubectl tests are unchanged and still pass. Co-authored-by: Nick Davies <github@nicolasdavies.com.au>
ldayton
added a commit
that referenced
this pull request
Jun 8, 2026
kubectl get secret -o yaml / -o json / jsonpath and config view --raw expose secret material, so they now require approval (while -o name / -o wide stay allowed). Commands whose resource, subcommand, or output format comes from a bash expansion are treated conservatively, since they could resolve to a secret or a data-exposing format at runtime. Opacity is detected via the per-token word_has_expansions flag (from #149) rather than a separate opaque_positions set, keeping a single expansion-tracking mechanism in the analyzer's security path. The kubectl tests are unchanged and still pass. Co-authored-by: Lily Dayton <43729618+ldayton@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Statically analyze
python -cinline code so safe one-liners auto-approve instead of always prompting, while anything containing a bash expansion falls back toask.This is @nickdavies's #134 (his commit is preserved here), rebased onto
mainnow that its base #122 has merged, plus a fix for a token-alignment bug in the expansion guard and tests that cover it.What #134 does
python -cwas alwaysask. Now the inline body is run through the same AST safety analyzer used for script files: clean code →allow, dangerous imports/builtins →ask. Crucially, if the-cargument contains a bash expansion ($VAR,$(...), …) it's sent toask, because bash rewrites the code at runtime and the static view is no longer trustworthy.The bug this fixes
word_has_expansionswas computed over the full word list but the python handler indexes it against the env-strippedtokens. So a leading assignment shifted every flag:FOO=bar python -c "$VAR"→ guard read the wrong token and didn't firetime/timeout/nice/…) dropped the flags entirely in the recursionIt only stayed safe because
$is invalid Python and the analyzer's syntax-error backstop caught it — i.e. the dedicated guard was silently a no-op in those cases. The fix re-slices the flags in lockstep withtokensat both the env-skip and the wrapper-recursion points (mirroring how the secrets PR handlesopaque_positions).Before vs after:
FOO=bar python -c "$VAR"time python -c "$VAR"FOO=bar python -c 'print(1)'Tests
Added regression tests asserting the expansion reason fires (not the incidental syntax error) for env-prefixed and wrapper-wrapped
-c, plus the safe-body-still-approves counterparts. Full suite: 10965 passing.Out of scope
env X=1 python -c …routes through theenvhandler's delegation re-parse, a separate lossy round-trip tracked in #116; it remains safe via the syntax backstop and isn't touched here.Closes #134.