2727from __future__ import absolute_import
2828
2929import io
30+ import json
3031import logging
3132import socket
3233import ssl
6061 "HTTPError"
6162]
6263
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+
6368# If you change these, update the docstring
6469# on _authority as well.
6570DEFAULT_HOST = "localhost"
6671DEFAULT_PORT = "8089"
6772DEFAULT_SCHEME = "https"
6873
74+
6975def _log_duration (f ):
7076 @wraps (f )
7177 def new_f (* args , ** kwargs ):
@@ -77,6 +83,28 @@ def new_f(*args, **kwargs):
7783 return new_f
7884
7985
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+
80108def _parse_cookies (cookie_str , dictionary ):
81109 """Tries to parse any key-value pairs of cookies in a string,
82110 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):
631659 """
632660 path = self .authority + self ._abspath (path_segment , owner = owner ,
633661 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 ))
635663 response = self .http .delete (path , self ._auth_headers , ** query )
636664 return response
637665
@@ -694,7 +722,7 @@ def get(self, path_segment, owner=None, app=None, headers=None, sharing=None, **
694722
695723 path = self .authority + self ._abspath (path_segment , owner = owner ,
696724 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 ))
698726 all_headers = headers + self .additional_headers + self ._auth_headers
699727 response = self .http .get (path , all_headers , ** query )
700728 return response
@@ -773,12 +801,7 @@ def post(self, path_segment, owner=None, app=None, sharing=None, headers=None, *
773801
774802 path = self .authority + self ._abspath (path_segment , owner = owner , app = app , sharing = sharing )
775803
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 ))
782805 all_headers = headers + self .additional_headers + self ._auth_headers
783806 response = self .http .post (path , all_headers , ** query )
784807 return response
@@ -845,8 +868,7 @@ def request(self, path_segment, method="GET", headers=None, body={},
845868
846869 all_headers = headers + self .additional_headers + self ._auth_headers
847870 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 ))
850872 if body :
851873 body = _encode (** body )
852874
0 commit comments