Skip to content

fix(security): harden against shell injection, command execution, and timing attacks#193

Open
mattalvaro wants to merge 3 commits intocloudflare:mainfrom
mattalvaro:security-hardening
Open

fix(security): harden against shell injection, command execution, and timing attacks#193
mattalvaro wants to merge 3 commits intocloudflare:mainfrom
mattalvaro:security-hardening

Conversation

@mattalvaro
Copy link

Summary

  • [CRITICAL] Validate requestId before shell interpolation in device approval to prevent command injection
  • [CRITICAL] Add command prefix allowlist to /debug/cli endpoint — only clawdbot, node --version, ls, ps, etc. are permitted
  • [HIGH] Add WebSocket rate limiting (100 msg/s) and message size cap (1MB) on client-to-container relay
  • [HIGH] Hash gateway token fingerprint with SHA-256 instead of storing plaintext prefix
  • [HIGH] Tighten trustedProxies from 0.0.0.0/0 to localhost only (127.0.0.0/8, ::1/128)
  • [HIGH] Log [SECURITY WARNING] when DEV_MODE bypasses auth alongside CF Access config
  • [MEDIUM] Add structured audit logging (src/utils/audit.ts) for auth, device approval, gateway restart, storage sync, and debug commands
  • [MEDIUM] Remove per-request console.log lines that leaked env var presence
  • [MEDIUM] Support Authorization: Bearer header for CDP auth (query param still works as fallback); refactor 4 duplicated auth checks into shared helper
  • [MINOR] Fix timingSafeEqual to not leak secret length via early return on length mismatch

Test plan

  • rm -rf dist && npm run build passes with zero TypeScript errors
  • Dashboard still connects and WebSocket chat works normally
  • Test shell injection: POST /api/admin/devices/foo;curl+evil.com/approve returns 400
  • Test debug CLI: /debug/cli?cmd=rm+-rf+/ returns 403
  • Test debug gateway-api: /debug/gateway-api?path=../../etc/passwd returns 400
  • Verify gateway still accepts proxy connections after tightening trustedProxies
  • Verify CDP auth works with both Authorization: Bearer header and ?secret= query param

🤖 Generated with Claude Code

mattalvaro and others added 3 commits February 7, 2026 07:42
The clawdbot gateway authenticates at the WebSocket application protocol
level, not via HTTP headers. sandbox.wsConnect() does not forward custom
headers, so token injection via Authorization headers or query params
never worked. The fix:

- Enable gateway.controlUi.allowInsecureAuth to bypass device pairing
- Add gateway.trustedProxies to trust all proxy connections
- Pass CLAWDBOT_GATEWAY_TOKEN env var for LAN binding requirement
- Remove unused addGatewayAuthHeader, use addGatewayAuthToken (no-op)
- Add preview_urls: false to wrangler.jsonc (Durable Objects compat)
- Add token change detection to gateway version fingerprinting

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… timing attacks

Address 10 vulnerabilities from security audit:
- Validate requestId before shell interpolation in device approval (critical)
- Add command allowlist to debug CLI endpoint (critical)
- Add WebSocket rate limiting (100 msg/s) and message size cap (1MB)
- Hash gateway token fingerprint with SHA-256 instead of storing prefix
- Tighten trustedProxies to localhost only in start-moltbot.sh
- Warn when DEV_MODE bypasses auth alongside CF Access config
- Add structured audit logging for security events
- Remove per-request env var logging that leaked config info
- Support Authorization: Bearer header for CDP auth, refactor duplicated checks
- Fix timingSafeEqual to not leak secret length on mismatch

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant