gtalug / infrastructure

GTALUG infrastructure (the server).
0 stars 0 forks source link

Can we protect the list from automated subscription attacks? #25

Open cbbrowne opened 10 years ago

cbbrowne commented 10 years ago

There is discussion on this for Mailman...

"Automated Subscription Bots Inundating List Owners With Subscription Requests" http://www.mail-archive.com/mailman-users%40python.org/msg61769.html

One aspect is preventing cross-site request forgery (CSRF) https://mail.python.org/pipermail/mailman-users/2012-January/072819.html

Another is to use CAPTCHAs https://www.dragonsreach.it/2014/05/03/adding-recaptcha-support-to-mailman/

I don't generally like CAPTCHAs, myself, I prefer to describe the problem abstractly (e.g. - "protect from automated subscription attacks") , as opposed to a particular prescription (e.g. - "we MUST implement CAPTCHA"). Perhaps there are other solutions, whether partial or full.

mgjk commented 10 years ago

Observation only: during testing, my account went to moderation mode, requiring approval before anything would be posted. We're not wide open, but it sounds like we're subject to the Moderation DoS described.

mgjk commented 10 years ago

Hmm.. Something like fail2ban could watch for subscription attempts and block if there are too many from the same IP, or too many total.

myles commented 10 years ago

/var/log/mailman/subscribe looks something like this (IP addresses and emails have been redacted):

Aug 16 17:12:31 2014 (13362) talk: pending example1@example.org  0:0:0:0:0:0:0:1
Aug 18 02:12:48 2014 (26320) announce: pending first last <example2@example.org>  example2@example.org
Aug 18 02:15:04 2014 (15980) announce: new first last <example2@example.org>, via web confirmation
Aug 18 16:46:02 2014 (17267) talk: pending example3@example.org  127.0.0.1
Aug 18 16:57:29 2014 (26320) talk: new example3@example.org, via email confirmation
Aug 18 17:18:06 2014 (17302) talk: pending Myles Braithwaite <myles@monkeyinyoursoul.com>  127.0.0.1
Aug 18 17:18:32 2014 (17309) talk: new Myles Braithwaite <myles@monkeyinyoursoul.com>, via web confirmation
Aug 19 11:22:18 2014 (19569) talk: pending "First Last" <example4@example.org>  127.0.0.1
Aug 19 11:46:38 2014 (19592) talk: new "First Last" <example4@example.org>, via web confirmation

Fail2Ban could work with something like this:

/etc/fail2ban/filter.d/mailman/conf:

failregex = .* (talk|operations|board): pending .* <HOST>$

/etc/fail2ban/jail.local:

[mailman]
enabled = true
port = "http,https"
filter = mailman
logpath = /var/log/mailman/subscribe

It only protects against web site and not email based signups (this isn't really an issue considering how much work it takes to signup for Mailman with email an attacker probably doesn't care).

myles commented 10 years ago

Here is an example of the output of fail2ban-regex (IP addresses have been redacted):

$ fail2ban-regex /var/log/mailman/subscribe ".* (talk|operations|board): pending .* <HOST>$"

Running tests
=============

Use regex line : .* (talk|operations|board): pending .* <HOST>$
Use log file   : /var/log/mailman/subscribe

Results
=======

Failregex
|- Regular expressions:
|  [1] .* (talk|operations|board): pending .* <HOST>$
|
`- Number of matches:
   [1] 18 match(es)

Ignoreregex
|- Regular expressions:
|
`- Number of matches:

Summary
=======

Addresses found:
[1]
    xxx.xxx.xxx.xxx (Sat Aug 02 04:11:15 2014)
    xxx.xxx.xxx.xxx (Mon Aug 04 00:32:23 2014)
    xxx.xxx.xxx.xxx (Mon Aug 04 00:36:27 2014)
    xxx.xxx.xxx.xxx (Mon Aug 04 18:12:49 2014)
    xxx.xxx.xxx.xxx (Mon Aug 04 18:16:42 2014)
    xxx.xxx.xxx.xxx (Tue Aug 05 17:38:38 2014)
    xxx.xxx.xxx.xxx (Tue Aug 05 17:42:11 2014)
    xxx.xxx.xxx.xxx (Tue Aug 05 18:47:26 2014)
    xxx.xxx.xxx.xxx (Tue Aug 05 19:31:40 2014)
    xxx.xxx.xxx.xxx (Tue Aug 05 19:37:23 2014)
    xxx.xxx.xxx.xxx (Fri Aug 08 22:26:32 2014)
    xxx.xxx.xxx.xxx (Sat Aug 09 21:26:44 2014)
    xxx.xxx.xxx.xxx (Wed Aug 13 16:20:57 2014)
    xxx.xxx.xxx.xxx (Wed Aug 13 21:11:16 2014)
    xxx.xxx.xxx.xxx (Wed Aug 13 21:15:36 2014)
    xxx.xxx.xxx.xxx (Mon Aug 18 16:46:02 2014)
    xxx.xxx.xxx.xxx (Mon Aug 18 17:18:06 2014)
    xxx.xxx.xxx.xxx (Tue Aug 19 11:22:18 2014)

Date template hits:
84 hit(s): MONTH Day Hour:Minute:Second
0 hit(s): WEEKDAY MONTH Day Hour:Minute:Second Year
0 hit(s): WEEKDAY MONTH Day Hour:Minute:Second
0 hit(s): Year/Month/Day Hour:Minute:Second
0 hit(s): Day/Month/Year Hour:Minute:Second
0 hit(s): Day/Month/Year Hour:Minute:Second
0 hit(s): Day/MONTH/Year:Hour:Minute:Second
0 hit(s): Month/Day/Year:Hour:Minute:Second
0 hit(s): Year-Month-Day Hour:Minute:Second
0 hit(s): Year.Month.Day Hour:Minute:Second
0 hit(s): Day-MONTH-Year Hour:Minute:Second[.Millisecond]
0 hit(s): Day-Month-Year Hour:Minute:Second
0 hit(s): TAI64N
0 hit(s): Epoch
0 hit(s): ISO 8601
0 hit(s): Hour:Minute:Second
0 hit(s): <Month/Day/Year@Hour:Minute:Second>

Success, the total number of match is 18

However, look at the above section 'Running tests' which could contain important
information.

So it works.