[Python-Dev] Hash collision security issue (now public)
steve at pearwood.info
Fri Jan 6 02:52:45 CET 2012
Benjamin Peterson wrote:
> 2012/1/5 Nick Coghlan <ncoghlan at gmail.com>:
>> On Fri, Jan 6, 2012 at 10:07 AM, Steven D'Aprano <steve at pearwood.info> wrote:
>>> Surely the way to verify the behaviour is to run this from the shell:
>>> python -c print(hash("abcde"))
>>> twice, and see that the calls return different values. (Or have I
>>> misunderstood the way the fix is going to work?)
>>> In any case, I wouldn't want to rely on the presence of a flag in the sys
>>> module to verify the behaviour, I'd want to see for myself that hash
>>> collisions are no longer predictable.
>> More directly, you can just check that the hash of the empty string is non-zero.
>> So -1 for a flag in the sys module - "hash('') != 0" should serve as a
>> sufficient check whether or not process-level string hash
>> randomisation is in effect.
> What exactly is the disadvantage of a sys attribute? That would seem
> preferable to an obscure incarnation like that.
There's nothing obscure about directly testing the hash. That's about as far
from obscure as it is possible to get: you are directly testing the presence
of a feature by testing the feature.
Relying on a flag to tell you whether hashes are randomised adds additional
complexity: now you need to care about whether hashes are randomised AND know
that there is a flag you can look up and what it is called.
And since the flag won't exist in all versions of Python, or even in all
builds of a particular Python version, it isn't a matter of just testing the
flag, but of doing the try...except or hasattr() dance to check whether it
At some point, presuming that there is no speed penalty, the behaviour will
surely become not just enabled by default but mandatory. Python has never
promised that hashes must be predictable or consistent, so apart from
backwards compatibility concerns for old versions, future versions of Python
should make it mandatory. Presuming that there is no speed penalty, I'd argue
in favour of making it mandatory for 3.3. Why do we need a flag for something
that is going to be always on?
More information about the Python-Dev