将不受信任的来源的信息作为python异常消息放置是否安全?

时间:2018-06-22 10:22:38

标签: python security code-injection

是否存在以下危险?像这样,如果有人将此异常打印到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))

2 个答案:

答案 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)

据我所知,没有什么危险。最不愉快的后果:

  1. (如果假定使用Python 2)如果val_from_untrusted_source不是ASCII,则在尝试提高UnicodeEncodeError时会发生RuntimeException
  2. 如果val_from_untrusted_source包含'\ r',并且有人将此异常写入日志-当前日志行的开头可能会被覆盖