Repository navigation
Security Model
Anton Popov edited this page Nov 10, 2026
·
1 revision
- The login cookie contains the credentials encrypted with AES-256-GCM under the server key, so sessions survive restarts without a database. Deleting
secret.keysigns everyone out. The cookie isHttpOnly; SameSite=Strict(andSecurein production). - Open IMAP connections live in memory per session and are closed after 10 minutes idle.
- Mutating API calls require a custom header (CSRF protection).
- Rate limits: login attempts per IP, password-reset requests and every code check.
- Secrets at rest are encrypted: extra-account passwords, S/MIME private keys and passkey sign-in copies are tied to the user's own password (or the server key); the files alone are useless. Decrypted S/MIME mail is never cached.
- No shell: the password command, the ManageSieve client and openssl run with fixed argument lists, never through a shell. User text that reaches a Sieve script or a certificate request is validated and escaped first.
- HTML mail is sanitised (DOMPurify) and rendered in a sandboxed, script-less iframe with its own CSP; remote content is blocked by default.
- Extra accounts: user-entered servers must be public hosts on standard mail ports (no access to the server's private network).
- Administration: the helper command decides who may do what on every call, see Administration.
- A webmail that holds your credentials while you are signed in is a trust decision: run it on a server you control.
Reporting a problem: please open an issue on GitHub, or contact the maintainer privately for anything security sensitive.
goodmail
Using it
Security
Running it