Releases: anymail/django-anymail
v4.0
v3.0
Changes
- Breaking change: Python 3.3 is no longer supported (see #99).
- Mailjet: Fix tracking webhooks to work correctly when Mailjet "group events" option is disabled (see #106).
- SendGrid: Fix a problem where Anymail's status tracking webhooks didn't always receive the same
event.message_id
as the sentmessage.anymail_status.message_id
, due to unpredictable behavior by SendGrid's API. Anymail now generates a UUID for each sent message and attaches it as a SendGrid custom arg named anymail_id. For most users, this change should be transparent. But it could be a breaking change if you are relying on a specific message_id format, or relying on message_id matching the Message-ID mail header or SendGrid's "smtp-id" event field. (More details in the docs; also see #108.) Thanks to @joshkersey for the report and the fix. - Support Django 2.1 prerelease.
Deprecations
- This will be the last Anymail release to support Django 1.8, 1.9, and 1.10 (see #110).
- This will be the last Anymail release to support the legacy SendGrid v2 EmailBackend (see #111). (SendGrid's newer v3 API has been the default since Anymail v0.8.)
- Anymail v3.x will receive security updates and fixes for any breaking ESP API changes through at least April, 2019.
- If these deprecations affect you and you cannot upgrade, set your requirements to
django-anymail~=3.0
(a "compatible release" specifier, equivalent to>=3.0,==3.*
).
v2.2
v2.1
NOTE: v2.1 accidentally introduced a breaking change: enabling Anymail webhooks with include('anymail.urls')
causes an error if boto3 is not installed, even if you aren't using Amazon SES. This is fixed in v2.2.
New features
- Amazon SES: Newly-supported ESP (docs).
- SparkPost: Add SPARKPOST_API_URL setting to support SparkPost EU and SparkPost Enterprise (docs).
Other changes
- Inbound: Fix several issues with inbound messages, particularly around non-ASCII headers and body content. Add workarounds for some limitations in older Python email packages.
- Postmark: Update for Postmark "modular webhooks." This should not impact client code. (Also, older versions of Anymail will still work correctly with Postmark's webhook changes.)
- Use tox to manage Anymail test environments (see contributor docs).
Notice
This will be the last Anymail release to support Python 3.3. See #99 for more information.
v2.0
Important updates
- Breaking change: Drop support for deprecated WEBHOOK_AUTHORIZATION setting. If you are using webhooks and still have this Anymail setting, you must rename it to WEBHOOK_SECRET. See the v1.4 release notes.
New features
- SendinBlue: Add new ESP (docs). Thanks to @RignonNoel for the implementation.
- Add EmailMessage
envelope_sender
attribute, which can adjust the message's Return-Path if supported by your ESP (docs). - Add universal wheel to PyPI releases for faster installation.
Other changes
- Handle Reply-To, From, and To in EmailMessage
extra_headers
the same as Django's SMTP EmailBackend if supported by your ESP, otherwise raise an unsupported feature error. Fixes the SparkPost backend to be consistent with other backends if bothheaders["Reply-To"]
andreply_to
are set on the same message. If you are setting a message'sheaders["From"]
orheaders["To"]
(neither is common), the new behavior is likely a breaking change. See docs and #91. - Treat EmailMessage
extra_headers
keys as case-insensitive in all backends, for consistency with each other (and email specs). If you are specifying duplicate headers whose names differ only in case, this may be a breaking change. See docs. - Update setup.py metadata, clean up implementation. (Hadn't really been touched since original Djrill version.)
- Prep for Python 3.7.
v1.4
Security fix
This fixes a low severity security issue affecting Anymail v0.2–v1.3. (CVE-2018-1000089)
Django error reporting includes the value of your Anymail WEBHOOK_AUTHORIZATION setting. In a properly-configured deployment, this should not be cause for concern. But if you have somehow exposed your Django error reports (e.g., by mis-deploying with DEBUG=True or by sending error reports through insecure channels), anyone who gains access to those reports could discover your webhook shared secret. An attacker could use this to post fabricated or malicious Anymail tracking/inbound events to your app, if you are using those Anymail features.
The fix renames Anymail's webhook shared secret setting so that Django's error reporting mechanism will sanitize it.
If you are using Anymail's event tracking and/or inbound webhooks, you should upgrade to this release and change "WEBHOOK_AUTHORIZATION" to "WEBHOOK_SECRET" in the ANYMAIL section of your settings.py. You may also want to rotate the shared secret value, particularly if you have ever exposed your Django error reports to untrusted individuals.
If you are only using Anymail's EmailBackends for sending email and have not set up Anymail's webhooks, this issue does not affect you.
The old WEBHOOK_AUTHORIZATION setting is still allowed in this release, but will issue a system-check warning when running most Django management commands. It will be removed completely in a near-future release, as a breaking change.
Thanks to Charlie DeTar (@yourcelf) for responsibly reporting this security issue through private channels.
v1.3
Security fix
v1.3 includes the v1.2.1 security fix released at the same time. Please review the v1.2.1 release notes, below, if you are using Anymail's tracking webhooks.
New features
- Inbound handling: Add normalized inbound message event, signal, and webhooks for all supported ESPs. (See new Receiving mail docs.) This hasn't been through much real-world testing yet; bug reports and feedback are very welcome.
- API network timeouts: For Requests-based backends (all but SparkPost), use a default timeout of 30 seconds for all ESP API calls, to avoid stalling forever on a bad connection. Add a REQUESTS_TIMEOUT Anymail setting to override. (See #80.)
- Test backend improvements: Generate unique tracking
message_id
when using the test backend; add console backend for use in development. (See #85.)
v1.2.1
Security fix
This release fixes a moderate severity security issue affecting Anymail v0.2–v1.2:
Prevent timing attack on WEBHOOK_AUTHORIZATION secret (CVE-2018-6596)
If you are using Anymail's tracking webhooks, you should upgrade to this release, and you may want to rotate to a new WEBHOOK_AUTHORIZATION shared secret (see docs). You should definitely change your webhook auth if your logs indicate attempted exploit.
(If you are only sending email using an Anymail EmailBackend, and have not set up Anymail's event tracking webhooks, this issue does not affect you.)
More information
Anymail's webhook validation was vulnerable to a timing attack. A remote attacker could use this to obtain your WEBHOOK_AUTHORIZATION shared secret, potentially allowing them to post fabricated or malicious email tracking events to your app.
There have not been any reports of attempted exploit. (The vulnerability was discovered through code review.) Attempts would be visible in HTTP logs as a very large number of 400 responses on Anymail's webhook urls (by default "/anymail/esp_name/tracking/"), and in Python error monitoring as a very large number of AnymailWebhookValidationFailure exceptions.
v1.2
v1.1
Bug fixes
- Mailgun: Support metadata in opened/clicked/unsubscribed tracking webhooks, and fix potential problems if metadata keys collided with Mailgun event parameter names. (See #76, #77)
Other changes
- Internal: Rework Anymail's ParsedEmail class and rename to EmailAddress to align it with similar functionality in the Python 3.6 email package, in preparation for future inbound support. ParsedEmail was not documented for use outside Anymail's internals (so this change does not bump the semver major version), but if you were using it in an undocumented way you will need to update your code.