GHSA-p8rw-8qj3-hf33
Omnigent: Unvalidated os_env.cwd in agent bundle yields arbitrary host filesystem access on runners without OMNIGENT_RUNNER_WORKSPACE
Quick fix
GHSA-p8rw-8qj3-hf33 — omnigent: upgrade to the fixed version with the command below.
pip install --upgrade 'omnigent>=0.3.0'Details
### Summary
An authenticated, non-admin user can obtain **arbitrary host-filesystem read/write** (and host environment-secret disclosure) on an Omnigent **runner** by uploading an agent bundle whose `os_env.cwd` points outside any intended workspace (e.g. `/` or `/home/<victim>`). The `cwd` field is taken **verbatim** from the bundle with no validation, normalization, or boundary check anywhere in the spec pipeline.
This is a **different sink** from GHSA-jrrm-9hc7-2v3h (CWE-94, shared-agent bundle overwrite -> stdio MCP RCE). It shares the bundle-upload *vector* but is reached through the user's **own** session-scoped agent and is **not** addressed by that advisory's proposed shared-agent guard.
### Preconditions
- Runner realizes a session-scoped uploaded bundle **without** `OMNIGENT_RUNNER_WORKSPACE` set. When that env var is set (CLI- and host-launched sessions set it), the spec `cwd` is overridden and the attack is neutralized — so this is deployment-gated, not universal. - Attacker is any authenticated user (no admin scope; `_require_user` only checks identity). No shared-agent overwrite needed.
### Details (verified against code)
1. **Parse — no validation.** `omnigent/spec/parser.py:696` stores `cwd=str(cwd_raw)` verbatim. Absolute paths (`/`, `/etc`), `../..`, etc. are all accepted. The `sandbox.type` is likewise author-chosen and `"none"` is legal. 2. **Validate — cwd unconstrained.** `omnigent/spec/validator.py` `_validate_os_env` checks only fork/scratch/egress combinations; it never references `cwd` (the sole mention, line ~526, is a comment). No boundary is applied to the cwd itself. The boundary in `server/schemas.py` validates a *caller-supplied workspace against* the spec cwd (treating the author cwd as trusted) and only for host-launched sessions — it does not bound the cwd. 3. **Sink.** `omnigent/inner/os_env.py:890` sets `cwd = Path(spec.cwd or os.getcwd()).resolve(strict=False)` as the environment root; `os_env.py:934` does `shutil.copytree(src=cwd, ...)` when `fork=true`. All agent file/shell tools are bounded by `_assert_within_cwd` (`os_env.py:1040`), which checks `resolved.relative_to(cwd)` — but since **cwd is attacker-controlled**, `cwd=/` makes the entire host filesystem in-bounds for read and write; `fork=true` with `cwd=/home/victim` copies that tree into the agent-readable workspace. 4. **Decisive gate.** `omnigent/runner/resource_registry.py:648-654`: `cwd = default_cwd` only when `self._runner_workspace is not None or spec_os_env.cwd in (None, ".", "./")`; otherwise `cwd = spec_os_env.cwd` (the attacker's absolute path). So `OMNIGENT_RUNNER_WORKSPACE` is the only thing standing between the spec and the host FS — and it is an operational control, not an in-code guard. A code comment at `tool_dispatch.py:~4207` claims cwd "is treated as a boundary at session-create time," which is not true on this path.
### Attack path
1. Authenticated user sends `POST /v1/sessions` (multipart) with an agent bundle whose `config.yaml` contains: ```yaml os_env: cwd: "/" # or /home/<victim>, with fork: true for one-shot exfil sandbox: { type: none } ``` 2. On a runner without `OMNIGENT_RUNNER_WORKSPACE`, the agent's `sys_os_read`/`write`/`edit`/`shell` tools now operate over the whole host filesystem, and (sandbox inactive) inherit the runner's full environment — exposing host secrets via e.g. `sys_os_shell("env")`.
### Impact
Arbitrary host-filesystem read/write and runner-environment secret disclosure, available to any authenticated user on an affected deployment. High severity (deployment-conditional).
### Suggested fix
Add a control on the `cwd` field itself in `omnigent/spec/_validate_os_env` (and/or at parse): reject absolute paths and `..` traversal, and require `cwd` to resolve within the runner workspace / an allow-listed root. Do not rely on `OMNIGENT_RUNNER_WORKSPACE` being set as the sole defense. Consider also disallowing bundle-author `sandbox.type: none` for server-realized (non-CLI) sessions.
### Related
GHSA-jrrm-9hc7-2v3h (same bundle-upload vector, different sink; that fix does not cover this).
Are you affected?
Enter the version of the package you're using.
Affected packages
References
- https://github.com/omnigent-ai/omnigent/security/advisories/GHSA-p8rw-8qj3-hf33[WEB]
- https://nvd.nist.gov/vuln/detail/CVE-2026-62677[ADVISORY]
- https://github.com/omnigent-ai/omnigent/pull/1417[WEB]
- https://github.com/omnigent-ai/omnigent/commit/7ca0cca3c9a65c04c489edf68f0e080424a26868[WEB]
- https://github.com/omnigent-ai/omnigent[PACKAGE]
- https://github.com/omnigent-ai/omnigent/releases/tag/v0.3.0[WEB]