3.5 KiB
3.5 KiB
Security
Model
- Devices authenticate with Basic Auth (required by the protocol) - always behind TLS (reverse proxy). The password is verified by logging in to IMAP and is passed to SMTP/DAV only within the same request. It is never stored. The successful login cache keeps only HMAC-SHA256(login, password) with a random key generated at process start.
- The IMAP pool keeps authenticated connections keyed by the same HMAC - a connection is only reused for a request with identical credentials.
- The panel is a separate listener (loopback by default; another address requires explicit consent).
Administrator passwords: argon2id. Session: random 256-bit token in an
HttpOnly; SameSite=Strictcookie (Secureover HTTPS); only its SHA-256 is stored. Every modifying request needs the CSRF header. The first administrator can only be created with a one-time token from the CLI (valid 60 minutes). - Panel headers: strict CSP (
script-src 'self', no inline code),X-Frame-Options: DENY,nosniff,Referrer-Policy: no-referrer, COOP.
Abuse protection
- Lockout after
auth_fail_maxfailures per account and3xper IP within the window; HTTP 429 withRetry-After. Other accounts from the same IP keep working until the IP limit is reached. - fail2ban friendly log line:
authentication failed user=jan@example.com ip=203.0.113.7 service=activesync# /etc/fail2ban/filter.d/active-push.conf [Definition] failregex = authentication failed user=\S+ ip=<HOST> service= journalmatch = _SYSTEMD_UNIT=active-push.service - Panel: 5 failed logins in 10 minutes lock the IP for 15 minutes; constant verification cost even for unknown accounts.
- Limits: request size (
sync.max_request_mb), attachments, messages, WBXML depth and element count, IMAP response size, timeouts on every backend operation, HTTP header read timeout. - Unknown ActiveSync command names are counted as
Unknown(no unbounded metric labels). - XML (Autodiscover, WebDAV) is parsed without DTD/entities (XXE, billion laughs).
- The DAV client never follows
hrefs to another host (SSRF). - Logins, device ids and device types are validated; SQL parameters are always bound.
smtp.enforce_fromrewritesFromto the account address;Bccis stripped from the transmitted copy.
Device control
- Provisioning policies (password, encryption, camera, maximum mail age ...). Changing a policy invalidates keys - devices must accept the policy again.
- Remote wipe (confirmed by typing the device id), device block, approval of new devices, mailbox block, blocked device types/User-Agents.
- Every administrative action is written to the audit log (who, what, when, from where).
systemd
The service runs as active-push without privileges or capabilities, with ProtectSystem=strict,
ProtectHome, PrivateTmp, PrivateDevices, MemoryDenyWriteExecute, a system call filter and write access
only to /var/lib/active-push. The database is 0600, the directory 0700, UMask=0077.
Recommendations
- TLS only at the reverse proxy, with HSTS; ActivePush on
127.0.0.1. - Panel through an SSH tunnel or VPN. If exposed - TLS +
panel.allowed_networks. - SMTP submission with
reject_sender_login_mismatch. - Enable
security.require_device_approvalin company environments. - Set a Prometheus token only if you scrape metrics; the endpoint then lives on the panel port.
logging.log_wbxmlcontains message content - only for short diagnosis.