2010-11-11 21 views
2

我想允許人們提供一個哈希函數的名稱的數字指紋某些目的的手段:在Python安全評估字符串調用hashlib

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

回答

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。

1
import hashlib 

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

我覺得這樣更安全比使用的eval()

+1

這仍然是容易出錯的最小值(調用的任何屬性hashlib)。他應該確保只有「白名單」功能可以被調用。 – gahooa 2010-11-11 22:17:02

+0

@gahooa:這段代碼更EAFP所以如果散列方法不存在,它會引發一個錯誤,這是沒問題:) – mouad 2010-11-11 22:19:16

+0

@gahooa:啊我看到你確實在你的答案中放了一些允許的散列方法嗯,是的好點,但它不是我從OP問題中所理解的:),但仍然很好,你只需完成OP問題並添加了答案:) – mouad 2010-11-11 22:21:09

4

如果應用一些SQL注入攻擊的概念,這將是conceviable爲用戶電源是這樣的:

"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
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)