27
27
from __future__ import absolute_import
28
28
29
29
import io
30
+ import json
30
31
import logging
31
32
import socket
32
33
import ssl
60
61
"HTTPError"
61
62
]
62
63
64
+ SENSITIVE_KEYS = ['Authorization' , 'Cookie' , 'action.email.auth_password' , 'auth' , 'auth_password' , 'clear_password' , 'clientId' ,
65
+ 'crc-salt' , 'encr_password' , 'oldpassword' , 'passAuth' , 'password' , 'session' , 'suppressionKey' ,
66
+ 'token' ]
67
+
63
68
# If you change these, update the docstring
64
69
# on _authority as well.
65
70
DEFAULT_HOST = "localhost"
66
71
DEFAULT_PORT = "8089"
67
72
DEFAULT_SCHEME = "https"
68
73
74
+
69
75
def _log_duration (f ):
70
76
@wraps (f )
71
77
def new_f (* args , ** kwargs ):
@@ -77,6 +83,28 @@ def new_f(*args, **kwargs):
77
83
return new_f
78
84
79
85
86
+ def mask_sensitive_data (data ):
87
+ '''
88
+ Masked sensitive fields data for logging purpose
89
+ '''
90
+ if not isinstance (data , dict ):
91
+ try :
92
+ data = json .loads (data )
93
+ except Exception as ex :
94
+ return data
95
+
96
+ # json.loads will return "123"(str) as 123(int), so return the data if it's not 'dict' type
97
+ if not isinstance (data , dict ):
98
+ return data
99
+ mdata = {}
100
+ for k , v in data .items ():
101
+ if k in SENSITIVE_KEYS :
102
+ mdata [k ] = "******"
103
+ else :
104
+ mdata [k ] = mask_sensitive_data (v )
105
+ return mdata
106
+
107
+
80
108
def _parse_cookies (cookie_str , dictionary ):
81
109
"""Tries to parse any key-value pairs of cookies in a string,
82
110
then updates the the dictionary with any key-value pairs found.
@@ -631,7 +659,7 @@ def delete(self, path_segment, owner=None, app=None, sharing=None, **query):
631
659
"""
632
660
path = self .authority + self ._abspath (path_segment , owner = owner ,
633
661
app = app , sharing = sharing )
634
- logger .debug ("DELETE request to %s (body: %s)" , path , repr (query ))
662
+ logger .debug ("DELETE request to %s (body: %s)" , path , mask_sensitive_data (query ))
635
663
response = self .http .delete (path , self ._auth_headers , ** query )
636
664
return response
637
665
@@ -694,7 +722,7 @@ def get(self, path_segment, owner=None, app=None, headers=None, sharing=None, **
694
722
695
723
path = self .authority + self ._abspath (path_segment , owner = owner ,
696
724
app = app , sharing = sharing )
697
- logger .debug ("GET request to %s (body: %s)" , path , repr (query ))
725
+ logger .debug ("GET request to %s (body: %s)" , path , mask_sensitive_data (query ))
698
726
all_headers = headers + self .additional_headers + self ._auth_headers
699
727
response = self .http .get (path , all_headers , ** query )
700
728
return response
@@ -773,12 +801,7 @@ def post(self, path_segment, owner=None, app=None, sharing=None, headers=None, *
773
801
774
802
path = self .authority + self ._abspath (path_segment , owner = owner , app = app , sharing = sharing )
775
803
776
- # To avoid writing sensitive data in debug logs
777
- endpoint_having_sensitive_data = ["/storage/passwords" ]
778
- if any (endpoint in path for endpoint in endpoint_having_sensitive_data ):
779
- logger .debug ("POST request to %s " , path )
780
- else :
781
- logger .debug ("POST request to %s (body: %s)" , path , repr (query ))
804
+ logger .debug ("POST request to %s (body: %s)" , path , mask_sensitive_data (query ))
782
805
all_headers = headers + self .additional_headers + self ._auth_headers
783
806
response = self .http .post (path , all_headers , ** query )
784
807
return response
@@ -845,8 +868,7 @@ def request(self, path_segment, method="GET", headers=None, body={},
845
868
846
869
all_headers = headers + self .additional_headers + self ._auth_headers
847
870
logger .debug ("%s request to %s (headers: %s, body: %s)" ,
848
- method , path , str (all_headers ), repr (body ))
849
-
871
+ method , path , str (mask_sensitive_data (dict (all_headers ))), mask_sensitive_data (body ))
850
872
if body :
851
873
body = _encode (** body )
852
874
0 commit comments