[Python-ideas] PEP 504: Using the system RNG by default

Steven D'Aprano steve at pearwood.info
Wed Sep 16 17:54:13 CEST 2015

On Wed, Sep 16, 2015 at 03:59:04PM +1000, Nick Coghlan wrote:

> Accordingly, my proposal is aimed as much at eliminating the perennial
> "But *why* can't I use the random module for security sensitive
> tasks?" argument as it is at anything else. I'd like the answer to
> that question to eventually be "Sure, you can use the random module
> for security sensitive tasks, so let's talk about something more
> important, like why you're collecting and storing all this sensitive
> personally identifiable information in the first place".

The answer to that question is *already* "sure you can use the random 
module". You just have to use it correctly.

[Aside: do you think that, having given companies and people a "secure 
by default" solution that will hopefully prevent data breaches, that 
they will be *more* or *less* open to the idea that they shouldn't be 
collecting this sensitive information?]

We've spent a long time taking about random() as regards to security, 
but nobody exposes the output of random directly. They use it as a 
building block to generate tokens and passwords, and *that's* where the 
breech is occurring. We shouldn't care so much about the building blocks 
and care more about the high-level tools: the batteries included.

Look at the example given by Nathaniel:


What was remarkable about this is how many individual factors were 
involved in the attacks. It wasn't merely an attack on Mersenne Twister, 
and it is quite possible that had any of the other factors been changed, 
the attacks would have failed.

E.g. the applications used MD5 hashes. What if they had used SHA-1? They 
leaked sensitive information such as PIDs and exposed the time that the 
random numbers where generated. They allowed the attackers to get as 
many connections as they wanted.

Someone might argue that none of those other problems would matter if 
the PRNG was more secure. That's true, up to a point: you never know 
when somebody will come up with an attack on the CSPRNG. Previous 
generations of CSPRNGs, including RC4, have been "retired", and we must 
expect that the current generation will be too. It is a good habit to 
avoid leaking this sort of information (times, PIDs etc) even if you 
don't have a concrete attack in place, because you don't know when a 
concrete attack will be discovered. Today's CSPRNG is tomorrow's 
hopelessly insecure PRNG, but defence is depth is always useful.

I propose that instead of focusing on changing the building 
blocks that people will use by default, we provide them with ready made 
batteries for the most common tasks, and provide a clear example of 
acceptable practices for making their own batteries. (As usual, the 
standard lib will provide batteries, and third-party frameworks or 
libraries can provide heavy-duty nuclear reactors.)

I propose:

- The random module's API is left as-is, including the default PRNG. 
  Backwards compatibility is important, code-churn is bad, and there are 
  good use-cases for a non-CSPRNG.

- We add at least one CSPRNG. I leave it to the crypto-wonks to decide 

- We add a new module, which I'm calling "secrets" (for lack of a better 
  name) to hold best-practice security-related functions. To start with,
  it would have at least these three functions: one battery, and two 
  building blocks:

  + secrets.token to create password recovery tokens or similar;

  + secrets.random calls the CSPRNG; it just returns a random number 
    (integer?). There is no API for getting or setting the state, 
    setting the seed, or returning values from non-uniform 

  + secrets.choice similarly uses the CSPRNG.

Developers will still have to make a choice: "do I use secrets, or 
random?" If they're looking for a random token (or password?), the 
answer is obvious: use secrets, because the battery is already there. 
For reasons that I will go into below, I don't think that requiring this 
choice is a bad thing. I think it is a *good* thing.

secrets becomes the go-to module for things you want to keep secret. 
random remains the module you use for games and simulations.

If there is interest in this proposed secrets module, I'll write up a 
proto-PEP over the weekend, and start a new thread for the benefit of 
those who have muted this one.

You can stop reading now. The rest is motivational rather than part of 
the concrete proposal.

Still here? Okay.

I think that it is a good thing to have developers explicitly make a 
choice between random and secrets. I think it is important that we 
continue to involve developers in security thinking. I don't believe 
that "secure by default" is possible at the application level, and 
that's what really matters. It doesn't matter if the developer uses a 
"secure by default" CSPRNG if the application leaks information some 
other way. We cannot possibly hope to solve application security from 
the bottom-up (although providing good secure tools is part of the 

I believe that computer security is to the IT world what occupational 
health and safety is to the farming, building and manufacturing 
industries (and others). The thing about security is that, like safety, 
it is not a product. There is no function you can call to turn security 
on, no secure=True setting. It is a process and a mind-set, and everyone 
involved needs to think about it, at least a little bit.

It took a long time for the blue collar industries to accept that OH&S 
was something that *everyone* has to be involved in, from the government 
setting standards to individual workers who have to keep their eyes open 
while on the job. Like the IT industry today, management's attitude was 
that safety was a cost that just ate into profits and made projects late 
(sound familiar?), and the workers' attitude was all too often "it won't 
happen to us".

It takes experience and training and education to recognise dangerous 
situations on the job, and people die when they don't get that training. 
It is part of every person's job to think about what they are doing.

I don't believe that it is possible to have "zero-thought security" any 
more than it is possible to have "zero-thought safety". The security 
professionals can help by providing ready-to-use tools, but the 
individual developers still have to use those tools correctly, and 
cultivate a properly careful mindset:

"If I wanted to break into this application, what information would I 
look for? How can I stop providing it? Am I using the right tool for 
this job? How can I check? Where's the security rep?"

Until the IT industry treats security as the building industry treats 
OH&S, attempts to bail out the Titanic with a teacup with bottom-up 
"safe by default" functions will just encourage a false sense of 


More information about the Python-ideas mailing list