在Python中安全地评估字符串以调用hashlib

时间:2010-11-11 22:10:12

标签: python

我想允许人们提供哈希函数的名称作为数字指纹识别某些对象的方法:

def create_ref(obj, hashfn='sha256'):
    """
    Returns a tuple of hexdigest and the method used to generate
    the digest.

    >>> create_ref({}, 'sha1')
    ('bf21a9e8fbc5a3846fb05b4fa0859e0917b2202f', 'sha1')
    >>> create_ref({}, 'md5')
    ('99914b932bd37a50b983c5e7c90ae93b', 'md5')
    """
    return (eval('hashlib.%s' % hashfn)(unicode(obj)).hexdigest(), hashfn)

硬编码hashlib是否足够强大以防止滥用eval

4 个答案:

答案 0 :(得分:4)

如果您应用了一些SQL注入攻击概念,那么用户可以提供类似这样的内容:

"sha1(...); some_evil_code(); hashlib.sha1"

这样可以完全打破这种“安全”:这样结束:

"hashlib." + "sha1(...); some_evil_code(); hashlib.sha1" + "(your-original-code)"

这将导致3个语句被运行(一个罚款,一个恶,一个罚款)。

(即使上面的代码中有漏洞,仍然可以利用这个概念)


相反,使用python的动态功能来完成这项工作!

TYPES = ('sha256', 'sha1', 'md5', ...)
def create_ref(obj, hashfn='sha256'):
   if hashfn not in TYPES:
      raise ValueError("bad type")

   # look up the actual method
   fun = getattr(hashlib, hashfn)

   # and call it on `obj`
   fun(...)

深思熟虑!

答案 1 :(得分:2)

而不是eval,请尝试以下代码:

def create_ref(obj, hashfn='sha256'):
    """
    Returns a tuple of hexdigest and the method used to generate
    the digest.

    >>> create_ref({}, 'sha1')
    ('bf21a9e8fbc5a3846fb05b4fa0859e0917b2202f', 'sha1')
    >>> create_ref({}, 'md5')
    ('99914b932bd37a50b983c5e7c90ae93b', 'md5')
    """
    allowed = hashlib.algorithms
    if hashfn in allowed:
        return (getattr(hashlib,hashfn)(unicode(obj)).hexdigest(), hashfn)
    else:
        raise NameError('Not a valid algorithm')

这将保证所提供的算法是有效的算法。 (请注意,hashlib.algorithms在2.7中是新的,因此如果您使用旧版本,请将hashlib.algorithms替换为允许的算法元组。

答案 2 :(得分:1)

import hashlib

...
return (getattr(hashlib, hashfn)(unicode(obj)).hexdigest(), hashfn)

我认为这比使用eval()

更安全

答案 3 :(得分:-1)

TYPES = {'sha256':hashlib.sha256 , 'sha1': hashlib.sha1, 'md5': hashlib.md5, ...}
def create_ref(obj, hashfn='sha256'):
    #var 1 - use sha256 as default on invalid hashfun
    #func=TYPES.get(hashfn, hashlib.sha256)

    #var 2 raise error on invalid hashfun
    if TYPES.has_key(hashfn):
        func=TYPES[hashfn]
    else:
        raise NameError('Not a valid algorithm')
    return (func(unicode(obj)).hexdigest(), hashfn)