是否存在以下危险?像这样,如果有人将此异常打印到stdout
上,代码是否可以执行?
def somefunc(val_from_untrusted_source):
if val_from_untrusted_source == 'something_we_except':
# do something useful
pass
else:
raise RuntimeException('unknown input: {}'.format(val_from_untrusted_source))
答案 0 :(得分:2)
永远不要这样!
日志消息旨在告知有关处理的信息,应安全地发送日志消息,以查找问题发生时发生的情况的证据。这里没有控制权,所以这里有一些可能的问题:
str(val_from_untrusted_source)
本身可能会引发一个异常,其中UnicodeEncodeError
对于Python 2中包含非ASCII字符的Unicode字符串,或者UnicodeDecodeError
对于Python 3中包含非ASCII字符的字节字符串。还包括特制的带有引发异常的__str__
方法的对象 str(val_from_untrusted_source)
可以是一个looooong字符串。它包括长字节或unicode字符串,还包括特制的微小对象:
class DONT:
def __init__(self, size, pattern):
self.pattern = pattern
self.size = size
def __str__(self):
return self.pattern * self.size
它们可能导致日志文件耗尽磁盘空间
__str__
方法或试图耗尽内存的方法来特殊设计对象。试想一下DONT
... 这就是在代码不受控制的最坏用例中可能发生的一切。在更实际的使用场景中,val_from_untrusted_source
可能是字符串。在那种情况下,限制它的大小并处理UnicodeError
异常就足够了:
if val_from_untrusted_source == 'something_we_except':
# do something useful
pass
else:
try:
txt = str(val_from_untrusted_source)
except UnicodeEncodeError: # unicode string on Python 2
txt = val_from_untrusted_source.encode(error = 'replace')
except UnicodeDecodeError: # byte string on Python 3
txt = val_from_untrusted_source.decode(error = 'replace')
except Exception: # quite weird but once we are there...
txt = "object non convertible to string"
if len(text) > 47): # limit length to 50
txt = txt[:47] + '...'
raise RuntimeException('unknown input: {}'.format(txt))
答案 1 :(得分:1)
据我所知,没有什么危险。最不愉快的后果:
val_from_untrusted_source
不是ASCII,则在尝试提高UnicodeEncodeError
时会发生RuntimeException
val_from_untrusted_source
包含'\ r',并且有人将此异常写入日志-当前日志行的开头可能会被覆盖