UnisonTalk doesn't yet follow a formal versioning/release cycle. Security
fixes are applied to the main branch — please make sure you're running the
latest commit before reporting an issue.
Please don't open a public GitHub issue for security vulnerabilities.
Instead, report it privately using one of these methods:
- Preferred: open a private security advisory on GitHub.
- Or contact the maintainer, Alireza Asakareh (RealUnfazed), directly through the contact details on the GitHub profile.
Please include:
- A description of the vulnerability and its potential impact
- Steps to reproduce it (a minimal example is ideal)
- Any suggested fix, if you have one
You should expect an initial response within a few days. Once a fix is available, it'll be released and you'll be credited in the release notes unless you'd prefer otherwise.
A few things worth knowing if you're evaluating this project for production use, since it started as a learning/reference implementation:
- This app has two kinds of conversation with very different guarantees — Cloud Chats and Secret Chats. See the "Cloud Chats vs. Secret Chats" and "Security model" sections in README.md before assuming anything about what's protected. Cloud Chats (the default) are encrypted at rest with a server-held key (
CLOUD_ENCRYPTION_KEY— seeserver/utils/fieldCrypto.js) but fully readable by the running application, same as Slack or Discord — that's expected, not a bug, and it's what makes cross-device sync work with no client-side key. Only Secret Chats are end-to-end encrypted, where the server has no key at all, and that comes with its own disclosed, honest list of limits (no forward secrecy, no safety-number verification, no multi-device sync, no group support). None of this is hidden — it's documented scope. CLOUD_ENCRYPTION_KEYmust be generated and kept safe before deploying with real data. It's what makes a MongoDB dump alone insufficient to read Cloud Chat messages — but losing it, or committing it to source control alongside your database backups, defeats the purpose entirely. Keep it in a proper secrets manager for anything beyond local development, and back it up somewhere durable: losing the key makes existing Cloud Chat messages permanently unreadable, with no recovery path.- For Secret Chats, encryption/decryption happen entirely client-side. The server (
server/) and MongoDB never have the key for these at all — a database compromise or a subpoena for stored data does not expose Secret Chat contents, regardless of what else is compromised on the server. It also doesn't protect against a compromised client (malicious browser extension, XSS, a device someone already has physical access to), which exposes exactly what that user could already read, same as any E2EE app. - Session cookies are configured for local development by default (see
.env.exampleandserver/app.js). Review the cookiesecure/sameSitesettings and setALLOWED_ORIGINbefore deploying publicly. - There's no built-in rate limiting on login, registration, or message sending.
- If Phasetime SSO is configured (see README's "Phasetime SSO" section — it's optional),
PHASETIME_CLIENT_SECRETdeserves the same care asSESSION_SECRET/CLOUD_ENCRYPTION_KEY: it's what lets the server exchange an authorization code for an access token, and it never touches the browser. Treat it as a real credential — don't commit it, don't log it, keep it in a proper secrets manager beyond local development. Accounts created via SSO have no local password at all (by design — seeserver/controllers/ssoController.js), so anyone with access to a Phasetime identity that's linked to a UnisonTalk account can sign in as that account; this is the expected trust relationship of using SSO, not a bug, but it does mean the security of a linked account is only as strong as the Phasetime instance it's linked to. - Attachment files are served directly from
server/uploads/(seeserver/middleware/upload.js) — Secret Chat attachment bytes are ciphertext there and are fetched via a JSON API rather than a direct file URL (see the README's Secret Chat section for why), but the files themselves aren't encrypted at rest the way message text and filenames are. Cloud Chat attachment files are plain there too. Either way, you'd want a dedicated storage service with proper access controls and backup/retention policies for production.