Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. 7 Skipped Deployments
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 64694656d5
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| ["get_symbols", "get_historical_price", "get_candlestick_data", "get_latest_price"].map( | ||
| (name) => [name, (arg: unknown) => hostCall(name, arg)], | ||
| ), |
There was a problem hiding this comment.
Prevent VM escape via host function constructors
The codemode methods are host-realm functions injected directly into untrusted execute code, which lets callers escape the sandbox by using a function constructor chain (for example codemode.get_symbols.constructor("return process.env")()). In the public Code Mode endpoint this gives arbitrary access to process, environment variables (including PYTH_PRO_ACCESS_TOKEN), and host capabilities, so token injection is no longer isolated to server-side code.
Useful? React with 👍 / 👎.
apps/mcp/src/codemode/executor.ts
Outdated
| const result = await runInNewContext(wrapped, sandbox, { | ||
| timeout: timeoutMs, | ||
| }); |
There was a problem hiding this comment.
Enforce execution timeout for unresolved async code
The timeout passed to runInNewContext only limits synchronous script execution; if user code returns a never-settling promise (for example await new Promise(() => {})), await runInNewContext(...) can hang indefinitely. Because execute accepts untrusted code, this allows callers to pin requests and degrade service capacity despite the configured timeoutMs.
Useful? React with 👍 / 👎.
| : JSON.stringify(result.result); | ||
| const resultSizeBytes = Buffer.byteLength(resultText); |
There was a problem hiding this comment.
Handle undefined execute results before byte-length logging
When executed code does not explicitly return a value, result.result is undefined, so JSON.stringify(result.result) also returns undefined; passing that into Buffer.byteLength throws a type error and turns an otherwise valid execution into an internal failure. This is easy to trigger with common snippets that omit return, so execute should normalize undefined results before logging/response construction.
Useful? React with 👍 / 👎.
Document a Cloudflare-first Code Mode path so API evolution does not require frequent MCP tool reshaping. Capture token-injection security and observability requirements to guide rollout.
- Add codemode executor (isolated-vm, 30s timeout, no network) - Add codemode bindings: search, execute, get_latest_price (token-injected) - Add createServerCodeModeOnly and pyth-mcp-codemode entrypoint - Add pythProAccessToken config and PYTH_PRO_ACCESS_TOKEN env - Add redact utils and logger serializers for token/sensitive data - Add unit, integration, and security tests for Code Mode Made-with: Cursor
Simplify search tool (remove code execution path), include full types in execute description, fix redactSecrets false positives on keys like author/authority/token_count, extract shared setupProcessCleanup in server.ts, complete return types in types.ts, and add sandbox boundary tests for timeout/process/require. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…sults
- Sever prototype chain on injected host functions to prevent sandbox
escape via .constructor("return process")()
- Race vm execution with a timer so never-settling promises also respect
the configured timeoutMs
- Normalize undefined results before Buffer.byteLength to avoid TypeError
when user code omits a return statement
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
Rationale
How has this been tested?