Skip to content

Commit 6b2e122

Browse files
added test
1 parent 941658a commit 6b2e122

File tree

5 files changed

+328
-17
lines changed

5 files changed

+328
-17
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import re
2+
import logging
3+
import logging.config
4+
5+
MBI_WITH_HYPHEN_PATTERN = r"""\b
6+
[1-9](?![SLOIBZsloibz])[A-Za-z](?![SLOIBZsloibz)])[A-Za-z\d]\d
7+
-(?![SLOIBZsloibz])[A-Za-z](?![SLOIBZsloibz])[A-Za-z\d]\d
8+
-((?![SLOIBZsloibz])[A-Za-z]){2}\d{2}
9+
\b
10+
"""
11+
12+
MBI_WITHOUT_HYPHEN_PATTERN = r"""\b
13+
[1-9](?![SLOIBZsloibz])[A-Za-z](?![SLOIBZsloibz)])[A-Za-z\d]\d
14+
(?![SLOIBZsloibz])[A-Za-z](?![SLOIBZsloibz])[A-Za-z\d]\d
15+
((?![SLOIBZsloibzd])[A-Za-z]){2}\d{2}
16+
\b"""
17+
18+
MBI_PATTERN = f'({MBI_WITH_HYPHEN_PATTERN}|{MBI_WITHOUT_HYPHEN_PATTERN})'
19+
SENSITIVE_DATA_FILTER = "sensitive_data_filter"
20+
21+
22+
def has_mbi_match(text):
23+
return bool(re.search(MBI_PATTERN, text, flags=re.VERBOSE))
24+
25+
26+
def mask_if_has_mbi(text):
27+
return re.sub(MBI_PATTERN, '***MBI***', str(text), flags=re.VERBOSE)
28+
29+
30+
def is_not_primitive(value):
31+
primitive_types = (int, float, bool, str, bytes)
32+
return not isinstance(value, primitive_types)
33+
34+
35+
def mask_mbi(value_to_mask):
36+
if isinstance(value_to_mask, str):
37+
return mask_if_has_mbi(value_to_mask)
38+
39+
if isinstance(value_to_mask, tuple):
40+
return tuple([mask_if_has_mbi(arg) for arg in value_to_mask])
41+
42+
if isinstance(value_to_mask, list):
43+
return [mask_if_has_mbi(arg) for arg in value_to_mask]
44+
45+
if isinstance(value_to_mask, dict):
46+
for key, value in value_to_mask.items():
47+
if is_not_primitive(value):
48+
mask_mbi(value)
49+
else:
50+
value_to_mask[key] = mask_if_has_mbi(value)
51+
52+
return value_to_mask
53+
54+
55+
class SensitiveDataFilter(logging.Filter):
56+
57+
def filter(self, record):
58+
try:
59+
record.args = mask_mbi(record.args)
60+
record.msg = mask_mbi(record.msg)
61+
return True
62+
except Exception:
63+
pass
64+
65+
def mask_sensitive_args(self, args):
66+
if isinstance(args, dict):
67+
return mask_mbi(dict)
68+
69+
return tuple([mask_if_has_mbi(arg) for arg in args])

hhs_oauth_server/request_logging.py

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import datetime
22
import hashlib
33
import json
4-
import re
54
import uuid
65

76
import apps.logging.request_logger as logging
@@ -23,9 +22,7 @@
2322
)
2423

2524
audit = logging.getLogger("audit.%s" % __name__)
26-
MBI_WITH_HYPHEN_PATTERN = r'\b\d[A-Z]{2}\d-[A-Z]{2}\d-[A-Z]{2}\d{2}\b'
27-
MBI_WITHOUT_HYPHEN_PATTERN = r'\b[1-9](?![SLOIBZ])[A-Z](?![SLOIBZ)])[A-Z\d]\d(?![SLOIBZ])[A-Z](?![SLOIBZ])[A-Z\d]\d(?![SLOIBZ])[A-Z]{2}\d{2}\b'
28-
MBI_PATTERN = f'({MBI_WITH_HYPHEN_PATTERN}|{MBI_WITHOUT_HYPHEN_PATTERN})'
25+
2926

3027
class RequestResponseLog(object):
3128
"""Audit log message to JSON string
@@ -140,20 +137,13 @@ def __init__(self, req, resp):
140137
self.log_msg["location"] = ""
141138
self.log_msg["size"] = 0
142139

143-
144-
def has_mbi_match(text):
145-
return bool(re.search(MBI_PATTERN, text))
146-
147-
def mask_if_has_mbi(text):
148-
return re.sub(MBI_PATTERN, '***MBI***', text)
149-
150140
def _log_msg_update_from_dict(self, from_dict, key, dict_key):
151141
# Log message update from a passed in dictionary
152142
try:
153143
value = from_dict.get(dict_key, None)
154144
if value is not None:
155145
if len(str(value)) > 0:
156-
self.log_msg[key] = self.mask_if_has_mbi(value)
146+
self.log_msg[key] = value
157147
except ObjectDoesNotExist:
158148
self.log_msg[key] = (
159149
"ObjectDoesNotExist exception for key " + key + ":" + dict_key
@@ -169,7 +159,7 @@ def _log_msg_update_from_object(self, obj, key, obj_key):
169159
value = getattr(obj, obj_key, None)
170160
if value is not None:
171161
if len(str(value)) > 0:
172-
self.log_msg[key] = self.mask_if_has_mbi(value)
162+
self.log_msg[key] = value
173163
except ObjectDoesNotExist:
174164
self.log_msg[key] = (
175165
"ObjectDoesNotExist exception for key " + key + ":" + obj_key
@@ -184,7 +174,6 @@ def _log_msg_update_from_querydict(self, key, qp_key):
184174
try:
185175
value_list = self.request.GET.getlist(qp_key, None)
186176
if value_list is not None:
187-
value_list = [self.mask_if_has_mbi(value) for value in value_list]
188177
if len(value_list) == 1:
189178
self.log_msg[key] = value_list[0]
190179
elif len(value_list) > 1:
@@ -532,8 +521,8 @@ def to_dict(self):
532521
except ObjectDoesNotExist:
533522
pass
534523
self._sync_app_name()
535-
masked_logged_dict = {key: self.mask_if_has_mbi(value) for key, value in self.log_msg.items()}
536-
return masked_logged_dict
524+
525+
return self.log_msg
537526

538527
##############################################################################
539528
#

hhs_oauth_server/settings/base.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import os
2+
from apps.logging.sensitive_logging_filters import SENSITIVE_DATA_FILTER, SensitiveDataFilter
23
import dj_database_url
34
import socket
45
import datetime
@@ -377,6 +378,12 @@
377378
"console": {
378379
"class": "logging.StreamHandler",
379380
"formatter": "verbose",
381+
"filters": [SENSITIVE_DATA_FILTER],
382+
}
383+
},
384+
"filters": {
385+
"sensitive_data_filter": {
386+
"()": SensitiveDataFilter,
380387
}
381388
},
382389
"loggers": {
@@ -421,6 +428,11 @@
421428
"handlers": ["console"],
422429
"level": "INFO",
423430
},
431+
'django': {
432+
'handlers': ['console'],
433+
'level': 'INFO',
434+
'propagate': True,
435+
},
424436
},
425437
},
426438
)

hhs_oauth_server/settings/logging_it.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
raise ValueError("Bad settings, expecting handlers defined in settings.LOGGING")
2222

2323
logging_handlers['file'] = {'class': 'logging.FileHandler',
24-
'filename': logfile_path, }
24+
'filename': logfile_path,
25+
"filters": [SENSITIVE_DATA_FILTER]}
2526

2627
loggers = LOGGING.get('loggers')
2728

0 commit comments

Comments
 (0)