Should Django natively support S/MIME email signing?

I’d like to open a discussion about whether Django’s email framework should include native support for S/MIME signing.

My use case will be to prove to my users that the app is actually sending the email, owns the email address and to avoid phishing.

Has anyone tackled this? And is there appetite for a core feature or at least an official recommendation?

I would be happy to contribute to the development of this feature.

Welcome @dioup !

From what I can see, it seems to me like it would be a perfect candidate as a third-party package as a Proof-of-concept / trial implementation. That’s typically the recommended first step toward new features being added.

It looks like there have been other packages created in this general category - django-gnupg-mails, django-secure-mail, and Djangi djembe. (Found by a rather quick search, I have no idea how close they are to what you’re looking for.)

My initial reaction is S/MIME signing (and encryption, and their PGP equivalents) would best be handled via a third-party package rather than integrated into django.core.mail

  • I think significant API changes would be needed to support email backends that compose their own MIME messages rather than calling Django’s EmailMessage.message(). (Or that delegate MIME composition to an external API.)
  • It’s not clear how Django would obtain the signing credentials for a particular sending address. (E.g., the django-djembe package Ken mentioned adds an Identity model mapping emails to private keys.)
  • It would require adding a dependency on (at least) the cryptography package. (Adding core dependencies is always controversial.)
  • I’d be a little concerned about maintenance churn to keep up with evolving algorithm recommendations.

All of these are more easily solved outside Django core. A third-party package can take an opinionated stance on which email backends are supported and how identity is managed, and can release on its own schedule independently from Django.

Have you already implemented a strong DMARC policy on your sending domain? In general, I’d expect that to be more effective than S/MIME signatures at protecting your users from phishing—particularly if you have any free Gmail users. DMARC is absolutely necessary in current email security, and you may find it sufficient. (DMARC is also probably easier to implement than S/MIME, and it gets you better reporting on spoofing attempts, too.)

1 Like

First thanks for your feedback.

I checked the libraries you mentioned and none of them mention only signing with a S/MIME certificate without encryption. However I found this smime-email (source), that fits more my need. I will try to suggest some changes to make it uses the Django Email Backend.

Understood, I will focus on going for a third-package.

Thanks a lot for you recommendations, I keep them in mind.

I’m curious - if you don’t mind my asking - do you do anything with the DMARC reports that you get from various domains?

Is there any generally-available tooling you find useful for these?

I’ve “eyeballed” a number of these files, and most of them appear to be “false alarms” from people trying to spam from my domain name. (The originating IP addresses are not mine.)

I’m just not sure what value I might be able to get from them.

In my case the DMARC reports are handled by Cloudflare. These were useful as we rolled DMARC out (initially report-only, then later reject) to make sure we weren’t missing a legitimate source of emails. After that, I’ve mostly ignored the reports since it’s doing what it’s supposed to do.

1 Like

I use Postmark’s free DMARC reporting: https://dmarc.postmarkapp.com/. It sends a weekly summary report of reported DMARC failures and successes by envelope-sender domain (or IP address if there’s no reverse DNS).

I haven’t really investigated other tools. The Postmark one was good enough when I first set it up years ago, and there’s never been a reason to switch. (It’s free, seems to be accurate, and has minimal advertising for their paid services.)

The main value of reporting was when first configuring DMARC, to identify all the systems and vendors that legitimately sent email “from” us. (Running with report-only p=none in the policy.)

Even after switching to p=reject, I’ve kept the weekly reports enabled. They’re confirmation everything is still working as expected. Like you say, they’re mostly “false alarms” from spammers trying to spoof sending from my domains (usually sending from individual IP addresses or poorly-secured ISPs or government agencies). They also let me know that our customers are still using email forwarding services that haven’t implemented ARC (which show up in the DKIM pass/SPF failure section). And if I ever did see a look-alike domain in the failures list, we’d know there was a targeted phishing attempt and could take further action.

1 Like

Yea, my situation is a bit easier to manage.

Postfix only listens to localhost for outgoing mail - the only source for outgoing emails are either the Django project or some command-line tools I use.

Anything coming in to Postfix from the outside can only be delivered to a local address.

I’ve never seen anything in my logs giving me an indication that a problem has occured - but you never know what might happen. I’ve just got the impression those dmarc reports aren’t going to give me any information I don’t already have.