Hi — really like the project, it makes managing skills/agents much nicer.
While reading through the code I noticed a couple of defensive-hardening opportunities for the default deployment posture. Both are small, backwards-compatible changes that meaningfully reduce the attack surface for the common "running locally on a laptop" use case.
1. Default network bind
By default the server binds to 0.0.0.0 in three places:
bin/start.mjs:19 — process.env.HOST = process.env.HOST || '0.0.0.0'
Dockerfile:45 — ENV HOST=0.0.0.0
docker-compose.yml:9 — ports: - "3030:3030" (shorthand for 0.0.0.0:3030:3030)
This exposes the server (and the Claude Code sessions it spawns via node-pty) to anyone on the same LAN/Wi-Fi out of the box. For a tool that can run a PTY and an agent with shell access, that feels stronger-than-needed defaults.
Suggestion: default to 127.0.0.1 and let users opt in to wider exposure via the existing HOST env var. For docker-compose, change the port mapping to "127.0.0.1:3030:3030". No behavior change for the single-user, single-machine case.
2. WebSocket Origin / Host validation
Three WebSocket handlers accept the upgrade with no Origin/Host check:
server/api/cli/ws.ts (PTY spawner)
server/api/chat-ws/ws.ts
server/api/v2/chat/ws.ts
Without an Origin check, any page the user visits in the same browser can open ws://localhost:3030/api/cli/ws and drive the server — WebSockets are exempt from same-origin policy, so binding to localhost alone doesn't prevent this. A Host check additionally guards against DNS rebinding.
Suggestion: in the open hook of each WS handler, reject connections whose Origin isn't in an allowlist (default: http://localhost:<PORT>, http://127.0.0.1:<PORT>, http://[::1]:<PORT>). Same idea for Host. Allow operators to extend the lists via env vars for reverse-proxy setups.
Happy to help
I have working patches for both that I've tested end-to-end against current main. Happy to send them as a PR if you'd like — just say the word.
One more thing
I noticed the repo doesn't have private vulnerability reporting enabled. If you'd consider turning it on (Settings → Security → Private vulnerability reporting), I have a few more findings I'd like to share responsibly rather than through a public issue.
Thanks for the project!
Hi — really like the project, it makes managing skills/agents much nicer.
While reading through the code I noticed a couple of defensive-hardening opportunities for the default deployment posture. Both are small, backwards-compatible changes that meaningfully reduce the attack surface for the common "running locally on a laptop" use case.
1. Default network bind
By default the server binds to
0.0.0.0in three places:bin/start.mjs:19—process.env.HOST = process.env.HOST || '0.0.0.0'Dockerfile:45—ENV HOST=0.0.0.0docker-compose.yml:9—ports: - "3030:3030"(shorthand for0.0.0.0:3030:3030)This exposes the server (and the Claude Code sessions it spawns via node-pty) to anyone on the same LAN/Wi-Fi out of the box. For a tool that can run a PTY and an agent with shell access, that feels stronger-than-needed defaults.
Suggestion: default to
127.0.0.1and let users opt in to wider exposure via the existingHOSTenv var. For docker-compose, change the port mapping to"127.0.0.1:3030:3030". No behavior change for the single-user, single-machine case.2. WebSocket Origin / Host validation
Three WebSocket handlers accept the upgrade with no Origin/Host check:
server/api/cli/ws.ts(PTY spawner)server/api/chat-ws/ws.tsserver/api/v2/chat/ws.tsWithout an Origin check, any page the user visits in the same browser can open
ws://localhost:3030/api/cli/wsand drive the server — WebSockets are exempt from same-origin policy, so binding to localhost alone doesn't prevent this. A Host check additionally guards against DNS rebinding.Suggestion: in the
openhook of each WS handler, reject connections whoseOriginisn't in an allowlist (default:http://localhost:<PORT>,http://127.0.0.1:<PORT>,http://[::1]:<PORT>). Same idea forHost. Allow operators to extend the lists via env vars for reverse-proxy setups.Happy to help
I have working patches for both that I've tested end-to-end against current
main. Happy to send them as a PR if you'd like — just say the word.One more thing
I noticed the repo doesn't have private vulnerability reporting enabled. If you'd consider turning it on (Settings → Security → Private vulnerability reporting), I have a few more findings I'd like to share responsibly rather than through a public issue.
Thanks for the project!