Skip to content

Harden local API and filesystem security boundaries#203

Open
imxyanua wants to merge 1 commit into
agegr:mainfrom
imxyanua:main
Open

Harden local API and filesystem security boundaries#203
imxyanua wants to merge 1 commit into
agegr:mainfrom
imxyanua:main

Conversation

@imxyanua

Copy link
Copy Markdown

Summary

Pi Web exposes local agent, filesystem, Git, model, plugin, skill, credential, and session operations through browser-accessible API routes. The existing implementation trusted lexical paths and did not reject cross-site browser requests, which allowed browser-origin attacks and symlink or junction escapes from approved workspaces. Large uploads and chat image attachments were also unbounded.

This PR adds a shared browser-origin gate, canonical filesystem authorization, consistent workspace checks across dependent routes, bounded upload and image handling, and regression coverage.

Root Cause

  • API routes relied on the application being used locally but did not enforce same-origin browser access. Browser requests from another site could reach sensitive local endpoints.
  • Workspace authorization compared normalized path strings before filesystem operations. Filesystem APIs resolve symbolic links and Windows junctions afterward, so a lexically contained path could resolve outside an allowed root.
  • Several model, plugin, skill, Git, and worktree routes accepted cwd or file paths without applying the same canonical workspace boundary.
  • File uploads and base64 chat image attachments had no explicit count or byte limits.
  • A bash-output regression test hardcoded POSIX /tmp paths and failed on Windows despite correct production behavior.

Changes

Security

  • Added a Next.js API proxy that rejects browser requests with a cross-site Fetch Metadata signal or a mismatched Origin.
  • Preserved non-browser API clients that do not send browser origin metadata.
  • Added realpath-based containment checks that resolve symlinks and Windows junctions before authorization.
  • Applied canonical workspace checks to file reads and indexing, Git status and diff, model discovery, plugin operations, skill listing/install/update/check, skill metadata writes, and worktree operations.
  • Preserved access to global skills managed inside the Pi agent directory.

Resource Limits

  • Limited individual filesystem uploads to 25 MiB.
  • Limited each upload request to 100 MiB total.
  • Limited chat attachments to 10 images and 10 MiB per image before base64 conversion.

Tests

  • Added regression coverage for same-origin and cross-origin browser requests.
  • Added a symlink/junction escape regression test.
  • Updated bash-output path tests to use platform-native temporary paths.

Verification

  • Full Node test suite: 99/99 passing in three independent full runs during the audit, plus a final post-commit run.
  • Focused security and path regression tests: passing.
  • TypeScript type checking with npx tsc --noEmit: passing in repeated runs, including post-commit verification.
  • ESLint with npm run lint: passing in repeated runs, including post-commit verification.
  • Production build with npm run build: passed three independent times with isolated build-time HOME and USERPROFILE, plus a final branch build.
  • Package dry run: valid npm artifact containing the CLI and .next build output; 454 entries, 5,333,998 compressed bytes, 29,142,590 unpacked bytes.
  • Branch verification: four focused commits, zero commits behind origin/main, no generated artifacts or secret-like files included.

Relevant tests were executed multiple times to verify deterministic behavior.

Breaking Changes

None.

Remaining Risks

  • The CLI still inherits Next.js default binding to 0.0.0.0 when no hostname is supplied. The API origin gate mitigates cross-site browser access but does not provide authentication for direct LAN clients. Default localhost binding or explicit authentication remains recommended follow-up work.
  • npm audit --omit=dev reports two high and two moderate production advisories in transitive sharp, postcss, and protobufjs dependencies. No compatible clean upgrade was available during this audit.
  • On this Windows environment, a normal build using the real user profile can fail when Pi SDK package/resource discovery traverses protected profile junctions. The same source builds successfully with isolated build-time home variables.
  • The repository has no browser end-to-end suite, so UI interaction coverage remains primarily unit, static, and build validation.
  • The npm artifact is approximately 5.3 MiB compressed and 29.1 MiB unpacked; packaging optimization remains separate follow-up work.

* fix(api): reject cross-origin browser requests
* fix(security): enforce canonical workspace boundaries
* fix(ui): bound chat image attachments
* test(files): use portable temporary paths
---------
Co-authored-by: EvoX <evox@evomap.ai>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant