Plugin-owned servers run unsecured; secured servers cannot be used (H-02)
Surfaced by the gpt-5.6-sol final review, verified locally against OpenCode 1.17.15 (server prints Warning: OPENCODE_SERVER_PASSWORD is not set; server is unsecured.).
spawnServerProcess() (server-lifecycle.mjs) launches opencode serve without generating OPENCODE_SERVER_PASSWORD, and OpencodeServerClient (opencode-server.mjs) never sends an Authorization header on any path (fetch requests, fresh-connection requests, health checks, SSE). Any local process that can reach the loopback port gets full API access (file content, sessions, lifecycle). Conversely, if a user already exports OPENCODE_SERVER_PASSWORD, the spawned server requires auth the client never sends, so the plugin breaks.
Also verified: POST /global/dispose returns true but does not stop the HTTP listener (/global/health keeps answering), so teardown that relies on dispose alone leaves an orphaned unsecured server; PID termination must remain part of teardown.
Fix:
- Generate a strong random password per plugin-owned server; pass it only to the server process and client.
- Add HTTP Basic auth to all four request paths (normal, fresh-connection, health, SSE).
- Store credential-bearing runtime state owner-only; redact credentials from status/log output.
- Support explicit credentials for an external server, or reject a password-protected external server with a precise message.
Tests: unauthenticated HTTP and SSE calls rejected; authenticated normal/fresh/health/SSE calls work; status and logs never reveal credentials.
Source: gpt-5.6-sol final review H-02 (opencode-plugin-cc-analysis.md).
Plugin-owned servers run unsecured; secured servers cannot be used (H-02)
Surfaced by the gpt-5.6-sol final review, verified locally against OpenCode 1.17.15 (server prints
Warning: OPENCODE_SERVER_PASSWORD is not set; server is unsecured.).spawnServerProcess()(server-lifecycle.mjs) launchesopencode servewithout generatingOPENCODE_SERVER_PASSWORD, andOpencodeServerClient(opencode-server.mjs) never sends anAuthorizationheader on any path (fetch requests, fresh-connection requests, health checks, SSE). Any local process that can reach the loopback port gets full API access (file content, sessions, lifecycle). Conversely, if a user already exportsOPENCODE_SERVER_PASSWORD, the spawned server requires auth the client never sends, so the plugin breaks.Also verified:
POST /global/disposereturnstruebut does not stop the HTTP listener (/global/healthkeeps answering), so teardown that relies on dispose alone leaves an orphaned unsecured server; PID termination must remain part of teardown.Fix:
Tests: unauthenticated HTTP and SSE calls rejected; authenticated normal/fresh/health/SSE calls work; status and logs never reveal credentials.
Source: gpt-5.6-sol final review H-02 (
opencode-plugin-cc-analysis.md).