Skip to content

Security: solarssk/mail-autodiscover

SECURITY.md

Security Policy

This document is for maintainers and admins who need the detailed security model behind mail-autodiscover.

If you are looking for setup help, start with README.md and the in-repo docs/ guides.

What this service is allowed to do

mail-autodiscover may return mail client configuration for allowed domains.

It may not:

  • verify that a mailbox exists,
  • expose internal domain lists on the public landing page,
  • act as an admin panel,
  • connect to LDAP, IMAP, Synology APIs, or user databases to validate an email address.

Those limits are intentional. They keep the service small and reduce the risk of mailbox enumeration.

Core security property: no mailbox enumeration

For every syntactically valid address in an allowed domain, the service returns the same configuration shape.

That means the service must not reveal whether alice@example.com exists while bob@example.com does not. Any future feature that checks mailbox existence would break the project's main security guarantee.

Trust boundaries

[Mail clients: Outlook, Thunderbird, Apple Mail]
        │ HTTPS
        ▼
[Reverse proxy: TLS termination, optional rate limiting]
        │
        ▼
[mail-autodiscover container]

Public endpoints

  • GET /health
  • GET /ready
  • GET /
  • GET /robots.txt
  • GET /favicon.ico
  • GET /apple-touch-icon.png
  • GET /mail/config-v1.1.xml
  • GET /.well-known/autoconfig/mail/config-v1.1.xml
  • GET /mail/ios.mobileconfig
  • GET /.well-known/apple-mail.mobileconfig
  • POST /autodiscover/autodiscover.xml
  • GET /autodiscover/autodiscover.xml

There is no admin API in the current version. Configuration comes from environment variables or an optional mounted YAML file.

Data handling

Data Logged? Notes
Full email addresses No Logs include only domain_allowed=true/false and a hashed domain prefix
Request XML body No Request bodies are never logged
Client IP Yes Stored in the unified access log as client_ip=
IMAP/SMTP hosts Returned to clients Comes from ENV or mounted YAML config, not from a user database

Built-in mitigations

  • Safe XML parsing with defusedxml
  • Request body size limit
  • XML output escaping via html.escape
  • Log-injection prevention: X-Request-ID and URL paths are restricted to safe characters before any log write (X-Request-ID: alphanumerics plus ._-; paths: control chars, whitespace, and = replaced)
  • Rate limiting per IP with RATE_LIMIT_PER_MINUTE and bounded in-memory storage
  • Security headers: nosniff, no-referrer, X-Frame-Options: DENY, Cache-Control: no-store, Content-Security-Policy, Permissions-Policy, and Strict-Transport-Security (when PUBLIC_BASE_URL uses https://)
  • Neutral error responses that do not expose your domain list
  • Non-root container user
  • CI security checks with gitleaks, bandit, pip-audit, Trivy, and CodeQL

Deployment requirements

  1. Run the service behind an HTTPS reverse proxy.
  2. Enable TRUST_PROXY_HEADERS=true only when requests really come through a trusted proxy.
  3. Set TRUSTED_PROXY_IPS or FORWARDED_ALLOW_IPS to your own proxy or Docker bridge CIDRs.
  4. Keep ALLOWED_DOMAINS limited to domains you actually operate.
  5. Do not expose the container directly to the public internet without TLS.
  6. In production, pin GHCR images by semver tag or digest instead of using latest.
  7. With APP_ENV=production, the service refuses to start on placeholder values (example.com, mail.example.com, http://localhost, missing TRUSTED_PROXY_IPS when proxy trust is on).
  8. Do not run multiple uvicorn workers (--workers N or Gunicorn multi-process) without an external rate-limiter. The built-in rate limiter is in-process only; with N workers the effective per-IP limit becomes N × RATE_LIMIT_PER_MINUTE.

Reverse proxy logging

Thunderbird Autoconfig and Apple Mail profile URLs include ?emailaddress=user@example.com in the query string. Mail clients require this parameter.

This service does not log full email addresses, but your reverse proxy may log the full request URI unless you configure it otherwise. Review access-log settings for paths such as /mail/config-v1.1.xml, /.well-known/autoconfig/, and /mail/ios.mobileconfig.

Apple Mail profiles

.mobileconfig profiles are generated without a code-signing certificate. iOS and macOS warn that the profile is unsigned before installation. That is expected for self-hosted mail setup.

Profile identifiers are stable per mailbox so users can re-download and update the same profile instead of accumulating duplicates.

What not to add casually

Changes in the list below need a deliberate security review because they would alter the trust model:

  • mailbox existence checks,
  • public endpoints that query LDAP, IMAP, or Synology APIs,
  • user-specific routing logic,
  • a public page that exposes internal hostnames or allowed domains,
  • forwarded-header trust without explicit proxy restrictions.

Vulnerability disclosure

Please open a private security advisory instead of a public issue:

Create a private advisory

Include:

  • a short description of the issue,
  • steps to reproduce,
  • expected impact,
  • an optional suggested fix.

There aren't any published security advisories