Skip to content

Fix high-severity security and bug findings - #2244

Merged
kojiwakayama merged 17 commits into
mainfrom
fix/security-bug-review-2026-06
Jun 9, 2026
Merged

Fix high-severity security and bug findings#2244
kojiwakayama merged 17 commits into
mainfrom
fix/security-bug-review-2026-06

Conversation

@kojiwakayama

@kojiwakayama kojiwakayama commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Addresses the high-severity findings from the deep code review that are ready to ship now. This PR is release-prepared as 0.1.739 and includes the regenerated coding-agent template manifest.

Security

Bugs

Explicit non-closure

Verification

  • deno task verify:quick
  • deno run -A scripts/build/generate-templates-manifest.ts --check
  • git diff --check
  • Pre-push hook passed: format/lint/typecheck/unit suite, 2023 passed, 0 failed.
  • Hosted checks are being rerun after the 0.1.739 release/manifest repair.

@kojiwakayama kojiwakayama added bug Something isn't working performance Performance issues security Security vulnerability or hardening labels Jun 9, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1b6f8cd552

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread cli/templates/files/coding-agent/tools/read-file.ts Outdated
Comment thread src/modules/server/ssr-import-rewriter.ts Outdated
Comment thread src/security/sandbox/worker-script.ts Outdated
Confine read-file/edit-file to the project directory so traversal like
../../etc/passwd is rejected before any filesystem access. Closes #2226.
Validate every ctx.fs path against the project root before calling a Deno
API. In compiled-binary mode the worker has full read permission, so this
adapter is the only boundary stopping user route handlers from reading
arbitrary host files. Closes #2227.
Return a generic 500 body; the full error is already logged server-side
(SEC-009). Closes #2228.
Pad out-of-range positions with 0xff instead of 0x00 so a padded slot can
never coincide with a real 0x00 byte and read as a match. Closes #2229.
Run child graphs on a scoped DAGExecutor instead of mutating the shared
maxConcurrency field, which concurrent map nodes could race on and leave
permanently corrupted. Closes #2230.
Wrap the SSE/AG-UI read loops in try/finally so a read error or a throwing
event handler still releases the reader, instead of leaving the
ReadableStream locked and the response body leaked. Closes #2231.
Reject with a proper JsonRpcError instead of a plain object, matching every
other dispatch method. Closes #2232.
Default the rewritten-import cache buster to a content hash instead of
Date.now(), which produced a unique token per millisecond and defeated all
downstream module caching. Closes #2233.
Drop the entry when stat succeeds but the path is no longer a regular file,
so we don't re-stat and fall through to a full fetch on every lookup.
Closes #2238.
The security/bug-fix PR changes coding-agent template files and needs a Veryfront Code release bump after the 0.1.738 module-fetcher release landed on main. Regenerate the embedded template manifest so scaffolded coding-agent tools contain the path traversal guard, and keep the runtime version constant in sync with deno.json.

Constraint: veryfront-code PRs that create a release must patch deno.json and VERSION.

Constraint: Template source changes must keep cli/templates/manifest.json current.

Rejected: Keep deno.lock churn from verification | no dependency changed and the lockfile edits were Deno cache resolution noise.

Confidence: high

Scope-risk: narrow

Tested: deno task verify:quick

Tested: deno run -A scripts/build/generate-templates-manifest.ts --check

Tested: git diff --check
Deriving the cache buster from the importing module's source left a child
module stamped with the parent's hash, so a changed child kept serving stale
until the parent changed. Restore the prior per-request token; a correct
optimization needs per-target-module versioning stamped by the module
server. Reverts the #2233 change.
Canonicalize paths with Deno.realPath so a symlink inside the project that
points outside it is rejected rather than followed, and use relative() for
containment so valid child paths are accepted on Windows. Adds regression
tests for traversal and symlink escape. (#2227)
read:true lets compiled-binary route handlers bypass ctx.fs via direct
Deno.* calls. Point to the blocking follow-up (#2245) rather than implying
the ctx.fs guard closes it.
@kojiwakayama

Copy link
Copy Markdown
Contributor Author

Thanks for the review — addressed below.

Codex P1 — template manifest not regenerated: Fixed. The guarded read-file/edit-file contents are now embedded in cli/templates/manifest.json (regenerated; generate-templates-manifest.ts --check is green), so scaffolded projects actually get the traversal check.

Codex P2 / cache-buster transitive staleness: Agreed, this was a real regression — a child stamped with the parent's content hash kept serving stale when only the child changed. Reverted the content-hash cache buster back to the prior per-request token. A correct optimization needs per-target-module versioning stamped by the module server (which reads the actual file); tracked separately. ⚠️ Note: the Prepare security fixes for release 0.1.739 commit was cut while that change was still present — it's now reverted, so re-cut/verify before release.

Review #2 + Codex P3 — symlink + Windows guard weakness: Fixed in worker-script.ts. The guard now canonicalizes via Deno.realPath (a symlink inside the project pointing outside is rejected, not followed) and uses relative() for cross-platform containment. Added regression tests covering ../ traversal and symlink escape (worker-script.test.ts).

Review #1 (HIGH/BLOCK) — compiled-binary read: true lets handlers bypass ctx.fs via direct Deno.*: Acknowledged and not claimed as closed. This PR scopes the documented ctx.fs adapter and fully contains the non-compiled mode (read is already [projectDir] there). It is defense-in-depth only in compiled-binary mode. Narrowing read:true to a binary-validated allow-list (or removing direct Deno.* from user-module scope) can only be safely validated against the binary e2e job, so it's tracked as blocking follow-up #2245 and documented in-code at worker-permissions.ts. Issue #2227 wording updated to reflect the reduced scope.

If the reduced scope (defense-in-depth in compiled-binary mode, full containment elsewhere, with #2245 blocking) isn't acceptable, I'm happy to keep this blocked until #2245 lands with binary-CI evidence.

@kojiwakayama kojiwakayama changed the title Fix high-severity findings from deep code review (security, bugs, perf) Fix high-severity security and bug findings Jun 9, 2026
SerializedError isn't assignable to Record<string, unknown> directly; go via
unknown for the absence-of-cause assertion.
Cross-runtime (Deno/Node/Bun) canonicalizing path resolver, needed so
template tools can defeat symlink escapes without runtime-specific APIs.
read-file, edit-file and list-files now canonicalize the target via realPath
and reject anything outside the project root — closing both ../ traversal
(list-files had no guard at all) and symlink escapes (read/edit had only a
lexical check). Containment is separator-normalized for Windows. Manifest
regenerated so scaffolded projects get the guards. (#2226)
Keep the runtime export-surface guard in sync with the new realPath export.
@kojiwakayama

Copy link
Copy Markdown
Contributor Author

Round 2 blockers — all addressed.

1. Typecheck fail on worker-script.test.ts:140 (HIGH): Fixed. The SerializedError → Record<string, unknown> cast now goes via unknown (serialized as unknown as Record<string, unknown>). deno check src/security/sandbox/worker-script.test.ts is clean.

2. list-files.ts path traversal (HIGH): Fixed. It had no containment at all — added the same canonicalized guard as read/edit.

3. read/edit/list symlink escape (HIGH): Fixed. The template tools no longer use a lexical check. All three now canonicalize via a new portable realPath (resolves symlinks) and reject anything outside the canonical project root; containment is separator-normalized for Windows.

Supporting changes:

  • Added realPath to veryfront/fs (src/platform/compat/fs.ts, cross-runtime Deno/Node/Bun) since the template tools need symlink resolution without runtime-specific APIs, and updated the fs/index export-surface test.
  • Regenerated cli/templates/manifest.json so scaffolded projects receive all three guarded tools (--check green).

Verification: deno fmt --check, deno lint, deno check src/index.ts, and the full deno task test:unit (2024 passed) all green via the pre-push hook. generate-templates-manifest.ts --check is current.

Unchanged by design: compiled-binary read:true remains documented residual risk tracked in blocking follow-up #2245 (not narrowed without binary-e2e validation).

@kojiwakayama
kojiwakayama merged commit a0bbc5a into main Jun 9, 2026
20 checks passed
@kojiwakayama
kojiwakayama deleted the fix/security-bug-review-2026-06 branch June 9, 2026 21:29
kojiwakayama added a commit that referenced this pull request Jun 9, 2026
The second code-review batch bounds cross-project module fetches at 5MB. The fallback check needs to compare UTF-8 bytes rather than UTF-16 code units so sources without Content-Length cannot exceed the intended byte cap with non-ASCII text. This also prepares the rebased batch for release 0.1.740.\n\nConstraint: PR #2247 was rebased onto release 0.1.739 after #2244 merged.\nConstraint: veryfront-code release PRs must keep deno.json and VERSION in sync.\nRejected: Keeping deno.lock churn from local Deno verification | dependency-resolution metadata changed without a dependency update.\nConfidence: high\nScope-risk: narrow\nTested: deno test --frozen --allow-all src/modules/react-loader/ssr-module-loader/cross-project-import-loader.test.ts src/mcp/session.test.ts src/provider/runtime-loader.test.ts\nTested: deno check --frozen focused touched module set\nTested: deno task verify:quick\nTested: git diff --check
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working performance Performance issues security Security vulnerability or hardening

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant