mirror of
https://gitlab.com/SIGBUS/nyaa.git
synced 2024-12-22 14:10:00 +00:00
config/forms: allow blacklisting email servers by IP
Adds a new config entry (EMAIL_SERVER_BLACKLIST, tuple of IPv4 addresses as strings) and an email validator for registering, which will query all the MX records for the domain and reject the registration if any of the A records for any of the MX records are found in the blacklist. If the query fails, the blacklist is ignored; the email is accepted.
This commit is contained in:
parent
86b7eb7ccd
commit
82aa243e45
|
@ -59,6 +59,11 @@ EMAIL_BLACKLIST = (
|
||||||
re.compile(r'(?i)@(msn\.com|passport\.(com|net))'),
|
re.compile(r'(?i)@(msn\.com|passport\.(com|net))'),
|
||||||
# '@dodgydomain.tk'
|
# '@dodgydomain.tk'
|
||||||
)
|
)
|
||||||
|
EMAIL_SERVER_BLACKLIST = (
|
||||||
|
# Bad mailserver IPs here (MX server.com -> A mail.server.com > 11.22.33.44)
|
||||||
|
# '1.2.3.4', '11.22.33.44'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Recaptcha keys (https://www.google.com/recaptcha)
|
# Recaptcha keys (https://www.google.com/recaptcha)
|
||||||
|
|
|
@ -14,6 +14,9 @@ from wtforms.validators import (DataRequired, Email, EqualTo, Length, Optional,
|
||||||
from wtforms.widgets import Select as SelectWidget # For DisabledSelectField
|
from wtforms.widgets import Select as SelectWidget # For DisabledSelectField
|
||||||
from wtforms.widgets import HTMLString, html_params # For DisabledSelectField
|
from wtforms.widgets import HTMLString, html_params # For DisabledSelectField
|
||||||
|
|
||||||
|
import dns.exception
|
||||||
|
import dns.resolver
|
||||||
|
|
||||||
from nyaa import bencode, models, utils
|
from nyaa import bencode, models, utils
|
||||||
from nyaa.extensions import config
|
from nyaa.extensions import config
|
||||||
from nyaa.models import User
|
from nyaa.models import User
|
||||||
|
@ -69,7 +72,7 @@ def upload_recaptcha_validator_shim(form, field):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def register_email_validator(form, field):
|
def register_email_blacklist_validator(form, field):
|
||||||
email_blacklist = app.config.get('EMAIL_BLACKLIST', [])
|
email_blacklist = app.config.get('EMAIL_BLACKLIST', [])
|
||||||
email = field.data.strip()
|
email = field.data.strip()
|
||||||
validation_exception = StopValidation('Blacklisted email provider')
|
validation_exception = StopValidation('Blacklisted email provider')
|
||||||
|
@ -86,6 +89,42 @@ def register_email_validator(form, field):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def register_email_server_validator(form, field):
|
||||||
|
server_blacklist = app.config.get('EMAIL_SERVER_BLACKLIST', [])
|
||||||
|
if not server_blacklist:
|
||||||
|
return True
|
||||||
|
|
||||||
|
validation_exception = StopValidation('Blacklisted email provider')
|
||||||
|
email = field.data.strip()
|
||||||
|
email_domain = email.split('@', 1)[-1]
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Query domain MX records
|
||||||
|
mx_records = list(dns.resolver.query(email_domain, 'MX'))
|
||||||
|
|
||||||
|
except dns.exception.DNSException:
|
||||||
|
app.logger.error('Unable to query MX records for email: %s - ignoring',
|
||||||
|
email, exc_info=False)
|
||||||
|
return True
|
||||||
|
|
||||||
|
for mx_record in mx_records:
|
||||||
|
try:
|
||||||
|
# Query mailserver A records
|
||||||
|
a_records = list(dns.resolver.query(mx_record.exchange))
|
||||||
|
for a_record in a_records:
|
||||||
|
# Check for address in blacklist
|
||||||
|
if a_record.address in server_blacklist:
|
||||||
|
app.logger.warning('Rejected email %s due to blacklisted mailserver (%s, %s)',
|
||||||
|
email, a_record.address, mx_record.exchange)
|
||||||
|
raise validation_exception
|
||||||
|
|
||||||
|
except dns.exception.DNSException:
|
||||||
|
app.logger.warning('Failed to query A records for mailserver: %s (%s) - ignoring',
|
||||||
|
mx_record.exchange, email, exc_info=False)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
_username_validator = Regexp(
|
_username_validator = Regexp(
|
||||||
r'^[a-zA-Z0-9_\-]+$',
|
r'^[a-zA-Z0-9_\-]+$',
|
||||||
message='Your username must only consist of alphanumerics and _- (a-zA-Z0-9_-)')
|
message='Your username must only consist of alphanumerics and _- (a-zA-Z0-9_-)')
|
||||||
|
@ -129,8 +168,9 @@ class RegisterForm(FlaskForm):
|
||||||
Email(),
|
Email(),
|
||||||
DataRequired(),
|
DataRequired(),
|
||||||
Length(min=5, max=128),
|
Length(min=5, max=128),
|
||||||
register_email_validator,
|
register_email_blacklist_validator,
|
||||||
Unique(User, User.email, 'Email already in use by another account')
|
Unique(User, User.email, 'Email already in use by another account'),
|
||||||
|
register_email_server_validator
|
||||||
])
|
])
|
||||||
|
|
||||||
password = PasswordField('Password', [
|
password = PasswordField('Password', [
|
||||||
|
|
|
@ -6,6 +6,7 @@ blinker==1.4
|
||||||
cffi==1.10.0
|
cffi==1.10.0
|
||||||
click==6.7
|
click==6.7
|
||||||
dominate==2.3.1
|
dominate==2.3.1
|
||||||
|
dnspython==1.15.0
|
||||||
elasticsearch==5.3.0
|
elasticsearch==5.3.0
|
||||||
elasticsearch-dsl==5.2.0
|
elasticsearch-dsl==5.2.0
|
||||||
flake8==3.3.0
|
flake8==3.3.0
|
||||||
|
|
Loading…
Reference in a new issue