Merge pull request #375 from ThomasWaldmann/validate-registration-email

validate email address in registration form
This commit is contained in:
TW 2018-10-14 15:16:50 +02:00 committed by GitHub
commit bd0fa0f040
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 91 additions and 0 deletions

View File

@ -0,0 +1,75 @@
# -*- coding: utf-8 -*-
import re
import logging
logger = logging.getLogger(__name__)
from django import forms
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from registration.forms import RegistrationForm
import dns.resolver
import dns.name
resolver = dns.resolver.Resolver()
resolver.search = [dns.name.root, ]
resolver.lifetime = 5.0
resolver.nameservers = settings.NAMESERVERS
maildomain_blacklist = settings.MAILDOMAIN_BLACKLIST.strip().splitlines()
def check_mx(domain):
valid = False
try:
mx_answers = resolver.query(domain, 'MX')
# domain exists in DNS, domain has MX
mx_entries = sorted([(mx_rdata.preference, mx_rdata.exchange) for mx_rdata in mx_answers])
for preference, mx in mx_entries:
try:
addr_answers = resolver.query(mx, 'A')
except dns.resolver.NoAnswer:
addr_answers = resolver.query(mx, 'AAAA')
# MX has IP addr
mx_addrs = [addr_rdata.address for addr_rdata in addr_answers]
for mx_addr in mx_addrs:
if mx_addr not in (u'127.0.0.1', u'::1', u'0.0.0.0', ):
valid = True
break
if valid:
break
except (dns.resolver.Timeout, dns.resolver.NoAnswer, dns.resolver.NoNameservers, dns.resolver.NXDOMAIN, ):
# expected exceptions (e.g. due to non-existing or misconfigured crap domains)
pass
return valid
def check_blacklist(domain):
for blacklisted_re in maildomain_blacklist:
if re.search(blacklisted_re, domain):
return False
return True
class RegistrationFormValidateEmail(RegistrationForm):
def clean_email(self):
"""
Validate the supplied email address to avoid undeliverable email and mailer daemon spam.
"""
email = self.cleaned_data.get('email')
valid_mx = False
try:
domain = email.split('@')[1]
valid_mx = check_mx(domain)
except Exception as e:
logger.exception('RegistrationFormValidateEmail raised an exception:')
not_blacklisted = check_blacklist(domain)
if valid_mx and not_blacklisted:
return email
logger.info('RegistrationFormValidateEmail: rejecting email address %r' % email)
raise forms.ValidationError(_("Enter a valid email address."))

View File

@ -51,6 +51,21 @@ BAD_AGENTS = set([]) # list can have str elements
from netaddr import IPSet, IPAddress, IPNetwork from netaddr import IPSet, IPAddress, IPNetwork
BAD_IPS_HOST = IPSet([]) # inner list can have IPAddress and IPNetwork elements BAD_IPS_HOST = IPSet([]) # inner list can have IPAddress and IPNetwork elements
# nameservers used e.g. for MX lookups in the registration email validation.
# google / cloudflare DNS IPs are only given as example / fallback -
# please configure your own nameservers in your local settings file.
NAMESERVERS = ['8.8.8.8', '1.1.1.1', ]
# registration email validation: disallow specific email domains,
# e.g. domains that have a non-working mx / that are frequently abused.
# we use a multiline string here with one regex per line (used with re.search).
# the domains given below are just examples, please configure your own
# regexes in your local settings file.
MAILDOMAIN_BLACKLIST = """
mailcatch\.com$
mailspam\.xyz$
"""
# Local time zone for this installation. Choices can be found here: # Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems. # although not all choices may be available on all operating systems.
@ -245,6 +260,7 @@ SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
ACCOUNT_ACTIVATION_DAYS = 7 ACCOUNT_ACTIVATION_DAYS = 7
REGISTRATION_EMAIL_HTML = False # we override the text, but not the html email template REGISTRATION_EMAIL_HTML = False # we override the text, but not the html email template
REGISTRATION_FORM = 'nsupdate.accounts.registration_form.RegistrationFormValidateEmail'
LOGIN_REDIRECT_URL = '/overview/' LOGIN_REDIRECT_URL = '/overview/'
LOGOUT_REDIRECT_URL = '/' LOGOUT_REDIRECT_URL = '/'