Title: [Security][High] No authentication, wildcard CORS, 0.0.0.0 bind — plus Vite dev/preview on 0.0.0.0 with allowedHosts:true
Severity: High (CWE-942, CWE-306, CWE-346)
Locations: packages/server/src/index.ts:19-33; packages/client/vite.config.ts:15-24; packages/client/src/config.ts:17-20
Summary
The server runs with zero auth: app.use(cors()) reflects any Origin, and the listener defaults to 0.0.0.0:3357. On the client side, vite.config.ts binds dev AND preview servers to 0.0.0.0 and sets allowedHosts: true, which disables Vite's Host-header (DNS-rebinding) protection. src/config.ts derives API_BASE/WS_URL from window.location.hostname, so any host that can reach :3356 gets a fully functional GraphCoder client aimed at the victim's own API server.
Evidence
packages/server/src/index.ts:19-33:
const host = process.env.HOST ?? '0.0.0.0'
app.use(cors())
app.use(express.json())
app.use('/api', graphRouter) // ... no auth middleware anywhere
server.listen(port, host, ...)
packages/client/vite.config.ts:15-24: host: true / allowedHosts: true on both dev and preview.
Impact
- Any website the developer visits can read all API responses cross-origin (source code, git history, annotations) and issue state-changing calls (open project, create/delete annotations, trigger diffs) — CORS reflects their origin.
- Every LAN peer can do the same directly, including opening the client UI at http://:3356/?project= and reading rendered source in their own browser.
- With the Host check disabled, a DNS-rebound page is same-origin with the API and gets full read access.
Recommended fix
Default HOST to 127.0.0.1; make LAN exposure an explicit opt-in (HOST env); replace cors() with an explicit origin allowlist (localhost dev ports) or a shared-secret token header on /api and /ws; remove allowedHosts: true in favor of an explicit host list (or serve the client from the API server so page origin == API origin).
Title: [Security][High] No authentication, wildcard CORS, 0.0.0.0 bind — plus Vite dev/preview on 0.0.0.0 with allowedHosts:true
Severity: High (CWE-942, CWE-306, CWE-346)
Locations: packages/server/src/index.ts:19-33; packages/client/vite.config.ts:15-24; packages/client/src/config.ts:17-20
Summary
The server runs with zero auth:
app.use(cors())reflects any Origin, and the listener defaults to0.0.0.0:3357. On the client side,vite.config.tsbinds dev AND preview servers to0.0.0.0and setsallowedHosts: true, which disables Vite's Host-header (DNS-rebinding) protection.src/config.tsderivesAPI_BASE/WS_URLfromwindow.location.hostname, so any host that can reach :3356 gets a fully functional GraphCoder client aimed at the victim's own API server.Evidence
packages/server/src/index.ts:19-33:
packages/client/vite.config.ts:15-24:
host: true/allowedHosts: trueon both dev and preview.Impact
Recommended fix
Default HOST to 127.0.0.1; make LAN exposure an explicit opt-in (HOST env); replace
cors()with an explicit origin allowlist (localhost dev ports) or a shared-secret token header on /api and /ws; removeallowedHosts: truein favor of an explicit host list (or serve the client from the API server so page origin == API origin).