Skip to content

Commit

Permalink
Merge pull request #7 from amberheilman/add-email-processor
Browse files Browse the repository at this point in the history
add email sanitization processor
  • Loading branch information
aremm committed Oct 3, 2017
2 parents b58d315 + 871105a commit 5fa68b4
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 3 deletions.
7 changes: 6 additions & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ http://localhost:8000/whatever provided that *whatever* is not an integer.

Version History
---------------
* `1.1.2`_

- Add email sanitization processor

* `1.1.1`_

- Fix password scrubbing in URLs.
Expand Down Expand Up @@ -94,7 +98,8 @@ License
.. _1.0.0: https://github.com/sprockets/sprockets.mixins.sentry/compare/0.4.0...1.0.0
.. _1.1.0: https://github.com/sprockets/sprockets.mixins.sentry/compare/1.0.0...1.1.0
.. _1.1.1: https://github.com/sprockets/sprockets.mixins.sentry/compare/1.1.0...1.1.1
.. _Next Release: https://github.com/sprockets/sprockets.mixins.sentry/compare/1.1.1...HEAD
.. _1.1.2: https://github.com/sprockets/sprockets.mixins.sentry/compare/1.1.1...1.1.2
.. _Next Release: https://github.com/sprockets/sprockets.mixins.sentry/compare/1.1.2...HEAD

.. |Version| image:: https://badge.fury.io/py/sprockets.mixins.sentry.svg?
:target: http://badge.fury.io/py/sprockets.mixins.sentry
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def read_requirements_file(req_name):

setuptools.setup(
name='sprockets.mixins.sentry',
version='1.1.1',
version='1.1.2',
description='A RequestHandler mixin for sending exceptions to Sentry',
long_description=codecs.open('README.rst', encoding='utf-8').read(),
url='https://github.com/sprockets/sprockets.mixins.sentry.git',
Expand Down
48 changes: 47 additions & 1 deletion sprockets/mixins/sentry/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
A RequestHandler mixin for sending exceptions to Sentry
"""
version_info = (1, 1, 1)
version_info = (1, 1, 2)
__version__ = '.'.join(str(v) for v in version_info)


Expand All @@ -19,6 +19,8 @@
import urlparse as parse

import raven
from raven._compat import string_types, text_type
from raven.processors import SanitizePasswordsProcessor
from tornado import web


Expand All @@ -37,6 +39,50 @@
_sentry_warning_issued = False


class SanitizeEmailsProcessor(SanitizePasswordsProcessor):
"""
Remove all email addresses from the payload sent to sentry.
"""

FIELDS = frozenset(['email', 'email_address'])
VALUES_RE = re.compile(r"""
((?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"
(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|
\\[\x01-\x09\x0b\x0c\x0e-\x7f])*\")
@
(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9]
(?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|
[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|
[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|
\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\]))
""", re.VERBOSE ^ re.IGNORECASE) # RFC5322

def sanitize(self, key, value):
if value is None:
return

if isinstance(value, string_types):
return self.VALUES_RE.sub(self.MASK, value)

if not key: # key can be a NoneType
return value

# Just in case we have bytes here, we want to make them into text
# properly without failing so we can perform our check.
if isinstance(key, bytes):
key = key.decode('utf-8', 'replace')
else:
key = text_type(key)

key = key.lower()
for field in self.FIELDS:
if field in key:
# store mask as a fixed length for security
return self.MASK
return value


class SentryMixin(object):
"""
Report unexpected exceptions to Sentry.
Expand Down
57 changes: 57 additions & 0 deletions tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,60 @@ def test_that_environment_is_set_by_default(self):
finally:
if saved:
os.environ['ENVIRONMENT'] = saved


class SanitizeEmailProcessorTests(unittest.TestCase):

data = {
'exception': {
'values': [{
'stacktrace': {
'frames': [{
'vars': {
'error': 'HTTPError("example@example.com"),',
'kwargs': {'email': 'example@example.com'}
},
}]
}
}],
},
'request': {
'data': 'ip_address=1&email=example%40example.com',
'cookies': {},
'headers': {'X-Email-Header': 'example+1234@example.net'},
'query_string': 'email=example@example.com&name=example',
},
'extra': {
'misc': 'Notes for example@example.com',
'env': {'email': 'example+1234{}@example.com'}
}
}

expectation = {
'exception': {
'values': [{
'stacktrace': {
'frames': [{
'vars': {
'error': 'HTTPError("********"),',
'kwargs': {'email': '********'}
},
}]
}
}],
},
'request': {
'data': 'ip_address=1&email=example%40example.com',
'cookies': {},
'headers': {'X-Email-Header': '********'},
'query_string': 'email=********&name=example',
},
'extra': {
'env': {'email': '********'},
'misc': 'Notes for ********'
}
}

def test_email_is_removed_from_extra_data(self):
result = sentry.SanitizeEmailsProcessor(mock.Mock()).process(self.data)
self.assertDictEqual(result, self.expectation)

0 comments on commit 5fa68b4

Please sign in to comment.