当前位置: 动力学知识库 > 问答 > 编程问答 >

Safely evaluate string in Python to call hashlib

问题描述:

I would like to allow people to provide the name of a hash function as a means of digitally fingerprinting some object:

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)

Is hard coding hashlib sufficently robust to prevent abuse of eval?

网友答案:

instead of eval, try this code:

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

This will guarantee that the algorithm provided is a valid algorithm. (Note that hashlib.algorithms is new in 2.7, so if you use an older version, replace hashlib.algorithms with a tuple of allowed algorithms.

网友答案:

No.

If you apply some of the SQL Injection attack concepts, it would be conceviable for the user to supply something like this:

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

Which would totally blow the "security" away by ending up like this:

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

Which would result in 3 statements being run (a fine one, and evil one, and a fine one).

(even if the above code has holes in it, the concept could still be exploited)


Instead, use the dynamic power of python to make this work!

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(...)

Food for thought!

网友答案:
import hashlib

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

i think like this is more safely than using eval()

网友答案:
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)
分享给朋友:
您可能感兴趣的文章:
随机阅读: