JSXMail
Menu

Security

How JSXMail is built

Specific enough to check. If something here turns out not to match the product, we would rather you told us.

Account credentials

  • Passwords are hashed with Argon2id using OWASP-recommended parameters. Plaintext passwords are never stored, logged or transmitted anywhere but the login request itself.
  • Login uses a username, never your recovery email address. Knowing where someone recovers their account does not help an attacker find their login.
  • Sessions are opaque random tokens stored as SHA-256 digests. A database disclosure cannot be replayed as a live session, and any session can be revoked instantly.
  • Session cookies are HttpOnly and SameSite=Lax, with the Secure flag in production. Cross-site requests additionally require a double-submit CSRF token.
  • TOTP two-factor authentication with single-use recovery codes. TOTP secrets are encrypted at rest with AES-256-GCM.

Reading untrusted mail

  • Inbound HTML is sanitised before it is stored, not merely before it is displayed. Scripts, inline event handlers, javascript: and data: URLs, forms, iframes and embeds are removed.
  • Remote images are blocked by default so a tracking pixel cannot report that you opened a message. Loading them routes the request through a server-side proxy, so the sender never sees your IP address.
  • That proxy resolves every hostname and refuses private and link-local addresses, so a crafted image URL cannot be used to reach internal infrastructure.
  • Links in messages open with noopener, noreferrer and nofollow.

Attachments

  • Files are identified by their actual bytes, not by the sender-supplied name or content type. An executable announced as an image is rejected.
  • Every file is scanned with ClamAV. Until a scan completes the file cannot be downloaded — "not yet checked" is treated as unsafe rather than safe.
  • Attachments are stored in object storage under randomly generated keys, so one cannot be guessed or reached by manipulating a path.
  • Downloads are served with a forced attachment disposition and nosniff, so nothing renders in place unless it is a type we consider safe to preview.

Abuse and rate limiting

  • Registration, verification email requests, login attempts, password recovery, mailbox creation, sending and uploads are each rate limited independently, by IP and by account.
  • Sending quotas are enforced hourly, daily and monthly against durable counters, so clearing a cache cannot restore an allowance.
  • Bounce and complaint webhooks generate abuse events that moderators review. Sending can be suspended per account, per mailbox or per domain, and takes effect on the next request.
  • Password recovery responses are deliberately identical whether or not an account exists, and recovery addresses are shown masked.

Infrastructure

  • Application containers run as a non-root user with all Linux capabilities dropped and no-new-privileges set.
  • PostgreSQL and Redis are not published to the host. Only the reverse proxy accepts external connections.
  • The audit log is append-only, enforced by database triggers rather than by convention, so a compromised application account cannot rewrite its own history.
  • Secrets are supplied through the environment. None are stored in the repository, rendered in the admin interface, or written to logs — the logger redacts them as a backstop.

What we do not claim

  • JSXMail is not end-to-end encrypted. Message content is encrypted in transit and stored on encrypted disks, but the server can read it — that is what makes server-side search and spam filtering possible.
  • Administrators can see operational metadata about accounts. Reading message content requires a separate privileged permission held only by the highest role, and every such access is logged.
  • Email itself is not a confidential medium end to end. Mail leaving JSXMail is only as private as the receiving provider makes it.

Reporting a vulnerability

Email security@staff.jsxmail.com with steps to reproduce. We will confirm receipt within three working days. Please do not test against other people’s accounts or run automated scans that degrade the service for others.