[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:
https://media.blackhat.com/bh-us-12/Briefings/Argyros/BH_US_12_Argyros_PRNG_WP.pdf
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
which.
- 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
distributions;
+ 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
solution).
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
security.
--
Steve
More information about the Python-ideas
mailing list