Mail (webmail): a look at the security model, a few small suggestions
-
Hi @nebulon , I've been using the new Mail app on one of our Cloudrons for a few weeks and it has quickly become my daily driver: sign in once with Cloudron and every mailbox I have access to is right there. Before rolling it out to more users I read through the code that runs in the container (1.1.1) with security in mind. Short version: it's very nicely done. A few notes and small suggestions below.
What I really like
- No master credential. The app has no password for the mail server at all: it uses the user's own OIDC token with a dedicated
mailclientscope as the IMAP/SMTP/Sieve password, and the mail server checks per mailbox whether that token may access it. Even a bug in the app can't open a mailbox the user has no rights to. That is a better model than classic webmail, where the user types their mail password into the web app. - Login through Cloudron OIDC with PKCE and state, so Cloudron's 2FA applies automatically and nobody ever types a mail password into the webmail.
- Mail HTML is rendered in a sandboxed iframe without
allow-scripts, and the frame document gets its own CSP withscript-src 'none'. Two locks, either one is enough. - Remote images and other external content are blocked by default, with a per-sender/per-domain allowlist. Great for tracking pixels.
- Session cookie is
HttpOnlyandSameSite=Lax, and HSTS is on.
Small suggestions
- Tokens in the session store end up in backups. Sessions are kept by tegel's file store in
/app/data/.session.store, and each session file holds the access token, the refresh token (offline_access) and themailclienttoken in plain text, valid for 14 rolling days. Since/app/datais backed up, anyone with access to a backup (unencrypted backups are not unusual) could use those tokens until they expire or are revoked. Sessions are disposable, so the simplest fix might be to keep the session store outside the backup (e.g./runor a path excluded from backup) — after a restore users just sign in again. Encrypting the tokens at rest would also work. - The session cookie has no
Secureflag. tegel setssecure: process.env.NODE_ENV === 'production', andNODE_ENVis not set in the container. HSTS covers most of it, but settingNODE_ENV=production(together withtrust proxy, since TLS ends at nginx) would close it. - No CSP or frame protection on the app itself. The message frame has a strict CSP, but the main page sends no
Content-Security-Policyand noX-Frame-Options/frame-ancestors, so the webmail can be framed by another site (clickjacking). Aframe-ancestors 'self'would already help, and the app looks like it could live with a fairly strict CSP. - Minor, defence in depth:
sanitizeHtml()in MessageView only strips external content; scripts and event handlers stay in the HTML and are neutralised by the sandbox + CSP. That is fine as long as those stay in place; a DOMPurify pass would be a third lock if the frame setup ever changes.
A question about 1.2.0
1.2.0 mentions "token exchange authentication" and needs Cloudron 10.1.1, so I can't try it yet. Does it change what is kept in the session (e.g. no refresh token any more, or a short-lived exchanged token only)? If so, point 1 may already be (partly) solved.
Thanks for building this, it's a really pleasant client to use already.
- No master credential. The app has no password for the mail server at all: it uses the user's own OIDC token with a dedicated
-
Thanks for all the points! The next version has secure cookies set when deployed, as well as setting
frame-ancestores: noneby default (tegel change so our other apps also benefit from this).Regarding the tokens, the mailbox listing and mail password via the
mailclientscope got removed and the mail server now uses tokens whicih the mail app can get for a user via the cloudron app bridge (hence the new cloudron version requirement). This means nothing mail related ends up in the session store and the oidc related parts there are only for the login bits of the webui.For the last part about HTML sanitizing, we will have to do some more work on mail rendering and will look into that then.
-
N nebulon marked this topic as a question
-
N nebulon has marked this topic as solved
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better 💗
Register Login