Skip to content

Commit a8d2e0a

Browse files
author
Inbal Tako
committed
Support pii data remove from config
1 parent 0c66cdb commit a8d2e0a

File tree

5 files changed

+100
-8
lines changed

5 files changed

+100
-8
lines changed

securenative/config/configuration_manager.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,9 @@ def load_config(cls, resource_path):
6969
"SECURENATIVE_FAILOVER_STRATEGY",
7070
options.fail_over_strategy),
7171
proxy_headers=cls._get_env_or_default(properties, "SECURENATIVE_PROXY_HEADERS",
72-
options.proxy_headers))
72+
options.proxy_headers),
73+
pii_headers=cls._get_env_or_default(properties, "SECURENATIVE_PII_HEADERS",
74+
options.pii_headers),
75+
pii_regex_pattern=cls._get_env_or_default(properties,
76+
"SECURENATIVE_PII_REGEX_PATTERN",
77+
options.pii_regex_pattern))

securenative/config/securenative_options.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ class SecureNativeOptions(object):
55

66
def __init__(self, api_key=None, api_url="https://api.securenative.com/collector/api/v1", interval=1000,
77
max_events=1000, timeout=1500, auto_send=True, disable=False, log_level="CRITICAL",
8-
fail_over_strategy=FailOverStrategy.FAIL_OPEN.value, proxy_headers=None):
8+
fail_over_strategy=FailOverStrategy.FAIL_OPEN.value, proxy_headers=None,
9+
pii_headers=None, pii_regex_pattern=None):
910

1011
if proxy_headers is None:
1112
proxy_headers = []
@@ -24,3 +25,5 @@ def __init__(self, api_key=None, api_url="https://api.securenative.com/collector
2425
self.disable = disable
2526
self.log_level = log_level
2627
self.proxy_headers = proxy_headers
28+
self.pii_headers = pii_headers
29+
self.pii_regex_pattern = pii_regex_pattern

securenative/context/securenative_context.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def from_http_request(request, options):
2121
client_token = None
2222

2323
try:
24-
headers = RequestUtils.get_headers_from_request(request.headers)
24+
headers = RequestUtils.get_headers_from_request(request.headers, options)
2525
except Exception:
2626
headers = None
2727

securenative/utils/request_utils.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import re
2+
13
from securenative.utils.ip_utils import IpUtils
24

35

@@ -16,7 +18,7 @@ def get_secure_header_from_request(headers):
1618

1719
@staticmethod
1820
def get_client_ip_from_request(request, options):
19-
if options and len(options.proxy_headers) > 0:
21+
if options and options.proxy_headers and len(options.proxy_headers) > 0:
2022
for header in options.proxy_headers:
2123
try:
2224
if request.environ.get(header) is not None:
@@ -79,10 +81,19 @@ def get_valid_ip(ips):
7981
return ip
8082

8183
@staticmethod
82-
def get_headers_from_request(headers):
84+
def get_headers_from_request(headers, options=None):
8385
h = {}
84-
for header in headers:
85-
if header not in RequestUtils.PII_HEADERS and header.upper() not in RequestUtils.PII_HEADERS:
86-
h[header] = headers[header]
86+
if options and options.pii_headers and len(options.pii_headers) > 0:
87+
for header in headers:
88+
if header not in options.pii_headers and header.upper() not in options.pii_headers:
89+
h[header] = headers[header]
90+
elif options and options.pii_regex_pattern:
91+
for header in headers:
92+
if not re.search(options.pii_regex_pattern, header):
93+
h[header] = headers[header]
94+
else:
95+
for header in headers:
96+
if header not in RequestUtils.PII_HEADERS and header.upper() not in RequestUtils.PII_HEADERS:
97+
h[header] = headers[header]
8798

8899
return h

tests/request_utils_test.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,3 +343,76 @@ def test_strip_down_pii_data_from_headers(self):
343343
self.assertEqual(h.get('passwd'), None)
344344
self.assertEqual(h.get('secret'), None)
345345
self.assertEqual(h.get('api_key'), None)
346+
347+
def test_strip_down_pii_data_from_custom_headers(self):
348+
headers = {
349+
'Host': 'net.example.com',
350+
'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)',
351+
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
352+
'Accept-Language': 'en-us,en;q=0.5',
353+
'Accept-Encoding': 'gzip,deflate',
354+
'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
355+
'Keep-Alive': '300',
356+
'Connection': 'keep-alive',
357+
'Cookie': 'PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120',
358+
'Pragma': 'no-cache',
359+
'Cache-Control': 'no-cache',
360+
'authorization': 'ylSkZIjbdWybfs4fUQe9BqP0LH5Z',
361+
'access_token': 'ylSkZIjbdWybfs4fUQe9BqP0LH5Z',
362+
'apikey': 'ylSkZIjbdWybfs4fUQe9BqP0LH5Z',
363+
'password': 'ylSkZIjbdWybfs4fUQe9BqP0LH5Z',
364+
'passwd': 'ylSkZIjbdWybfs4fUQe9BqP0LH5Z',
365+
'secret': 'ylSkZIjbdWybfs4fUQe9BqP0LH5Z',
366+
'api_key': 'ylSkZIjbdWybfs4fUQe9BqP0LH5Z'
367+
}
368+
369+
with requests_mock.Mocker(real_http=True) as request:
370+
request.headers = headers
371+
372+
options = SecureNativeOptions(pii_headers=['authorization', 'access_token', 'apikey', 'password',
373+
'passwd', 'secret', 'api_key'])
374+
h = RequestUtils.get_headers_from_request(request.headers, options)
375+
376+
self.assertEqual(h.get('authorization'), None)
377+
self.assertEqual(h.get('access_token'), None)
378+
self.assertEqual(h.get('apikey'), None)
379+
self.assertEqual(h.get('password'), None)
380+
self.assertEqual(h.get('passwd'), None)
381+
self.assertEqual(h.get('secret'), None)
382+
self.assertEqual(h.get('api_key'), None)
383+
384+
def test_strip_down_pii_data_from_regex_pattern(self):
385+
headers = {
386+
'Host': 'net.example.com',
387+
'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)',
388+
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
389+
'Accept-Language': 'en-us,en;q=0.5',
390+
'Accept-Encoding': 'gzip,deflate',
391+
'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
392+
'Keep-Alive': '300',
393+
'Connection': 'keep-alive',
394+
'Cookie': 'PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120',
395+
'Pragma': 'no-cache',
396+
'Cache-Control': 'no-cache',
397+
'http_auth_authorization': 'ylSkZIjbdWybfs4fUQe9BqP0LH5Z',
398+
'http_auth_access_token': 'ylSkZIjbdWybfs4fUQe9BqP0LH5Z',
399+
'http_auth_apikey': 'ylSkZIjbdWybfs4fUQe9BqP0LH5Z',
400+
'http_auth_password': 'ylSkZIjbdWybfs4fUQe9BqP0LH5Z',
401+
'http_auth_passwd': 'ylSkZIjbdWybfs4fUQe9BqP0LH5Z',
402+
'http_auth_secret': 'ylSkZIjbdWybfs4fUQe9BqP0LH5Z',
403+
'http_auth_api_key': 'ylSkZIjbdWybfs4fUQe9BqP0LH5Z'
404+
}
405+
406+
with requests_mock.Mocker(real_http=True) as request:
407+
request.headers = headers
408+
409+
options = SecureNativeOptions(pii_regex_pattern='((?i)(http_auth_)(\w+)?)')
410+
h = RequestUtils.get_headers_from_request(request.headers, options)
411+
412+
self.assertEqual(h.get('http_auth_authorization'), None)
413+
self.assertEqual(h.get('http_auth_access_token'), None)
414+
self.assertEqual(h.get('http_auth_apikey'), None)
415+
self.assertEqual(h.get('http_auth_password'), None)
416+
self.assertEqual(h.get('http_auth_passwd'), None)
417+
self.assertEqual(h.get('http_auth_secret'), None)
418+
self.assertEqual(h.get('http_auth_api_key'), None)

0 commit comments

Comments
 (0)