-
Notifications
You must be signed in to change notification settings - Fork 0
Comparing changes
Open a pull request
base repository: rammie/rsh
base: 0.0.4
head repository: rammie/rsh
compare: 0.0.5
- 11 commits
- 12 files changed
- 2 contributors
Commits on Mar 25, 2026
-
Fix sandbox escape via post-expansion absolute paths and harden edge …
…cases - Executor's check_expanded_arg_path now rejects absolute paths (critical: command substitution like `cat $(realpath file)` could read arbitrary files) - Block sed -i/--in-place via PREFIX_BLOCKED when sed is added to allowlist - Glob expansion skips paths that fail canonicalize() instead of including them - Tilde expansion rejected in executor as defense-in-depth (validator already blocks) Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for bc9dee5 - Browse repository at this point
Copy the full SHA bc9dee5View commit details -
Extract shared check_arg_path_safety to deduplicate path checks
The validator and executor had near-identical path safety checks (absolute path + traversal rejection). Unified into a single pub function in validator.rs that both call sites now use. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for 9fe8c29 - Browse repository at this point
Copy the full SHA 9fe8c29View commit details -
Validate parameter expansion sub-expressions and implement &> redirects
Fix critical security issue: command substitutions inside parameter expansion sub-expressions (e.g., ${var:-$(cmd)}, ${var:+$(cmd)}, ${var/$(cmd)/repl}) were not validated, allowing arbitrary command execution bypassing the allowlist. The validator now parses and validates all sub-expression strings (default values, alternative values, error messages, patterns, replacements, array indices) for command substitutions and variable references. Also implement &> and &>> redirect execution (previously passed validation but was silently ignored), and document symlink traversal as a non-goal. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>Configuration menu - View commit details
-
Copy full SHA for bd43e88 - Browse repository at this point
Copy the full SHA bd43e88View commit details -
Harden validator: path-check redirects, cap for-loops, validate subst…
…ring exprs, reject ${:=} Four security hardening fixes: - Validator now calls check_arg_path() on redirect target filenames, catching absolute paths and .. traversal before any process spawns (executor had this as defense-in-depth, but validator should enforce it too) - For-loop iterations capped at 10,000 (matching while/until loops) - ${var:offset:length} offset/length arithmetic expressions now validated for command substitutions and variable references - ${var:=default} (AssignDefaultValues) rejected as variable assignment Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>Configuration menu - View commit details
-
Copy full SHA for 9120b9f - Browse repository at this point
Copy the full SHA 9120b9fView commit details -
Hard-block awk/sed, validate arithmetic expressions, track $? exit st…
…atus, extract loop constant - Add ALWAYS_BLOCKED list: awk/gawk/mawk/nawk/sed/gsed are rejected even with --allow, since their built-in commands (system(), e, r, w) bypass rsh's security model. Remove sed from PREFIX_BLOCKED (now fully hard-blocked). - Validate arithmetic expressions ($((expr))) for embedded command substitutions - Track $? (last exit status) in local_vars so conditionals like `false || echo $?` work correctly - Extract MAX_LOOP_ITERATIONS constant shared by for/while/until loops - Update docs and tests Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for 042d19d - Browse repository at this point
Copy the full SHA 042d19dView commit details -
Fix concatenated short-flag path bypass, remove less from allowlist, …
…execute stderr redirects in pipelines - Harden check_arg_path_safety to inspect values concatenated after short flag letters (e.g., -f../../secret), closing an information disclosure vector via grep -f, rg -f, file -f, etc. - Remove less from default allowlist — its interactive escape capabilities (pipe to commands, open editor) are unsafe; still available via --allow. - Execute stderr redirects (2>/dev/null, 2>&1) on non-final pipeline commands instead of silently ignoring them. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for bc04bb6 - Browse repository at this point
Copy the full SHA bc04bb6View commit details -
Fix blocked-flag bypass via expansion, hard-block shells/interpreters…
…/env/xargs Critical fix: blocked flags (find -delete/-exec, sort -o, fd --exec) could be injected via command substitution (e.g., `find . $(echo -delete)`) or for-loop variables, bypassing validation-time checks. The executor now re-checks blocked flags on expanded args and re-validates the expanded command name against the allowlist and ALWAYS_BLOCKED. - Add check_blocked_flags() and check_command_allowed() as shared public functions used by both validator and executor (deduplicated from prior private methods) - Hard-block shells (sh, bash, zsh, dash, ksh, csh, tcsh, fish), subprocess launchers (env, xargs), and interpreters (python, python3, perl, ruby, node) even with --allow - Add 17 new tests covering expansion bypass vectors and hard-blocked commands Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for bf65c96 - Browse repository at this point
Copy the full SHA bf65c96View commit details
Commits on Mar 26, 2026
-
Move path checking from validator to executor, making executor the se…
…curity boundary The validator now does structural AST checks only (allowlist, blocked flags, forbidden syntax, variable approval, redirect gating). All path checking (absolute paths, .. traversal) happens post-expansion in the executor, where it operates on actual expanded strings rather than raw Word.value text. This eliminates a long tail of edge cases from trying to statically analyze bash's dynamic string construction (parameter expansion variants, command substitution output, etc.). The executor already re-validates command names, blocked flags, and argument paths after expansion — this change makes that the single source of truth for value-based security checks. Changes: - validator: remove check_arg_path calls (args, for-loop values, redirects) - executor: add validate_redirect_target helper for post-expansion path checks - executor: reject unsupported parameter expansions instead of silent empty string - executor: add ParameterLength support, remove redundant absolute path check from apply_redirects - docs: update CLAUDE.md and README.md to explain validator vs executor roles Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for 114f842 - Browse repository at this point
Copy the full SHA 114f842View commit details -
Pin allowlist at compile time, remove --allow flag and ALWAYS_BLOCKED
The --allow flag, RSH_ALLOWLIST env var, and ~/.rsh/allowlist config file created a whack-a-mole problem: any binary that can exec (shells, scripting languages, xargs, env, etc.) had to be individually blocklisted. Instead, pin the allowlist at compile time so only explicitly listed commands can run — no runtime override possible. - Remove --allow CLI flag, RSH_ALLOWLIST env var, ~/.rsh/allowlist config - Remove ALWAYS_BLOCKED list (no longer needed without --allow) - Simplify Allowlist::load(cli_allow) to Allowlist::new() - Add printf and printenv to pinned allowlist (read-only, useful for testing) - Consolidate duplicate "not in allowlist" tests with shared helper Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for 0813ecb - Browse repository at this point
Copy the full SHA 0813ecbView commit details -
Fix blocked-flag bypass via combined short-flag clusters (fd -Hx, sor…
…t -ro) Single-letter blocked flags like fd's -x/-X and sort's -o could be hidden inside combined short-flag clusters (e.g., -Hx, -ro, -nro) which bypassed both exact-match and prefix-match checks. fd -Hx is particularly critical since fd's -x spawns arbitrary commands outside rsh's sandbox. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for 1045483 - Browse repository at this point
Copy the full SHA 1045483View commit details -
Add built-in restricted sed for safe line extraction
Implement sed as an in-process builtin that only supports -n with address+p (e.g. sed -n '10,20p' file). No sed binary is executed, eliminating the risk of sed's e (execute), w (write), s///e, and -i features. Supports single lines, ranges, $ (last line), multiple expressions via semicolons or -e, multiple files, and stdin pipelines. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for dd89ce3 - Browse repository at this point
Copy the full SHA dd89ce3View commit details
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff 0.0.4...0.0.5