it's also Ruby syntax
[web.git] / personal / _posts / 2018-06-02-mailman-subscription-spam.md
1 ---
2 title: "Fighting Mailman Subscription Spam: The Easy Way"
3 categories: sysadmin
4 ---
5
6 I recently noticed that both of the Mailman setups that I am running are being
7 abused for *subscription spam*: Bots would automatically attempt to subscribe
8 foreign email addresses to public mailing lists, resulting in a subscription
9 notification being sent to that address.  I am still extremely saddened by the
10 fact that this is a thing---whoever sends this spam has no direct benefit and no
11 way of selling anything (they don't control the content of the message); the
12 only effect is to annoy the owner of that email address, the victim.  That seems
13 to be enough for some. :(
14
15 Oh, and my servers' reputation goes down because people mark these emails as
16 spam.  So, more than enough reasons to try and stop this.
17
18 <!-- MORE -->
19
20 ### The Big Guns
21
22 My first reaction was to go and look for a way to add a CAPTCHA to the
23 subscription page.  Unfortunately, Mailman 2 itself only very recently (with
24 version 2.1.26) gained support for CAPTCHAs, and even that just supports
25 Google's reCAPTCHA.  I am not going to expose my users to Google's tracking like
26 that, nor am I willing to actively discriminate against people not having Google
27 accounts (reCAPTCHA is much more annoying if Google can't track you because you
28 are not logged in), so reCAPTCHA was clearly not an option.  Instead, the plan
29 was to look at one of the patches that add CAPTCHA support to older versions of
30 Mailman and implement a simple question-and-answer CAPTCHA myself.
31
32 **Update:** I previously claimed Mailman 2 does not support CAPTCHAs at all,
33   which turned out to be incorrect. **/Update**
34
35 ### Keep It Simple
36
37 But then, while just getting started on this and browsing the Mailman sources, I
38 found out about `SUBSCRIBE_FORM_SECRET`.  `SUBSCRIBE_FORM_SECRET` is a Mailman
39 config option that, once set to a random string, will make Mailman embed a
40 [CSRF token](https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet)
41 into the subscription form.  Mailman will also enforce that the form must be
42 submitted *at least* five seconds after it was generated.  Since the bots that
43 have found my servers so far are much less patient than that, just setting
44 `SUBSCRIBE_FORM_SECRET` was enough to completely get rid of the subscription
45 spam.
46
47 So, if you are reading this and running a Mailman installation: **Please set
48 `SUBSCRIBE_FORM_SECRET` and protect your setup against abuse!** Just run
49 `openssl rand -base64 18` to get some random string, and then add
50 `SUBSCRIBE_FORM_SECRET = "<random string here>"` to `/etc/mailman/mm_cfg.py`.
51 It's really that simple!  Just a
52 [four-line patch in my Ansible playbook](https://git.ralfj.de/ansible.git/commitdiff/937b170594be82e500ae726dc47de8ca9ef3dfcf)
53 to get this rolled out to all servers.  Note that you need to be at least on
54 Mailman 2.1.16 for this to work; all currently supported versions of Debian come
55 with a recent enough version (if you use backports on Debian 7 "Wheezy").
56
57 The more people do this, the more it will help to stop this kind of spam.  Or
58 rather, it'll force the spammers to upgrade their game.  I assume eventually I
59 *will* have to add a CAPTCHA.  Or maybe there is a simple and reliable way to
60 migrate to Mailman 3 before that happens---and maybe that will have more
61 reasonable CAPTCHA options, something beyond just reCAPTCHA.