Skip to content

v1.34.2

Choose a tag to compare

@Arul- Arul- released this 07 Jun 07:00
· 63 commits to main since this release

Security Fixes

  • Path traversal (symlink escapes): Four routes — `/api/local-file`, `/api/template`, `/api/pwa/icon`, and UI sibling resolution — used lexical `path.resolve()` + `isPathWithin()` without resolving symlinks. A symlink under the allowed directory pointing outside it would pass the boundary check but serve the escaped target. Fixed with a two-phase check: lexical boundary first, then `fs.realpath()` + second boundary check.

  • Path traversal in `/api/browse`: Client-controlled `root` query parameter allowed setting the boundary to `/`, making `isPathWithin()` always true. Root is now derived server-side from the photon's workdir or `state.workingDir`. Also fixed a secondary issue where `fs.realpath(dirPath)` was called before the boundary check, leaking path existence via 500 errors on non-existent paths.

  • CORS wildcard hardening: Five endpoints were returning `Access-Control-Allow-Origin: *` — the webhook server, `/mcp` streamable transport, `/api/openapi.json`, and both OAuth AS endpoints. All now use `getCorsOrigin(req)` (localhost-only), consistent with the rest of the codebase.

  • Error message sanitization: Raw `err.message` was returned to clients on `/api/invoke`, `/api/create-photon`, `/api/test/list`, and four marketplace endpoints, potentially leaking internal file paths. Replaced with generic messages.

  • Rate limiting on file I/O: `/api/browse`, `/api/local-file`, `/api/ui`, `/api/template`, and `/api/pwa/icon` had no rate limiting. Added a 60 req/min limiter. `/api/test/run` (spawns subprocesses) now gates on the existing API rate limiter.

  • OPTIONS preflight: All `/api/*` routes now respond correctly to CORS preflight requests with `getCorsOrigin`-based headers.

Thanks to @sebastiondev (Foundation Machines) for the initial reports via automated CWE audits on PRs #4 and #5.