Skip to content

Security: icesixgod/codex-trajectory

Security

SECURITY.md

Security Policy

Supported versions

Security fixes are provided for the latest released version.

Reporting a vulnerability

Do not open a public issue for a vulnerability that may expose local task content or escape the authorized Codex session directories. Use GitHub's private vulnerability reporting for this repository. Include the affected version, platform, reproduction steps, and expected impact. You should receive an acknowledgement within seven days.

Security model

All user-facing trajectory and app-only live-update tools leave task logs untouched and accept session identifiers rather than file paths. The session-list tool writes a private derived index and correctly advertises readOnlyHint: false; its title contains up to 100 characters from the first prompt. Archives default to excluded, and full detail requires an explicitly selected session ID. They resolve each configured root, then use descriptor-checked reads for regular, single-link descendants below the active or archived root; descendant symbolic links/reparse points, file hardlinks, non-regular sources, root escapes, ambiguous ID prefixes, and inconsistent paginated lineage boundaries fail closed. Plain and Zstandard-compressed logical rollouts share byte, line, decompression-window, discovery, and lineage bounds. The byte budget defaults to 512 MiB; an explicit selected-task maxReadBytes can raise it to at most 64 GB without changing other bounds. The override is request-local, does not enlarge probes of unrelated logs, and participates in projection cache identity; the panel choice is not persisted. Size errors expose only byte counts, and raising the budget does not enable full details. Session and JSON-RPC inputs have byte, collection, nesting, and numeric conversion bounds; encoded JSON-RPC responses are capped at 8 MiB; public filesystem failures do not include local paths. The native entry resolves only an exact, validated per-request task identity within those same roots; missing or conflicting context opens a selector instead of another task. No app-only tool changes Goals or interrupts turns.

On POSIX, every path component is opened descriptor-relative with O_NOFOLLOW. Windows uses reparse-point rejection, pre/post component identities, regular/single-link fstat, and final HANDLE-path containment because Python does not expose an equivalent directory-relative no-reparse primitive. It does not yet use native NtCreateFile with a RootDirectory handle, so a theoretical same-user component-replacement race within an already authorized session root remains; the final HANDLE check still rejects a source whose opened object resolves outside that root.

Safe summary mode excludes raw inputs, outputs, metadata, base instructions, and encrypted reasoning. Full details remain bounded and still exclude base instructions and encrypted reasoning, but the plugin cannot protect content after a user explicitly loads those details into a Codex conversation. The viewer uses a restrictive Content Security Policy, escapes log-derived markup, and times out unanswered host requests.

The plugin contains no remote-debugging client, DOM injector, loopback viewer server, watcher, or task-control transport. Its native MCP Apps bridge accepts messages only from its parent host, consumes bounded theme color values, and cancels pending requests and polling on teardown. Besides the bounded derived search cache, app-only preference tools can persist explicit consent to default future panels to full details. The private, atomically written setting contains only a version and boolean, accepts at most 512 bytes, rejects linked/non-regular files, and defaults to summaries when absent or invalid. The viewer provides a revocation button. Public tool defaults and live windows remain summaries. Host context is not persisted.

There aren't any published security advisories