Skip to content

Security: linways/lwchat

SECURITY.md

Security policy

Reporting a vulnerability

Email sibin@linways.com with the details. Do not open a public GitHub issue — start in private and we'll coordinate disclosure once a fix is shipped.

Useful details to include:

  • A description of the vulnerability and its impact
  • Steps to reproduce
  • Your assessment of severity (critical / high / medium / low)
  • Whether you've already disclosed this elsewhere

We aim to respond within 3 business days.

Supported versions

Only the latest commit on main (and the latest tagged release) is supported. Older tags will not receive security fixes — pull the latest and re-install via ./install.sh update.

Scope — what counts as a vulnerability

In scope:

  • Anything that lets a third party read or modify a user's Google Chat data, Redmine data, or local ~/.lwchat/ state without their consent
  • Token-handling bugs (incorrect file permissions, refresh-token leakage, plain-text logging of tokens)
  • OAuth flow flaws — PKCE bypass, state confusion, CSRF on the loopback callback, accepting auth codes for a different code_challenge
  • Code-injection or path-traversal in lwchat commands or install.mjs
  • Anything that lets a forked install accidentally consume Linways's OAuth quota beyond what DEFAULT_CLIENT_ID overrides cover

Not in scope:

  • The bundled OAuth client_id and client_secret in lib/auth.js. This is deliberate. Google's OAuth policy for "Desktop app" client type explicitly treats the client_secret as non-confidential — it must be embedded in the binary for the flow to work, and Google's own doc says "the client_secret for installed applications is not" confidential. PKCE provides the real security boundary. See docs/DECISIONS.md ADR-015. gcloud CLI, gh CLI, doppler, supabase, and many others ship their client_secret the same way.
  • The "unverified app" OAuth warning — lwchat uses an Internal consent screen, so the warning only appears for users outside the Linways Workspace.
  • Vulnerabilities in third-party tools that lwchat installs symlinks into (Claude Code, Codex CLI, Copilot, Antigravity, Cursor) — report those upstream.
  • Reports generated by automated scanners against lib/auth.js's bundled secret without any other context. We're aware. See the ADR.

Security model summary

Surface Boundary
OAuth tokens (~/.lwchat/tokens.json) File mode 0600 — only the file owner can read
OAuth flow Loopback redirect URI (only a process on the same machine can complete) + PKCE RFC 7636, S256 (per-attempt verifier never leaves the lwchat process)
Posting to Chat (post, reply, dm) SKILL.md instructs agents to show resolved text before sending and to never post without explicit user permission
Local data Stored under ~/.lwchat/ only; never transmitted anywhere except the Google APIs the user explicitly authorized
Network egress Only Google's OAuth + Chat + People endpoints, plus Redmine if lwr is installed

Out-of-band contact

If sibin@linways.com is unreachable and the issue is genuinely time-critical, file a private GitHub Security Advisory at https://github.com/linways/lwchat/security/advisories/new.

There aren't any published security advisories