Merge lp:~jks/mailman/hcaptcha into lp:mailman/2.1

Proposed by Jouni K. Seppänen
Status: Needs review
Proposed branch: lp:~jks/mailman/hcaptcha
Merge into: lp:mailman/2.1
Diff against target: 125 lines (+59/-11)
3 files modified
Mailman/Cgi/listinfo.py (+13/-3)
Mailman/Cgi/subscribe.py (+40/-8)
Mailman/Defaults.py.in (+6/-0)
To merge this branch: bzr merge lp:~jks/mailman/hcaptcha
Reviewer Review Type Date Requested Status
Jim Popovitch (community) Approve
Mark Sapiro process Disapprove
Review via email: mp+389691@code.launchpad.net

Description of the change

I noticed that a Mailman 2.1 site I run was being used for sending subscribe confirmation messages to people. I didn't want to implement reCaptcha because of privacy concerns, and hCaptcha seems to be almost a drop-in replacement that at least promises to respect user privacy. This change allows using hCaptcha instead of reCaptcha for guarding the subscription form.

When testing, the dummy keys from https://docs.hcaptcha.com/#localdev may be useful:

Dummy Site Key:10000000-ffff-ffff-ffff-000000000001
Dummy Secret Key:0x0000000000000000000000000000000000000000

To post a comment you must log in.
Revision history for this message
Mark Sapiro (msapiro) wrote :

Mailman 2.1 is end of life. No new features are being implemented.

review: Disapprove (process)
Revision history for this message
Jim Popovitch (jimpop) wrote :

If it has life, let it live....

If you love some(thing) set it free...

Revision history for this message
Jim Popovitch (jimpop) wrote :

BTW, python2 is fully supported until 2025 in Ubuntu 20.04 LTS (Focal)

https://lists.ubuntu.com/archives/ubuntu-announce/2020-April/000256.html

Revision history for this message
Mark Sapiro (msapiro) wrote :

I never said people weren't free to make their own forks. I just said I and the GNU Mailman project weren't going to do it. It's GPL'd. Have at it.

Revision history for this message
Jim Popovitch (jimpop) wrote :

If you just want to step aside and move on, then do it.

The question that never gets answered is: There are plenty of people involved with the project, how come you get to decide it dies? Let it die due to inactivity, sure.

Revision history for this message
Mark Sapiro (msapiro) wrote :

@jimpop For the last several years the only member of the Gnu Mailman project supporting the actual Mailman 2.1 code base has been me. I get to decide what I am willing to do. I'm not trying to kill Mailman 2.1. I have said I will accept i18n updates and fix security issues and critical bugs. I still actively support Mailman 2.1 users on the <email address hidden> list, but I am not implementing new features. That's all.

Revision history for this message
Jim Popovitch (jimpop) wrote :

So let me, jks, and anyone else who wants to jump in, maintain new features.

Revision history for this message
Mark Sapiro (msapiro) wrote :

I assume you aren't just asking permission to create and maintain your own branch on Launchpad and add it to your PPA, since you don't need my permission/approval to do that, so I guess you are asking for commit permission on https://code.launchpad.net/~mailman-coders/mailman/2.1 and the ability to add new releases to https://launchpad.net/mailman/2.1/, https://ftp.gnu.org/gnu/mailman/ and https://sourceforge.net/projects/mailman/ and perhaps the ability to update
http://www.list.org, https://www.gnu.org/software/mailman and http://mailman.sourceforge.net/.

If that is the case, I suggest you start by making a proposal to <email address hidden>.

Revision history for this message
Jouni K. Seppänen (jks) wrote :

Hey, I just needed to patch my own installation of Mailman and thought that the patch would be useful to others; I didn't propose to take on the burden of maintaining Mailman. Apparently this patch wasn't welcome, which is certainly fair enough.

Perhaps eventually I will find the time and energy to attempt a migration to Mailman 3 and figure out if it already has hCaptcha support or similar protection against subscription spam. Until such time, it seems I'll have to be running a patched version, and perhaps others in a similar situation can find this patch here.

Revision history for this message
Jim Popovitch (jimpop) wrote :

> I assume you aren't just asking permission to create and maintain your own
> branch on Launchpad and add it to your PPA, since you don't need my
> permission/approval to do that, so I guess you are asking for commit
> permission on https://code.launchpad.net/~mailman-coders/mailman/2.1 and the
> ability to add new releases to https://launchpad.net/mailman/2.1/,
> https://ftp.gnu.org/gnu/mailman/ and https://sourceforge.net/projects/mailman/
> and perhaps the ability to update
> http://www.list.org, https://www.gnu.org/software/mailman and
> http://mailman.sourceforge.net/.

All that would be wonderful, but that's overkill. What is needed is the ability to approve new features and to commit them into the original and common code base that has been in place for decades now. Sure, anyone can do that in their own fork, but the mm2 project is where it should be done. I understand that your personal opinion is that you don't want to do that. No one should be upset or offended by you deciding that you don't want to do something; people should applaud that.

> If that is the case, I suggest you start by making a proposal to mailman-
> <email address hidden>.

Noted. I don't see a need for any great changes other than one or two additional people to test and approve new features that come up once or twice a year. I'll make a post on the list to ask for one or two others to join me in coming up with a proposal. Thanks.

review: Approve

Unmerged revisions

1861. By Jouni K. Seppänen

Allow using hCaptcha in addition to reCaptcha

hCaptcha is allegedly better for user privacy.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Mailman/Cgi/listinfo.py'
2--- Mailman/Cgi/listinfo.py 2019-06-19 23:56:49 +0000
3+++ Mailman/Cgi/listinfo.py 2020-08-23 10:21:44 +0000
4@@ -263,15 +263,25 @@
5 replacements['<mm-fullname-box>'] = mlist.FormatBox('fullname', size=30)
6 # If reCAPTCHA is enabled, display its user interface
7 if mm_cfg.RECAPTCHA_SITE_KEY:
8+ captcha_api = 'https://www.google.com/recaptcha/api.js?hl=%s' % lang
9+ div_class = 'g-recaptcha'
10+ sitekey = mm_cfg.RECAPTCHA_SITE_KEY
11+ elif mm_cfg.HCAPTCHA_SITE_KEY:
12+ captcha_api = 'https://hcaptcha.com/1/api.js?hl=%s' % lang
13+ div_class = 'h-captcha'
14+ sitekey = mm_cfg.HCAPTCHA_SITE_KEY
15+ else:
16+ captcha_api = None
17+ if captcha_api is not None:
18 noscript = _('This form requires JavaScript.')
19 replacements['<mm-recaptcha-ui>'] = (
20 """<tr><td>&nbsp;</td><td>
21 <noscript>%s</noscript>
22- <script src="https://www.google.com/recaptcha/api.js?hl=%s">
23+ <script src="%s">
24 </script>
25- <div class="g-recaptcha" data-sitekey="%s"></div>
26+ <div class="%s" data-sitekey="%s"></div>
27 </td></tr>"""
28- % (noscript, lang, mm_cfg.RECAPTCHA_SITE_KEY))
29+ % (noscript, captcha_api, div_class, sitekey))
30 else:
31 replacements['<mm-recaptcha-ui>'] = ''
32
33
34=== modified file 'Mailman/Cgi/subscribe.py'
35--- Mailman/Cgi/subscribe.py 2020-06-10 22:04:26 +0000
36+++ Mailman/Cgi/subscribe.py 2020-08-23 10:21:44 +0000
37@@ -39,6 +39,25 @@
38 SLASH = '/'
39 ERRORSEP = '\n\n<p>'
40 COMMASPACE = ', '
41+CAPTCHA = {
42+ 'recaptcha': {
43+ 'name': 'reCAPTCHA',
44+ 'verify': 'https://www.google.com/recaptcha/api/siteverify',
45+ 'secret_key': mm_cfg.RECAPTCHA_SECRET_KEY,
46+ 'site_key': mm_cfg.RECAPTCHA_SITE_KEY,
47+ 'value': 'g-recaptcha-response',
48+ 'include_site_key': False
49+ },
50+ 'hcaptcha': {
51+ 'name': 'hCAPTCHA',
52+ 'verify': 'https://hcaptcha.com/siteverify',
53+ 'secret_key': mm_cfg.HCAPTCHA_SECRET_KEY,
54+ 'site_key': mm_cfg.HCAPTCHA_SITE_KEY,
55+ 'value': 'h-captcha-response',
56+ 'include_site_key': True
57+ },
58+}
59+
60
61 # Set up i18n
62 _ = i18n._
63@@ -136,24 +155,37 @@
64 os.environ.get('REMOTE_ADDR',
65 'unidentified origin')))
66
67- # Check reCAPTCHA submission, if enabled
68+ # Check reCAPTCHA/hCAPTCHA submission, if enabled
69 if mm_cfg.RECAPTCHA_SECRET_KEY:
70+ captcha = CAPTCHA['recaptcha']
71+ elif mm_cfg.HCAPTCHA_SECRET_KEY:
72+ captcha = CAPTCHA['hcaptcha']
73+ else:
74+ captcha = None
75+
76+ if captcha is not None:
77+ name = captcha['name']
78+ data = {
79+ 'secret': captcha['secret_key'],
80+ 'response': cgidata.getvalue(captcha['value'], ''),
81+ 'remoteip': remote
82+ }
83+ if captcha['include_site_key']:
84+ data['sitekey'] = captcha['site_key']
85 request = urllib2.Request(
86- url = 'https://www.google.com/recaptcha/api/siteverify',
87- data = urllib.urlencode({
88- 'secret': mm_cfg.RECAPTCHA_SECRET_KEY,
89- 'response': cgidata.getvalue('g-recaptcha-response', ''),
90- 'remoteip': remote}))
91+ url = captcha['verify'],
92+ data = urllib.urlencode(data)
93+ )
94 try:
95 httpresp = urllib2.urlopen(request)
96 captcha_response = json.load(httpresp)
97 httpresp.close()
98 if not captcha_response['success']:
99 e_codes = COMMASPACE.join(captcha_response['error-codes'])
100- results.append(_('reCAPTCHA validation failed: %(e_codes)s'))
101+ results.append(_('%(name)s validation failed: %(e_codes)s'))
102 except urllib2.URLError, e:
103 e_reason = e.reason
104- results.append(_('reCAPTCHA could not be validated: %(e_reason)s'))
105+ results.append(_('%(name)s could not be validated: %(e_reason)s'))
106
107 # Are we checking the hidden data?
108 if mm_cfg.SUBSCRIBE_FORM_SECRET:
109
110=== modified file 'Mailman/Defaults.py.in'
111--- Mailman/Defaults.py.in 2020-06-10 22:04:26 +0000
112+++ Mailman/Defaults.py.in 2020-08-23 10:21:44 +0000
113@@ -156,6 +156,12 @@
114 RECAPTCHA_SITE_KEY = None
115 RECAPTCHA_SECRET_KEY = None
116
117+# Use hCAPTCHA to protect the subscription form from spam bots, as an
118+# alternative to the Google reCAPTCHA (at most one of the two can be enabled).
119+# Obtain the following keys from https://www.hcaptcha.com
120+HCAPTCHA_SITE_KEY = None
121+HCAPTCHA_SECRET_KEY = None
122+
123 # Installation wide ban list. This is a list of email addresses and regexp
124 # patterns (beginning with ^) which are not allowed to subscribe to any lists
125 # in the installation. This supplements the individual list's ban_list.