← 回到四專案比較

獨立審查 · 完整回覆

Orca

Orca · Claude Code · 讀取安全程式碼

2026-10-227a06b6579 ↗僅讀公開網路

確切題目

Is there a security risk in installing this tool? Read the security-related code in this repository and understand its encryption and data transmission mechanisms before answering. If a mechanism cannot be verified from the accessible code, say so.
題目附帶的固定版本連結 ↗

下方完整保留 agent 原始回覆,原文語言有明確標示。中文導讀是編輯整理,不是原文,也不是驗證結論。審查沒有執行安裝或攻擊測試。

中文導讀(編輯整理)

確認 v2 relay 加密、同意後遙測及機密保護儲存;提醒 QR 憑證存續時間與舊版 v1 的不確定性。

實際閱讀範圍:約 35 個桌面/共用安全檔案;未讀手機 app 或私有後端。

下載完整英文原文 · SHA-256 ff9601031e278d614399c6dfd51589787adcd52360a893aab600e8bcab075cb7

完整英文原始回覆(未翻譯)

Security assessment: Orca at commit 7a06b65

Bottom line: I found no sign that this is malicious or that it quietly sends your data somewhere. The mobile-relay encryption, telemetry and local secret storage are reasonably well built. The real risk comes from what the tool is for: it gives AI agents, and optionally a paired phone, broad control of your machine as your user account. If you turn on mobile pairing, the QR code effectively hands someone remote control of your computer.

How I reviewed it: I read about 35 security-relevant files on GitHub at this commit. I had no local clone, so each file went through a fetch tool that summarizes the page with a smaller model. I didn’t run grep across the whole repo or read every line myself, so treat this as a targeted review, not an audit.

Verified from the code

Phone ↔ desktop encryption (v2 protocol). The relay server can’t read your traffic.

  • Key exchange: the desktop has an X25519 keypair (via the tweetnacl library, src/main/runtime/e2ee-keypair.ts). Its public key is in the pairing QR code, and the phone checks it during the handshake, so the relay can’t swap in its own key.
  • Session keys: derived with HKDF-SHA256 from the shared secret, a random 32-byte value from each side, and a hash of the handshake. Each direction gets its own key (src/shared/mobile-e2ee-v2-node-key-schedule.ts).
  • Messages: encrypted and authenticated with nacl.secretbox. Each message carries a sequence number, and the desktop only accepts the next expected one, so replayed or reordered messages are rejected (mobile-e2ee-v2-framing.ts, mobile-e2ee-v2-desktop-session.ts).
  • Device login: the phone’s device token is sent inside the encrypted channel, after the handshake (mobile-e2ee-auth-validation.ts).

Relay design. Per the cloud/ README, both devices connect out to the relay, which forwards frames between them. With the encryption above, it only sees ciphertext plus metadata such as timing, sizes and IDs.

Local network listener. The WebSocket server is plain ws:// with no TLS, relying on the encryption layer above. It starts on loopback (127.0.0.1) and only opens to all network interfaces when you generate a LAN/QR pairing offer (runtime-rpc-network-exposure.ts). On Windows, a firewall rule is created only through an explicit “repair” action with a UAC prompt. It applies to Private networks but doesn’t restrict remote addresses.

Telemetry. It goes to PostHog (us.i.posthog.com) and is consent-gated: nothing is sent until you choose (src/main/telemetry/consent.ts).

  • It sends app version, OS, a persistent install ID and a session ID, with event fields checked against a schema. GeoIP lookup is turned off in the SDK.
  • DO_NOT_TRACK=1 or ORCA_TELEMETRY_DISABLED=1 disables it, and so does any CI environment.
  • Source and dev builds send nothing because there’s no write key.

Secrets at rest. Settings secrets (proxy URL, OpenCode cookie and similar) are encrypted with Electron’s safeStorage, which uses the OS keychain. If encryption isn’t available, they aren’t written in plaintext (protected-secret-persistence.ts). The E2EE private key itself is stored as plain base64 JSON. Its file is written atomically and locked to your user (0600 on macOS/Linux, ACLs on Windows; src/shared/secure-file.ts).

Weaknesses and caveats

  1. The QR code is a long-lived credential. It contains the device token, the desktop public key, the address to connect to, and the relay details (runtime-rpc-mobile-pairing.ts). In src/shared/pairing.ts I found no expiry and no one-time-use check. Anyone who photographs it can pair.
  2. A paired phone has wide powers. Allowed actions include terminal.send, terminal.create, agent.launch, files.read, git.push, github.mergePR and ssh.connect. That is effectively shell access as your user.
  3. The old v1 protocol is still accepted by default. The requireV2 flag defaults to false (rpc/e2ee-channel.ts). v1 has no handshake binding and no visible replay protection. I couldn’t confirm whether production builds turn requireV2 on.
  4. Minor: the device token is checked with ===, not a constant-time comparison. This happens inside the encrypted channel, so the impact is low.
  5. Inherent to the tool: it runs coding agents with your full user permissions and offers “Computer Use” for desktop apps. Treat agent output and any repo you point it at as untrusted.

What I couldn’t verify

  • Relay auth and back end: the API and auth services are in a private repo (stablyai/orca-cloud), so server-side behavior and what it logs can’t be checked.
  • Binaries vs. source: whether the released DMG, EXE, AppImage, Homebrew and AUR builds match this source, and how the auto-updater checks signatures. I didn’t read updater.ts in depth.
  • Mobile app: I didn’t review mobile/.
  • Linux keychain: whether a weak safeStorage backend (such as basic_text) is rejected.
  • Electron hardening: renderer settings (sandbox, contextIsolation, CSP) and the Design Mode and embedded-browser code.

Recommendations

  • If you don’t need the phone app, don’t pair. The listener then stays on loopback.
  • If you do pair, treat the QR code like a password and revoke devices you no longer use. Prefer “This computer only” or relay mode over LAN exposure on untrusted networks.
  • Set DO_NOT_TRACK=1 or decline the telemetry prompt if you want zero analytics.
  • Install from the official release or Homebrew cask and check the code signature.
  • Run agents only on repos you trust.
← 回到比較表