def is_allowed_getattr(self, name, safe=True): # TODO this API is ugly. if not safe: # Unsafe is mostly used to check for __getattr__/__getattribute__. # getattr_static works for properties, but the underscore methods # are just ignored (because it's safer and avoids more code # execution). See also GH #1378. # Avoid warnings, see comment in the next function. with warnings.catch_warnings(record=True): warnings.simplefilter("always") try: return hasattr(self._obj, name), False except Exception: # Obviously has an attribute (propably a property) that # gets executed, so just avoid all exceptions here. return False, False try: attr, is_get_descriptor = getattr_static(self._obj, name) except AttributeError: return False, False else: if is_get_descriptor and type( attr) not in ALLOWED_DESCRIPTOR_ACCESS: # In case of descriptors that have get methods we cannot return # it's value, because that would mean code execution. return True, True return True, False
def is_allowed_getattr(self, name): # TODO this API is ugly. try: attr, is_get_descriptor = getattr_static(self._obj, name) except AttributeError: return False, False else: if is_get_descriptor and type( attr) not in ALLOWED_DESCRIPTOR_ACCESS: # In case of descriptors that have get methods we cannot return # it's value, because that would mean code execution. return True, True return True, False
def safe_getattr(obj, name, default=_sentinel): try: attr, is_get_descriptor = getattr_static(obj, name) except AttributeError: if default is _sentinel: raise return default else: if isinstance(attr, ALLOWED_DESCRIPTOR_ACCESS): # In case of descriptors that have get methods we cannot return # it's value, because that would mean code execution. # Since it's an isinstance call, code execution is still possible, # but this is not really a security feature, but much more of a # safety feature. Code execution is basically always possible when # a module is imported. This is here so people don't shoot # themselves in the foot. return getattr(obj, name) return attr