Security is our top priority. clsh provides remote terminal access to your machine. Any security vulnerability could mean full machine compromise. We treat every report with urgency.
Do NOT open a public GitHub issue for security vulnerabilities.
- Description of the vulnerability
- Steps to reproduce
- Potential impact
- Suggested fix (if you have one)
- 48 hours: We will acknowledge receipt of your report
- 7 days: We will triage the vulnerability and provide an initial assessment
- 30 days: We aim to release a fix for confirmed vulnerabilities
clsh is a remote shell tool, so we apply defense-in-depth at every layer:
- Bootstrap tokens: Single-use, 5-minute TTL, SHA-256 hashed in SQLite. Passed via URL hash fragment (never sent to server logs or proxy).
- Password auth: Server-side scrypt hashing (N=16384, r=8, p=1, 64-byte key, 16-byte random salt). Verification uses
crypto.timingSafeEqualto prevent timing attacks. - Biometric auth: WebAuthn with platform authenticator (Face ID / Touch ID).
userVerification: 'required'. Credential IDs stored server-side for cross-context restoration. - JWT: HS256 tokens with 30-day expiry. Authenticated via first WebSocket message (not URL query string).
- HTTPS: Enforced via ngrok SDK or SSH tunnel (localhost.run). Local Wi-Fi fallback warns about plain HTTP.
- CORS: Restricted to known origins (localhost, ngrok domains, tunnel URLs). No wildcard.
- Security headers: X-Frame-Options (DENY), X-Content-Type-Options (nosniff), Content-Security-Policy, X-XSS-Protection.
- Password/biometric login: 5 requests per 15 minutes per IP
- Bootstrap auth: 10 requests per 15 minutes per IP
- General API: Standard Express rate limiting
- Origin validation:
verifyClientcallback rejects cross-origin upgrade requests - Max payload: 64KB limit prevents memory exhaustion
- Resize bounds: Terminal dimensions clamped (cols: 1-500, rows: 1-200)
- Auth required: First message must be valid JWT or connection is terminated
- Face ID + password: Dual unlock methods, client-side WebAuthn + SHA-256 password verification
- Server-side sync: Biometric credentials and client password hashes stored server-side for PWA restoration (iOS PWAs get isolated localStorage)
- Auto-lock: Triggers on visibility change (tab switch, app background)
In scope:
- Authentication and authorization bypasses
- Token/session hijacking or leakage
- WebSocket security issues
- PTY escape or command injection
- Tunnel exposure issues
- Sensitive data leakage
- Password hash weaknesses
- Biometric auth bypasses
- Dependencies with known CVEs
Out of scope:
- Issues requiring physical access to the host machine
- Social engineering attacks
- Denial of service (the agent runs locally, single-user)
- Issues in third-party services (ngrok, localhost.run)
- Vulnerabilities in outdated versions (please update first)
| Version | Supported |
|---|---|
| Latest | Yes |
We appreciate responsible disclosure. With your permission, we will credit you in the release notes and in a SECURITY_ACKNOWLEDGMENTS.md file.
- Keep your
NGROK_AUTHTOKENprivate; never commit it to version control - Use a strong password (6+ characters) during lock screen setup
- Enable Face ID / Touch ID for quick, secure unlock
- Use a permanent ngrok domain with HTTPS for the safest remote access
- Run clsh on a trusted network when using local Wi-Fi fallback
- Keep Node.js and dependencies up to date