Repository navigation
v0.36.4
0.36.4 (2026-10-23)
Bug Fixes
- email: SMTP email checks the server's certificate, and SMTP_CA_FILE names a private CA (#1329) (297b9b7)
Security note: email through an SMTP server
Published as GitHub security advisory GHSA-j26w-qcgq-rvph.
Who was affected. Releases 0.2.0 to 0.36.3 with email on (EMAIL_ENABLED=true), SMTP_HOST set, and both SMTP_USERNAME and SMTP_PASSWORD set. That includes a SendGrid setup with SMTP_HOST also set, whenever a SendGrid send failed and the API fell back to SMTP. Email through SendGrid alone was not affected, and nothing Controlvar ships turns SMTP on.
What could have been seen. Before 0.36.4 the API did not check the SMTP server's certificate before signing in, so anyone on the network path between the API and the SMTP server could have read the SMTP username and password, and the test email itself. In these releases the API connects to the SMTP server only when a developer or administrator sends a test email (POST /api/v1/notifications/test with "channel": "email" and a recipient); nothing else sends email.
What to do. Upgrade to 0.36.4. Then, if a test email was ever sent with both login settings set, or you cannot tell, change the SMTP password at your mail provider and update SMTP_PASSWORD. Change it after the upgrade, not before: an earlier release would send the new password the same way. In the provider's sign-in records for that username, look for sign-ins from an address other than your API's outbound address, and for mail you did not send.
With SMTP_USERNAME or SMTP_PASSWORD empty, no password was sent; 0.36.4 still sends that mail without STARTTLS unless SMTP_CA_FILE is set (see below).
Email through an SMTP server: what to check after upgrading
- Who: deployments with email on (
EMAIL_ENABLED=true) andSMTP_HOSTset that also set bothSMTP_USERNAMEandSMTP_PASSWORD, or set the newSMTP_CA_FILE. WithSENDGRID_API_KEYset as well, this applies whenever a SendGrid send fails and the API falls back to SMTP. - What changes: the API completes STARTTLS and checks the server's certificate (valid for
SMTP_HOST, trusted by the API image's operating-system certificate store or bySMTP_CA_FILE, TLS 1.2 or later) before it signs in or sends the message. If the server offers no STARTTLS or the certificate does not pass, nothing is sent. SettingSMTP_CA_FILErequires this even without a login. - What to do: use the server's STARTTLS port (usually 587; port 465 is not supported) and check that its certificate is valid for the name in
SMTP_HOST. For a private certificate authority, setSMTP_CA_FILEto a PEM file inside the API container, readable by the API's user (uid 1001). It replaces the default store for SMTP; put both sets of certificates in the file if you need both. - How to check: send a test email with an administrator or developer token and an explicit recipient (
POST /api/v1/notifications/testwith{"channel":"email","recipient":"you@example.com"}) and readsuccessin the response: HTTP 200 alone does not mean it was sent. If it is false, the API log has an error containingSMTP step=that names the step and what to check. If that error says the server accepted the message, confirm delivery before retrying. - Unchanged: email through SendGrid, and the order (SendGrid first, then SMTP when no SendGrid key is set or a SendGrid send fails). With either login setting empty and
SMTP_CA_FILEblank, the SMTP session is as before: no STARTTLS and no login.
Images
docker pull ghcr.io/controlvar/controlvar:core-0.36.4 # API, core profile
docker pull ghcr.io/controlvar/controlvar:full-0.36.4 # API, full profile
docker pull ghcr.io/controlvar/controlvar-web:core-0.36.4 # dashboard, core profile
docker pull ghcr.io/controlvar/controlvar-web:full-0.36.4 # dashboard, full profile
API images are built for linux/amd64; dashboard images for
linux/amd64. A host on any other architecture runs them under
emulation.
Verifying
Every image is signed with cosign keyless and carries an SPDX SBOM
attestation:
cosign verify ghcr.io/controlvar/controlvar:core-0.36.4 \
--certificate-identity-regexp '^https://github\.com/Controlvar/controlvar/\.github/workflows/release\.yml@refs/(heads/main|tags/v[0-9].*)$' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
cosign verify-attestation --type spdxjson ghcr.io/controlvar/controlvar:core-0.36.4 \
--certificate-identity-regexp '^https://github\.com/Controlvar/controlvar/\.github/workflows/release\.yml@refs/(heads/main|tags/v[0-9].*)$' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
The same SBOMs are attached below.