Repository navigation
Security: Core RPC server uses wildcard CORS (Access-Control-Allow-Origin: *) #2262
Description
Summary
The in-process JSON-RPC HTTP server (src/core/jsonrpc.rs) sends Access-Control-Allow-Origin: * on every response, including authenticated /rpc calls. Combined with Access-Control-Allow-Headers: Content-Type, Authorization, any browser origin can issue authenticated cross-origin requests to the local RPC server if it possesses the per-launch bearer token.
Location: src/core/jsonrpc.rs:616-635 (with_cors_headers).
headers.insert(
header::ACCESS_CONTROL_ALLOW_ORIGIN,
HeaderValue::from_static("*"),
);Threat model
The bearer token (OPENHUMAN_CORE_TOKEN) is the only thing protecting /rpc. The token is generated fresh per launch and is intended to stay inside the Tauri webview and the Rust process. But there are realistic paths for a token to end up visible to another origin:
- A user pastes an error message or HAR file into a web tool / pastebin / chat.
- A third-party script loaded by a future feature reads it from memory and beacons it out.
- A debug session leaves the token in a screenshot, log share, or Sentry breadcrumb.
- A CEF child webview running a third-party origin (Slack, Gmail, etc.) is compromised by a malicious script. Because the wildcard ACAO permits any origin, that script can directly call the local RPC.
With wildcard CORS, possession of the token is sufficient from any origin in any browser. The token should also be bound to origins we actually ship.
For an agentic assistant the RPC surface includes shell tool calls, memory access, credential reads, and sending messages on the user's behalf — so the blast radius of unauthorized RPC access is high.
Proposed fix
Replace the wildcard with an explicit allowlist:
tauri://localhost(macOS / Linux Tauri v2 webview)http://tauri.localhostandhttps://tauri.localhost(Windows Tauri v2 webview)http://127.0.0.1:*,http://localhost:*,http://[::1]:*(Vite dev server, E2E harnesses)- Optional comma-separated env override
OPENHUMAN_CORE_ALLOWED_ORIGINSfor debug harnesses
The middleware echoes the request's Origin back in Access-Control-Allow-Origin only when it matches the allowlist; otherwise the header is omitted and the browser blocks the response. Vary: Origin is added so caches respect per-origin responses. Requests without an Origin header (curl, non-browser) are unaffected.
Acceptance criteria
- Cross-origin browser requests from any origin not on the allowlist are blocked (no
Access-Control-Allow-Originreturned). - The Tauri webview (
coreRpcClient.tsfetch path) continues to work on macOS, Linux, and Windows. pnpm dev(Vite athttp://localhost:1420) continues to work.- A unit test suite covers allowed Tauri origin, allowed localhost-with-port, disallowed origin, missing-origin request, and env-override.
Vary: Originis set so the response is not incorrectly cached across origins.
Other security issues I'm looking into
- Webhook signature / replay verification
- Moving the encryption master key to OS keychain.
- Prompt-injection enforcement vs. detection.
- The general dual-channel trust model for scraped third-party content.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsDone
Activity
Alexxigang commentedon May 20, 2026
I traced this to
with_cors_headersinsrc/core/jsonrpc.rs: it unconditionally emitsAccess-Control-Allow-Origin: *for both preflight and authenticated RPC responses. I am working on a fix that replaces the wildcard with an explicit origin allowlist (including Tauri + localhost dev origins), addsVary: Origin, and lands focused regression tests for allowed, disallowed, missing-origin, and env-override cases.leighstillard commentedon May 20, 2026
@Alexxigang sorry mate I just beat you to it
Alexxigang commentedon May 20, 2026
Update: I found active PR #2266 covering this issue and will not open a duplicate PR. I already validated the same root cause locally, but I am stepping back here and will move to another open issue instead.
fix(security): replace wildcard CORS on core RPC with origin allowlist
fix(security): replace wildcard CORS on core RPC
fix(security): replace wildcard CORS on core RPC with origin allowlist
fix(security): replace wildcard CORS on core RPC
fix(security): replace wildcard CORS on core RPC with origin allowlist
fix(security): replace wildcard CORS on core RPC
fix(security): replace wildcard CORS on core RPC with origin allowlist
fix(security): replace wildcard CORS on core RPC
fix(security): replace wildcard CORS on core RPC with origin allowlis…
fix(security): replace wildcard CORS on core RPC\n\n## Summary\n\n- R…