Security

Small surface, published review

Missivus holds a credential that can send email as your company. That is exactly the kind of code that should be reviewed line by line and documented in public — so it was.

The security model in one paragraph

The Exchange application access policy is what bounds the blast radius. Every finding below is contained by it — even a fully compromised credential can send as one shared mailbox and do nothing else. That is why the installation guide treats the policy as a required step with a verification command, not as optional hardening.

What the review covered

The v0.1.1 tree was audited after the first live deployment — the Graph transport, the settings model, the test-email API method and the Vue component, checked for secret leakage through logs, API responses, HTML source and the browser console; authentication and CSRF on the API surface; input validation on every setting; and whether Graph error bodies can reach anyone but a superuser. Claims about Matomo behaviour were verified against Matomo's source, not recalled.

Findings, honestly stated

Fixed before release

  • A base-URL override could have aimed the client secret at an attacker's host — URLs are now validated to be bare https origins before any request is built.
  • A network failure mid-upload could leak a pre-authenticated upload URL into the log — now converted and redacted like every other failure.
  • Settings accepted any string — every field now validates its shape, so a pasted Secret ID fails at save time, not as an opaque Microsoft error later.
  • The test-email API method accepted any recipient and answered GET — now POST-only with a validated address, kept out of server access logs.

Verified clean

  • Secrets never reach the HTML source, the API response, or the browser console — password fields are masked by Matomo core, and the plugin adds two guards of its own on top.
  • The test call is CSRF-protected by Matomo's token model, with a POST-only rule added as defence in depth.
  • Everything logged or thrown passes through a redactor that blanks known secrets by value and credentials by shape — tokens, assertions, bearer headers, upload URLs — and fails closed.

Accepted trade-offs, documented

  • The short-lived access token is cached in Matomo's file-backed cache — anyone who can read it can already read Matomo's config, which may hold the secret itself. Mitigated by the 55-minute lifetime and the access policy.
  • A superuser can send unthrottled test emails — a nuisance vector, not a privilege one; a superuser could reconfigure mail outright anyway.
  • A secret entered in the settings UI is stored unencrypted in Matomo's database — the config-file and environment-variable tiers exist precisely so it never has to be, and they take precedence.

Read the full review with all eleven findings on GitHub

Reporting a vulnerability

Email the address below with the details. Please give us the chance to fix a problem before it becomes public — and never include a client secret, certificate or PEM file in a report.

Security contact: