[Security-sig] RFC: PEP: Make os.urandom() blocking on Linux

Cory Benfield cory at lukasa.co.uk
Wed Jun 22 06:13:28 EDT 2016


> On 21 Jun 2016, at 23:57, Barry Warsaw <barry at python.org> wrote:
> 
> At a minimum, I think a proper treatment of the alternative where os.urandom()
> remains (on Linux at least) a thin wrapper around /dev/urandom.  We would add
> os.getrandom() as the low-level interface to the new C lib function, and
> expose any higher level functionality in the secrets module if necessary.
> Then we would also add a strong admonition to the documentation explaining the
> trade-offs between os.urandom() and os.getrandom() and point people to the
> latter for strong crypto use cases.

I’d like to explore this approach further.

In a model like this, os.getrandom() would basically need to have, in its documentation, a recipe for using it in a general-purpose, cross-OS manner. That recipe would be, at minimum, an admonition to use the secrets module.

However, if we’re going to implement an entire function in order to say “Do not use this, use secrets instead”, why are we bothering? Why add the API surface and a function that needs to be maintained? Why not just make the use of getrandom a private implementation detail of secrets?

Making getrandom() a private detail of secrets has the advantage of freeing us from some backward compatibility concerns, which as we’ve identified are a real problem here. Given that there’s no understandable use case where someone would write anything but "try: os.getrandom(); except AttributeError: os.urandom”, it doesn’t seem sensible to give people the option to get this wrong.

The other way to approach this is to have os.getrandom() do the appropriate dance, but others have suggested that the os module is intended only to be thin wrappers around things that the OS provides (a confusing argument given that closerange() exists, but that’s by the by).

> Your proto-PEP uses this as a rationale:
> 
>    Security experts promotes ``os.urandom()`` to genereate cryptographic
>    keys, even instead of ``ssl.RAND_bytes()``.
> 
> and that's been a commonly cited reason for why strengthening os.urandom() is
> preferable to adding a more direct mapping to the underlying function that
> provides that strengthened randomness.  If if the assertion is true -and
> respectfully, it isn't backed up by any actual citations in the proto-PEP- it
> doesn't make it right.  It's also a bad precedence to follow IMHO.  Where do
> we draw the line in changing existing APIs to their use or misuse as the case
> may be?

Here’s some relevant citations:

- https://stackoverflow.com/questions/10341112/whats-more-random-hashlib-or-urandom
- https://cryptography.io/en/latest/random-numbers/
- https://code.google.com/p/googleappengine/issues/detail?id=1055

However, I don’t think I agree with your assertion that it’s a bad precedent. I think the bad precedent is introducing new functions that do what the old functions should have done. Some examples of this:

- yaml.safe_load, introduced to replace yaml.load which leads to documents like this: https://security.openstack.org/guidelines/dg_avoid-dangerous-input-parsing-libraries.html#incorrect
- PHP’s mysql_real_escape_string, introduced to replace mysql_escape_string, which leads to misguided questions like this one: https://security.stackexchange.com/questions/8028/does-mysql-escape-string-have-any-security-vulnerabilities-if-all-tables-using-l

Each of these functions has been a never-ending supply of security vulnerabilities because they encourage users to fall into a pit of failure. Users who are not sufficiently defensive when approaching their code will reach for the most obvious tool in the box, and the Python cryptographic community has spent a long time making os.urandom() the most obvious tool in the box because no other tool was available. The argument, then, is that we should make that tool better, rather than build a new tool and let the old one fester.

> We can discuss whether your proposal or my[*] alternative is the right one for
> Python to follow, and I may lose that argument, but I think it's only proper
> and fair to represent this point of view in this proto-PEP.  I do not think a
> separate competing PEP is appropriate.

I agree with this. The PEP should accurately represent competing views, even if it doesn’t agree with them.

Cory


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://mail.python.org/pipermail/security-sig/attachments/20160622/6733ed92/attachment.sig>


More information about the Security-SIG mailing list