On Jun 22, 2016, at 11:13 AM, Cory Benfield wrote: >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?
Because the os module has traditionally surfaced lower-level operating system functions, so os.getrandom() would be an extension of this. That's also why I advocate simplifying os.urandom() so that it reverts more or less to exposing /dev/urandom to Python. With perhaps a few exceptions, os doesn't provide higher level APIs. The point here is that, let's say you're an experienced Linux developer and you know you want to use getrandom(2) in Python. os.getrandom() is exactly that. It's completely analogous to why we provide, e.g. os.chroot() and such. Now, let's say you just want some guaranteed high quality random bytes, and you don't really know or care what's being used. The lower level os functions are *not* the right APIs to use, but secrets is. That's why the documentation points people over there for better, higher-level APIs, and it's there that we have the freedom to change underlying implementation as needed to deliver on the promised improved security. >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. I agree. >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. This doesn't follow though. Again, it's about providing low-level Python bindings to underlying operation system functions in os, and higher level APIs with more cross-platform guarantees in secret. >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). As I mentioned, there are exceptions (os.makedirs() is the other one that comes to mind), but I do think the rule for os should be -and has usually traditionally been- exactly as you say. OTOH, neither os.makedirs() nor os.closerange() are that far removed from their lower level cousins, so that's a practicality over purity justification. >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. I don't agree that any of this is what os.urandom() should have done. It's that people have used it for other purposes and changed what they think it should have done. Now we're redefining os.urandom() to fit that new purpose. That's the bad precedence IMHO. Cheers, -Barry
pgp7AmXQOgCmW.pgp
Description: OpenPGP digital signature
_______________________________________________ Security-SIG mailing list Security-SIG@python.org https://mail.python.org/mailman/listinfo/security-sig