You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Reject dangling symlinks in workspace file operations #446
On the official v1.93.4 source behavior, the workspace resolver treated a dangling symlink as a nonexistent path. The later write followed that link and created a synthetic file outside the workspace through both LocalProcessSandbox::write and the host-side file API used by DockerSandbox::write.
This is a host-side workspace file-jail bypass in the file API. It is not a Docker container escape and did not demonstrate an outside-workspace shell command. The relevant path is crates/biorouter-sandbox/src/lib.rs, canonicalize_existing_ancestor.
Current status
A source change on the local codex/security-reviewer-assessment branch detects and rejects dangling symlinks. The component regression checks both file APIs and verifies that outside canaries remain unchanged. The branch is not merged or released. Concurrent replacement of a checked path has not been addressed.
Recommendation
Use directory-handle-relative file operations that prevent symlink traversal and concurrent path replacement, with a cross-platform implementation. Keep the existing workspace file interface and clear path-escape error so routine research use remains unchanged.
Defensive audit remediation update (local source branch; not released)
The path fix now covers the shared sandbox resolver, the public developer editor, diff-selected child paths, and explicitly user-created remembered directory grants. Review also found that diff overlap handling could widen containment to the workspace parent; the resolved target is now checked against the original base before the patch library creates directories.
Verified post-change:
Sandbox host-side file APIs: three replays of the eight-case set, with all 21 negative observations denied and all three normal controls allowed; no outside writes.
Public editor: three replays of 11 checks, with all 21 unsafe-path observations denied and all 12 normal-use observations allowed; no outside files or directories created. Controls include ordinary direct writes, nested diff creation, a valid workspace-prefixed diff, and an existing internal symlink via direct write.
Public scope regression rejects unresolved symlinks while preserving a normal new-file grant.
The initial sandbox dangling-link finding was reproduced at baseline. Additional editor routes were found through source review and tested after remediation; these were not all separately replayed against the original release. A DockerSandbox host-side file-API failure is not a container escape.
Recommendations preserving convenience: retain the current editor/file APIs, supported nested paths and overlap-prefixed patches, and clear errors for rejected paths. For a stronger architecture, use directory-handle-relative opens and creation rather than a separate pathname check followed by open. Concurrent path replacement remains unassessed and is not solved by this narrow validation patch. File-API checks do not establish containment of LocalProcessSandbox commands, which run as the host account.
Status: source changes and focused regressions are complete locally on codex/security-reviewer-assessment (base f73ebf74c578717a7af64b221e57358a63dda8e3). No merge or fixed distribution is claimed. Leaving this issue open for maintainer review and integration.
Two linked follow-ups now define how to preserve cross-folder convenience while strengthening the boundary:
External folder access: ask for scoped permission and resume file operations #424 consolidates the external-folder requirement: pause a legitimate operation, ask the user for access to the specific folder with explicit scope/duration, then resume that pending action after approval. A user-resolvable missing grant should not become a generic terminal error or silently skipped task.
Anchor file operations to authorized directory handles #452 proposes actual file I/O anchored to authorized directory handles, with staged migration of reads, writes, patch child targets, and undo, plus Unix/Windows compatibility review. This addresses concurrent path substitution beyond the selected dangling-link/patch-path cases covered by the current local audit fixes.
These are separate implementation proposals, not additional completed audit results. Folder authorization determines which roots are permitted; handle-backed execution determines how operations safely use them. Preserve supported normal editing and internal-link workflows; do not silently broaden authority or bypass a denial through another tool.
Historical desktop/browser/CLI observations used f227 artifacts, accepted via the reviewed production-equivalence comparison; exact-main CI/build/smoke is attributed separately below.
Problem. Missing-target/ancestor handling let some structured host file operations create files outside the workspace through dangling symlinks.
Fix and UX.Bounded binding validates link traversal and missing ancestry, captures actual parents and refuses unsafe missing link targets. The host sandbox check and structured editor paths use the strengthened boundary; #452 addresses validation/open substitution. Normal nested creation/internal links remain supported. A legitimate external target can use #424 consent and resume, including approved dangling-target creation.
Validation. Preserved baseline: six outside writes among 24 file-API observations. The initial corrected stream had 21 expected refusals/three legitimate controls in 24 observations; the separate editor stream had 21 unsafe-path refusals/12 legitimate controls. These are distinct cohorts. Final local sandbox controls 25 and folder-authority 14 passed; current Windows bounded-file integration passed 18/18. Final native evidence includes captured-target retargeting, refusal/canary checks and legitimate authorized external writes, within the 81-pair cohort. Current macOS CI supplies separate compatibility tests.
Limits. The finding involved host file APIs, including DockerSandbox host-side file methods; it was not a demonstrated container escape. No unrestricted shell/computer containment, arbitrary network-filesystem guarantee or pooled attack-success rate is established.
Recommendation. Route future file operations through the shared bounded layer and retain ordinary nested/internal-link controls alongside escape regressions.
Merged-main verification.PR454 is merged at 0580110; main Rust CI, frontend CI and related checks finished 20 successes/one skipped (17 push successes plus three landing/deployment checks; these are not security-test counts). Normal main build manifest SHA256: 38cc2979c7da104cb623975bac7f6922a085e834a1be5c18e961d7f26ea811fc; shipping receipt: e6e1d8957d8d0b22a9aae814011a1e028c5d279848ffabbf4c6d0c4edf3c0112. Actual main01 smoke separately recorded four pairs—three reads/one typed Deny—and three unchanged canaries; it does not rerun/recount the historical 81-pair cohort.
Submission record. Manuscript v1.1 local Supplementary Data S1: Supplementary Data S1 - BioRouter Security Audit - 2026-10-24.zip; manifest SHA256 4f0c0c110ca0b07a29d5281870227f7b36c744a0f37ccb499b8ef1283dea116e. This is a user/submission package, not a claim of public upload. Public PR/source/CI links above provide the public implementation proof.
Activity
Broccolito commentedon Oct 23, 2026
Defensive audit remediation update (local source branch; not released)
The path fix now covers the shared sandbox resolver, the public developer editor, diff-selected child paths, and explicitly user-created remembered directory grants. Review also found that diff overlap handling could widen containment to the workspace parent; the resolved target is now checked against the original base before the patch library creates directories.
Verified post-change:
The initial sandbox dangling-link finding was reproduced at baseline. Additional editor routes were found through source review and tested after remediation; these were not all separately replayed against the original release. A DockerSandbox host-side file-API failure is not a container escape.
Recommendations preserving convenience: retain the current editor/file APIs, supported nested paths and overlap-prefixed patches, and clear errors for rejected paths. For a stronger architecture, use directory-handle-relative opens and creation rather than a separate pathname check followed by open. Concurrent path replacement remains unassessed and is not solved by this narrow validation patch. File-API checks do not establish containment of LocalProcessSandbox commands, which run as the host account.
Status: source changes and focused regressions are complete locally on
codex/security-reviewer-assessment(basef73ebf74c578717a7af64b221e57358a63dda8e3). No merge or fixed distribution is claimed. Leaving this issue open for maintainer review and integration.Broccolito commentedon Oct 24, 2026
Two linked follow-ups now define how to preserve cross-folder convenience while strengthening the boundary:
These are separate implementation proposals, not additional completed audit results. Folder authorization determines which roots are permitted; handle-backed execution determines how operations safely use them. Preserve supported normal editing and internal-link workflows; do not silently broaden authority or bypass a denial through another tool.
Broccolito commentedon Oct 24, 2026
Issue #446: Reject dangling symlink workspace escapes
Issue · Host PR #454 · merged main source
Historical desktop/browser/CLI observations used f227 artifacts, accepted via the reviewed production-equivalence comparison; exact-main CI/build/smoke is attributed separately below.
Problem. Missing-target/ancestor handling let some structured host file operations create files outside the workspace through dangling symlinks.
Fix and UX. Bounded binding validates link traversal and missing ancestry, captures actual parents and refuses unsafe missing link targets. The host sandbox check and structured editor paths use the strengthened boundary; #452 addresses validation/open substitution. Normal nested creation/internal links remain supported. A legitimate external target can use #424 consent and resume, including approved dangling-target creation.
Validation. Preserved baseline: six outside writes among 24 file-API observations. The initial corrected stream had 21 expected refusals/three legitimate controls in 24 observations; the separate editor stream had 21 unsafe-path refusals/12 legitimate controls. These are distinct cohorts. Final local sandbox controls 25 and folder-authority 14 passed; current Windows bounded-file integration passed 18/18. Final native evidence includes captured-target retargeting, refusal/canary checks and legitimate authorized external writes, within the 81-pair cohort. Current macOS CI supplies separate compatibility tests.
Limits. The finding involved host file APIs, including DockerSandbox host-side file methods; it was not a demonstrated container escape. No unrestricted shell/computer containment, arbitrary network-filesystem guarantee or pooled attack-success rate is established.
Recommendation. Route future file operations through the shared bounded layer and retain ordinary nested/internal-link controls alongside escape regressions.
Merged-main verification. PR454 is merged at
0580110; main Rust CI, frontend CI and related checks finished 20 successes/one skipped (17 push successes plus three landing/deployment checks; these are not security-test counts). Normal main build manifest SHA256:38cc2979c7da104cb623975bac7f6922a085e834a1be5c18e961d7f26ea811fc; shipping receipt:e6e1d8957d8d0b22a9aae814011a1e028c5d279848ffabbf4c6d0c4edf3c0112. Actual main01 smoke separately recorded four pairs—three reads/one typed Deny—and three unchanged canaries; it does not rerun/recount the historical 81-pair cohort.Submission record. Manuscript v1.1 local Supplementary Data S1: Supplementary Data S1 - BioRouter Security Audit - 2026-10-24.zip; manifest SHA256 4f0c0c110ca0b07a29d5281870227f7b36c744a0f37ccb499b8ef1283dea116e. This is a user/submission package, not a claim of public upload. Public PR/source/CI links above provide the public implementation proof.