# Audit Issues
> Active issue backlog for current `oy-cli` code. Fixed historical findings were removed after the amended 0.8.0 validation pass.
## Findings summary
| 1 | Partially mitigated | High | Audit input can disclose unskipped secret-like repository files to the model provider | `src/audit/input.rs::collect_files`, `src/audit/input.rs::should_skip_path`, `src/audit.rs::run` |
| 2 | Open | High | PATH-based `gh` / `aws` discovery can execute attacker-controlled binaries | `src/agent/auth.rs::gh_auth_token`, `src/agent/bedrock.rs::aws_cli_available` |
| 3 | Open | Medium | Terminal escape sequences from repo/model/tool output are printed unsanitized | `src/cli/ui.rs::out`, `src/cli/ui/render.rs::markdown`, `src/cli/ui/progress.rs::tool_result` |
| 4 | Open | Medium | Workspace/private file writes have symlink TOCTOU windows | `src/cli/config/paths.rs::resolve_workspace_output_path`, `src/cli/config/paths.rs::write_workspace_file`, `src/cli/config/paths.rs::write_private_file` |
## Detailed findings
### 1. Audit input can disclose unskipped secret-like repository files to the model provider
- **Status:** Partially mitigated.
- **Severity:** High
- **Category:** Data exposure / unsafe file collection, OWASP ASVS V8/V13
- **Trust boundary / sink:** Local repository files → model-provider prompt.
- **Validated evidence:** `src/audit/input.rs::collect_files` collects reviewable files and `src/audit.rs::run` sends chunked file contents to `session::run_prompt_once_no_tools(...)`. `src/audit/input.rs::should_skip_path` skips `.env.*` plus filenames containing `credential`, `secret`, or `token`, with regression coverage for `credentials.json` and `secrets.yaml`.
- **Residual impact:** This is still not fail-closed. Secret-bearing files with unrecognized names can still be included if not ignored by gitignore and if their extension is reviewable.
- **Exploitability / preconditions:** User runs `oy audit` in a repository containing secret-bearing files not skipped by gitignore or the hardcoded denylist.
- **Fix:** Add an explicit sensitive-file policy: conservative default skips for common cloud/kube/service-account credential paths, clear audit transparency about skipped sensitive files, and an explicit `--include-sensitive`/`--include-hidden` opt-in with tests.
### 2. PATH-based `gh` / `aws` discovery can execute attacker-controlled binaries
- **Status:** Open.
- **Severity:** High
- **Category:** Process execution from untrusted PATH, OWASP ASVS V12/V14
- **Trust boundary / sink:** User environment / current workspace `PATH` → implicit `Command::new(...)` execution.
- **Validated evidence:** `src/agent/auth.rs::gh_auth_token` runs `Command::new("gh").arg("auth").arg("token").output()`. It is reached through GitHub/Copilot token discovery paths. `src/agent/bedrock.rs::aws_cli_available` runs `Command::new("aws").arg("--version")`.
- **Impact:** If `PATH` resolves `gh` or `aws` to an attacker-controlled binary, ordinary model/auth/status discovery can execute arbitrary code with the user’s permissions, outside the tool approval flow.
- **Exploitability / preconditions:** User’s `PATH` contains the workspace or another attacker-writable directory before the real CLI binary.
- **Fix:** Do not auto-run external CLIs during discovery. Require explicit approval, use configured absolute paths, or use SDK/env credential lookup. At minimum, resolve the binary path first and refuse relative or workspace-contained executables.
### 3. Terminal escape sequences from repo/model/tool output are printed unsanitized
- **Status:** Open.
- **Severity:** Medium
- **Category:** Output encoding / terminal injection, OWASP ASVS V7
- **Trust boundary / sink:** Repo file contents, shell/web output, or model text → terminal stdout/stderr.
- **Validated evidence:** `src/cli/ui.rs::out` / `err` print raw strings. `src/cli/ui/render.rs::markdown`, `diff`, and `numbered_block` render raw content lines. `src/cli/ui/progress.rs::tool_result` prints preview lines directly. `src/cli/ui/text.rs::truncate_width` accounts for ANSI width but does not strip or escape control sequences.
- **Impact:** Malicious content containing OSC/CSI/control sequences can clear or spoof the terminal, create deceptive hyperlinks, alter window title, or set clipboard contents when previewed or rendered.
- **Exploitability / preconditions:** User views model/tool/repo output from a malicious repository, fetched page, or command output in a terminal supporting these sequences.
- **Fix:** Sanitize untrusted text at the UI boundary. Allow only ANSI sequences generated by the renderer; escape or replace C0/C1 controls, CSI, OSC, and BEL/ST-terminated sequences in model/tool/repo-originated strings. Keep generated styling separate from untrusted content so sanitization does not strip `oy`'s own color output.
### 4. Workspace/private file writes have symlink TOCTOU windows
- **Status:** Open.
- **Severity:** Medium
- **Category:** Filesystem race / symlink write, OWASP ASVS V12
- **Trust boundary / sink:** Workspace/output path controlled by user/model/local repo state → file write with user permissions.
- **Validated evidence:** `src/cli/config/paths.rs::write_workspace_file` checks `reject_symlink_destination(path)`, creates parents, then opens with `OpenOptions::create(true).write(true).truncate(true)`. `resolve_workspace_output_path` validates existing ancestors but stops at the first missing component. `write_private_file` uses similar create/truncate behavior for private state.
- **Impact:** A concurrent local attacker controlling the workspace can replace the checked path or a newly-created ancestor with a symlink after validation and before open, redirecting writes outside the workspace.
- **Exploitability / preconditions:** Attacker can modify the workspace concurrently during output or replacement writes. For a local single-user CLI this is mainly a hardening issue, but it matters for shared workspaces and untrusted repositories.
- **Fix:** Use race-safe opens: `O_NOFOLLOW` for the final component on Unix, create/open ancestors relative to directory file descriptors with no-follow checks, and revalidate parent directories after creation. Apply equivalent symlink rejection to private config/session writes.