Repository navigation
💡 Org Shell Defect-Class Regression Lint for scripts/ (jq/sed Injection, Temp Paths, Workflow Commands) #1474
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Summary
Turn the 26 security findings filed in one batch (#1384–#1409) into a deterministic, tested lint (scripts/lib/shell-defect-lint.sh plus bats tests). It fails CI when a known defect class comes back in the org's roughly 24k lines of bash. Neither CodeQL nor zizmor nor ShellCheck covers taint-style shell bugs.
Market Signal
Semgrep's Bash support has been experimental since 0.70 and its extract mode was removed in 1.65, so no mainstream SAST does taint analysis on bash. Newer tools such as foxguard ship bash taint rules, which shows the gap is recognised. Agent-authored shell is growing across the industry, and Trivy research reported 38% of workflows exposed to script injection.
User Signal
#1384 (workflow-command injection via echo), #1385 (jq program injection), #1397 (sed replacement injection), #1387/#1388 (fixed /tmp paths that follow symlinks), #1401 (regex match on IDs, grep error read as success), #1403/#1408 (quadratic loops), #1416 (refs treated as code). That is about 26 security issues closed in 30 days, and #1197 and #1462 show further hardening deferred.
Technical Opportunity
The repo already follows the 'decision logic in a pure, tested script' pattern (check-duplicate-decls.sh, agents-md-lint.sh with agents-md-rules.json, duplicate-decl-gate workflow). A rules JSON with one entry per defect class (regex or AST via tree-sitter-bash), each with fixture files taken from the actual pre-fix code of each issue, gives true-positive and true-negative bats tests. The lint wires in as a required check in ci-tests and as a reusable for downstream repos.
Assessment
Adversarial Review
Strongest objection: Regex lints on shell are noisy and get bypassed. A human review or Claude security review already found these bugs, so why build bespoke tooling?
Rebuttal: The review found them after the code had merged, as 26 separate issues. A lint stops them before merge, at zero marginal cost per PR. The scope is deliberately narrow: only the classes this org has actually shipped, each anchored to a real regression fixture, with an inline allow-comment carrying a justification for any exception. Noise is bounded because every rule needs a fixture proving the pre-fix code is flagged and the fixed code is not.
Suggested Next Step
Catalogue the 26 fixes in #1414–#1422 into a defect-class table (class, pre-fix snippet, fixed idiom), pick the 5 highest-frequency classes, and land a lint plus fixtures in DRY_RUN (warn-only) for 2 weeks before making it required.
All reactions