galaxyproject / galaxyproject/loom

exec-guard bash classifier: more safe-allowlist commands read/exec outside the workspace

Open
#259 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
TypeScript
Stars
14
Forks
12
Avg merge
6d 5h
Merged PRs (30d)
17

Description

Follow-up to #224 / #250. While hardening the bash enumeration jail in #250, an adversarial review of `extensions/loom/exec-guard/bash-risk.ts` surfaced several *other* ways a safe-allowlisted bash command still reaches outside the workspace without prompting. #250 closes the bare `ls/find/stat/du/wc/file ` gap plus quote-stripping and `df`; these are separate and predate it. Listed roughly worst-first.

### 1. `git diff --no-index` dumps arbitrary external file content
`git diff`, `git show`, `git log` are auto-safe via `SAFE_PREFIXES`, but the classifier's `cmd` stays `git` (not in `PATH_READING`), so no path operands are collected and the command is allowed outright:

```
git diff --no-index /etc/passwd /etc/hosts # prints both files' full contents as a diff
git show HEAD:/etc/passwd # (within a repo) arbitrary blob read
git log /some/external/path
```

This is arbitrary file-content exfiltration through an auto-safe prefix -- strictly worse than the metadata leak #224 reported. Options: drop the `git` prefixes from the auto-safe set, or parse them conservatively (treat any non-flag operand as a read path, and reject `--no-index`).

### 2. `find`/`fd` `-exec`/`-x` is arbitrary execution classified as safe
`find` and `fd` are in `SAFE_COMMANDS`, and `-exec ... {} +` / `-x ...` contain no `SHELL_META`, so they classify `safe`:

```
find ~/.ssh -type f -exec cat {} + # dumps key contents; sensitiveReadPaths is empty (find isn't READ_LIKE)
fd -x cat ~/.ssh/id_rsa
```

These get at most a `read:escape` ask (not the credential-store hard-deny), and auto-allow outright if the target sits inside a configured workspace root. `-exec`/`-x` is really arbitrary command execution wearing a safe verb -- the guard should force any `find`/`fd` carrying `-exec`/`-execdir`/`-ok`/`-x`/`-X` to `unknown` (ask).

### 3. Unexpanded shell variables bypass the jail
`SHELL_META` catches `$(` and `${...}` but not bare `$VAR`, and the path resolver only expands `~`/home forms:

```
ls $PWD/.. # guard resolves literal "$PWD/.." under cwd (inside); shell reads the parent at runtime
cat $PWD/../.ssh/config # can walk out of the workspace AND past the credential-store hard-deny
```

The guard reasons over the literal string while the shell expands `$PWD`/`$HOME`/`$OLDPWD` at exec time. Either expand the common read-only vars before resolving, or treat a `$`-containing operand as untrusted (ask).

### 4. Attached path-valued options are dropped
The `!t.startsWith("-")` filter discards `--opt=value`, so options whose value is an external file slip through with no path collected:

```
grep --file=/etc/passwd needle . # reads patterns FROM /etc/passwd
rg --file=/etc/passwd needle .
wc --files0-from=/etc/passwd
du --files0-from=/etc/passwd
file --files-from=/etc/passwd
fd --ignore-file=/etc/passwd pattern .
```

Recognize the handful of path-valued long options and collect their `=`-attached (and space-separated) values into `readPaths`.

### Root cause
Most of the above trace to the same thing: the classifier uses a naive whitespace split + prefix match rather than a real shell lexer, and the safe-allowlist trusts a verb without fully accounting for its argument grammar. Worth considering a small conservative lexer, or a "if any operand looks unmodelled, fall to ask" backstop, instead of widening the allowlist case by case.

### Notes
- The policy floor ordering itself is sound: sensitive-read floor, then the workspace-jail `readPaths` loop, then the safe-allow -- so the fix for each of these is to make sure the relevant operand reaches `readPaths` (or to force the command to `unknown`), no `policy.ts` change required.
- All repros classify `safe` today on the #250 branch; verified by probing `classifyBash` directly.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in extensions/loom/exec-guard/bash-risk.ts and inspect classifyBash, SAFE_PREFIXES, SAFE_COMMANDS, PATH_READING, and readPaths. Reproduce the listed commands with classifyBash directly, then verify that git path operands, find/fd execution flags, variable-containing operands, and attached path-valued options are no longer classified as safe. Confirm the existing policy.ts ordering needs no change.

Written by the indexing model from the issue text.

Assessment

Tech stack
bash, git, typescript
Domain
cli, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.