forked from getsentry/sentry
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(security): Block abusive email patterns
We're seeing a lot of junk signups from \[email protected] so this is a simply quick fix to make a configurable pattern match on blocking email addresses. It's not the be-all-end-all, but it prevents this simplistic attack. We'll likely also want to restore captcha in some cases in the future, but thats going to be a much more complex feature.
- Loading branch information
Showing
11 changed files
with
101 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
from __future__ import absolute_import | ||
|
||
from django.utils.translation import ugettext_lazy as _ | ||
from rest_framework import serializers | ||
|
||
from sentry.web.forms import fields | ||
|
||
|
||
class AllowedEmailField(serializers.EmailField): | ||
type_name = 'AllowedEmailField' | ||
type_label = 'email' | ||
form_field_class = fields.AllowedEmailField | ||
|
||
default_error_messages = { | ||
'invalid': _('Enter a valid email address.'), | ||
} | ||
default_validators = fields.AllowedEmailField.default_validators |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,3 @@ | ||
from __future__ import absolute_import, print_function | ||
|
||
import logging | ||
|
||
from django.utils import timezone | ||
|
||
from .emails import generate_security_email | ||
|
||
logger = logging.getLogger('sentry.security') | ||
|
||
|
||
def capture_security_activity( | ||
account, type, actor, ip_address, context=None, send_email=True, current_datetime=None | ||
): | ||
if current_datetime is None: | ||
current_datetime = timezone.now() | ||
|
||
logger_context = { | ||
'ip_address': ip_address, | ||
'user_id': account.id, | ||
'actor_id': actor.id, | ||
} | ||
|
||
if type == 'mfa-removed' or type == 'mfa-added': | ||
logger_context['authenticator_id'] = context['authenticator'].id | ||
|
||
logger.info(u'user.{}'.format(type), extra=logger_context) | ||
|
||
if send_email: | ||
msg = generate_security_email( | ||
account=account, | ||
type=type, | ||
actor=actor, | ||
ip_address=ip_address, | ||
context=context, | ||
current_datetime=current_datetime, | ||
) | ||
msg.send_async([account.email]) | ||
from .utils import * # NOQA |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
from __future__ import absolute_import, print_function | ||
|
||
import logging | ||
|
||
from django.conf import settings | ||
from django.utils import timezone | ||
|
||
from .emails import generate_security_email | ||
|
||
logger = logging.getLogger('sentry.security') | ||
|
||
|
||
def capture_security_activity( | ||
account, type, actor, ip_address, context=None, send_email=True, current_datetime=None | ||
): | ||
if current_datetime is None: | ||
current_datetime = timezone.now() | ||
|
||
logger_context = { | ||
'ip_address': ip_address, | ||
'user_id': account.id, | ||
'actor_id': actor.id, | ||
} | ||
|
||
if type == 'mfa-removed' or type == 'mfa-added': | ||
logger_context['authenticator_id'] = context['authenticator'].id | ||
|
||
logger.info(u'user.{}'.format(type), extra=logger_context) | ||
|
||
if send_email: | ||
msg = generate_security_email( | ||
account=account, | ||
type=type, | ||
actor=actor, | ||
ip_address=ip_address, | ||
context=context, | ||
current_datetime=current_datetime, | ||
) | ||
msg.send_async([account.email]) | ||
|
||
|
||
def is_valid_email_address(value): | ||
return not settings.INVALID_EMAIL_ADDRESS_PATTERN.search(value) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,7 +25,7 @@ | |
from sentry.models import (Organization, OrganizationStatus, User, UserOption, UserOptionValue) | ||
from sentry.security import capture_security_activity | ||
from sentry.utils.auth import find_users, logger | ||
from sentry.web.forms.fields import CustomTypedChoiceField, ReadOnlyTextField | ||
from sentry.web.forms.fields import CustomTypedChoiceField, ReadOnlyTextField, AllowedEmailField | ||
from six.moves import range | ||
|
||
|
||
|
@@ -185,7 +185,7 @@ class PasswordlessRegistrationForm(forms.ModelForm): | |
widget=forms.TextInput(attrs={'placeholder': 'Jane Doe'}), | ||
required=True | ||
) | ||
username = forms.EmailField( | ||
username = AllowedEmailField( | ||
label=_('Email'), | ||
max_length=128, | ||
widget=forms.TextInput(attrs={'placeholder': '[email protected]'}), | ||
|
@@ -308,8 +308,7 @@ def clean_password(self): | |
|
||
|
||
class EmailForm(forms.Form): | ||
|
||
alt_email = forms.EmailField( | ||
alt_email = AllowedEmailField( | ||
label=_('New Email'), | ||
required=False, | ||
help_text='Designate an alternative email for this account', | ||
|
@@ -345,7 +344,7 @@ def clean_password(self): | |
class AccountSettingsForm(forms.Form): | ||
name = forms.CharField(required=True, label=_('Name'), max_length=30) | ||
username = forms.CharField(label=_('Username'), max_length=128) | ||
email = forms.EmailField(label=_('Email')) | ||
email = AllowedEmailField(label=_('Email')) | ||
new_password = forms.CharField( | ||
label=_('New password'), | ||
widget=forms.PasswordInput(), | ||
|
@@ -630,7 +629,7 @@ def save(self): | |
|
||
|
||
class NotificationSettingsForm(forms.Form): | ||
alert_email = forms.EmailField( | ||
alert_email = AllowedEmailField( | ||
label=_('Email'), | ||
help_text=_('Designate an alternative email address to send email notifications to.'), | ||
required=False | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from __future__ import absolute_import |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
from __future__ import absolute_import | ||
|
||
from sentry.security.utils import is_valid_email_address | ||
|
||
|
||
def test_is_valid_email_address_number_at_qqcom(): | ||
assert is_valid_email_address('[email protected]') is False | ||
|
||
|
||
def test_is_valid_email_address_normal_human_email_address(): | ||
assert is_valid_email_address('[email protected]') is True |