Skip to content

fix(registry): resolve paren/brace wraps and env-then-sudo in command safety - #5606

Merged
JSONbored merged 1 commit into
JSONbored:mainfrom
wondercreatemaster:fix/resolveSegmentCommand-paren-brace-env-sudo-5585
Jul 27, 2026
Merged

fix(registry): resolve paren/brace wraps and env-then-sudo in command safety#5606
JSONbored merged 1 commit into
JSONbored:mainfrom
wondercreatemaster:fix/resolveSegmentCommand-paren-brace-env-sudo-5585

Conversation

@wondercreatemaster

@wondercreatemaster wondercreatemaster commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Fix resolveSegmentCommand so leading (/{/whitespace are skipped before reading the command word — (rm -rf /) resolves to rm instead of "".
  • Loop sudo/env prefix stripping until stable so env VAR=x sudo <cmd> is handled the same as sudo env VAR=x <cmd>.
  • Every shell-safety detector that depends on the resolver (hasRecursiveForceRemove, hasWorldWritableChmod, hasPipeToShellInstall, hasBase64DecodedShell) benefits without per-detector changes.

Closes #5585

Submission Source

  • This is not a direct content submission.
  • Changed routes/components/endpoints/tools are listed below.
  • Screenshots or No visual impact are included when relevant.
  • This PR links the issue it resolves, or the no-issue maintainer-lane rationale is written in Notes.

Schema and Quality Checks

  • Platform/code PR: focused validation is listed below.
  • No forbidden fields were added (viewCount, copyCount, popularityScore)

Quality Evidence

  • Changed surface:

  • Resolver change: skip leading (/{/whitespace on each prefix-loop iteration and before the final command read; re-check sudo/env after each strip instead of a fixed sudo-then-env order.

  • Expected behavior / before→after:

    input before (resolveSegmentCommandhasRecursiveForceRemove) after
    (rm -rf /) ""false rmtrue
    env FOO=bar sudo rm -rf / sudofalse rmtrue
    sudo env FOO=bar rm -rf / rm → true rm → true (unchanged)
    rm -rf / rm → true rm → true (unchanged)
  • Invariants: individual detector logic untouched; only the shared resolver changed (per issue scope).

  • Screenshots: No visual impact — registry command-safety correctness only; no routes/UI.

Validation

  • pnpm exec vitest run tests/command-safety-lib.test.ts tests/command-safety.test.ts tests/command-safety-posix-shell.test.ts98 passed
  • pnpm exec vitest run tests/submission-risk-invariants.test.ts72 passed
  • pnpm build — passed
  • pnpm validate:clean — passed
  • pnpm exec prettier --check on touched files — clean
  • trunk check --upstream origin/main — no issues
  • git diff --check / node --check packages/registry/src/command-safety-lib.js — clean

Notes

… safety

Skip leading (/ { /whitespace in resolveSegmentCommand so (rm -rf /) still
resolves to rm, and loop sudo/env prefix stripping so env VAR=x sudo <cmd>
is handled the same as sudo env.

Closes JSONbored#5585

Co-authored-by: Cursor <cursoragent@cursor.com>
@loopover-orb

loopover-orb Bot commented Jul 27, 2026

Copy link
Copy Markdown

Warning

⏸️ LoopOver review result - manual review recommended

Review updated: 2026-07-27 20:22:56 UTC

2 files · 1 AI reviewer · no blockers · CI pending · blocked

⏸️ Suggested Action - Manual Review

Review summary
This PR fixes resolveSegmentCommand to skip leading grouping characters ((/{) and whitespace, and loops sudo/env prefix stripping to convergence rather than a fixed order, closing a real evasion gap (#5585) where wrapping a command in parens/braces or reordering env/sudo caused detectors like hasRecursiveForceRemove to miss dangerous commands. The logic is correct: skipGroupingOpeners, skipAssignments, skipSudoPrefix, and skipEnvPrefix are looped until no strip succeeds, then a final grouping/assignment skip runs before reading the command token, matching the documented before/after table. Tests are focused, cover the new grouping and prefix-loop cases (paren, brace, nested parens, env-then-sudo, sudo-then-env, sudo-inside-paren), and the change is scoped only to the shared resolver plus its regression tests as claimed.

Nits — 4 non-blocking
  • skipGroupingOpeners does not track quote state, so a quoted string beginning with '(' or '{' as its first character (e.g. an env value edge case) could theoretically be misparsed, though this is unlikely to occur at the position it's called (command-safety-lib.js resolveSegmentCommand).
  • No closing-paren/brace handling is added — the resolver treats '(rm -rf /)' as 'rm' with trailing ')' likely absorbed elsewhere; consider a comment or test noting how the trailing group closer is handled by downstream arg-token parsing.
  • Consider adding a test for unbalanced or deeply nested grouping (e.g. '(((rm -rf /' without closing) to confirm no infinite loop or incorrect index, since skipGroupingOpeners has no upper bound guard beyond `end`.
  • Add a brief inline note on why skipGroupingOpeners doesn't need quote-awareness, for future maintainers touching this function.

Decision drivers

  • ✅ Code review — No blockers (1 reviewer)
  • ✅ Gate result — Passing (No configured blocker found.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ✅ Linked #5585
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low review scope from cached public metadata (1 linked issue).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 33 registered-repo PR(s), 21 merged, 0 issue(s).
Contributor context ✅ Confirmed Gittensor contributor wondercreatemaster; Gittensor profile; 33 PR(s), 0 issue(s).
Improvement ✅ Minor risk: clean · value: minor · LLM: moderate
Linked issue satisfaction

Addressed
The diff adds skipGroupingOpeners() to strip leading whitespace/paren/brace and restructures sudo/env stripping into a loop that rechecks after each strip, matching the issue's desired behavior, and includes 'Closes #5585' plus regression tests for both (rm -rf /) and env...sudo cases with before/after evidence.

Review context
  • Author: wondercreatemaster
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: JavaScript, Python, TypeScript, Java, MDX, Swift
  • Official Gittensor activity: 33 PR(s), 0 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Keep the PR focused and include validation evidence before maintainer review.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.
🧪 Chat with LoopOver

Ask LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.

  • @loopover ask &lt;question&gt; answers contribution-quality Q&A with source citations and freshness.
  • @loopover chat &lt;question&gt; answers in natural prose from cached decision-pack facts via local inference (maintainer/collaborator; read-only).
  • A plain-language @loopover mention with a real question is routed to the closest matching read-only command automatically — no exact syntax required.

Full command reference: https://loopover.ai/docs/loopover-commands

🧪 Experimental — new and may change.

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed


💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.

  • Re-run LoopOver review

@loopover-orb loopover-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.5x multiplier. label Jul 27, 2026
@codecov

codecov Bot commented Jul 27, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.43%. Comparing base (442a72d) to head (0efe732).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #5606   +/-   ##
=======================================
  Coverage   96.42%   96.43%           
=======================================
  Files         529      529           
  Lines       16321    16334   +13     
  Branches     3734     3734           
=======================================
+ Hits        15738    15751   +13     
  Misses        195      195           
  Partials      388      388           
Files with missing lines Coverage Δ
packages/registry/src/command-safety-lib.js 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@JSONbored
JSONbored merged commit dea61da into JSONbored:main Jul 27, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:bug Gittensor-scored bug fix — scores a 0.5x multiplier.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: resolveSegmentCommand returns an empty command for paren/brace-wrapped commands, bypassing shell-safety detectors

2 participants