Hi all,
Session module does not require hashing to generate session ID. This
RFC removes hashing from session module and enable use_strict_mode as
an insurance for broken RNG.
https://wiki.php.net/rfc/session-id-without-hashing
Comments are appreciated!
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Session module does not require hashing to generate session ID. This
RFC removes hashing from session module and enable use_strict_mode as
an insurance for broken RNG.
I cannot talk about the merits of the randomness-change here, but
use_strict_mode defaulting to 1 is major +1 from me.
Why it's advertised everywhere as best practice but even set to 0 in
php.ini-production is beyond me.
- Markus
Hi!
Session module does not require hashing to generate session ID. This
RFC removes hashing from session module and enable use_strict_mode as
an insurance for broken RNG.
I'm not sure why that should be the default. First of all, I'm not sure
exporting the state of the PRNG is that good an idea, there may be
vulnerability in the PRNG that could be opened (or made easier) for
exploit with direct access to its output. I'd rather not provide this
opening unnecessarily. Second, I do not see why we need to do maximum
breakage change if we could just make an identity "hash" function and
support both cases. "Session generation performance" does not have a lot
of meaning here - I'd be very surprised to see any application that is
bound by the speed of generating session IDs.
Also, I don't see how use_strict_mode change is related to the hashing.
Could you explain?
Stas Malyshev
smalyshev@gmail.com
Hi Stas,
Session module does not require hashing to generate session ID. This
RFC removes hashing from session module and enable use_strict_mode as
an insurance for broken RNG.I'm not sure why that should be the default. First of all, I'm not sure
exporting the state of the PRNG is that good an idea, there may be
vulnerability in the PRNG that could be opened (or made easier) for
exploit with direct access to its output. I'd rather not provide this
opening unnecessarily.
PRNG like /dev/urandom is supposed to be secure, but fair point. It
may be good idea keeping old hash based session ID just in case
someone find vulnerability. I suppose it's unlikely with modern PRNGs,
though.
If we have to care about PRNG state exposure, code may be changed to
read random length from RPNG. This would be good enough mitigation. I
would like to hear from PRNG experts if this is good enough. (or not
needed)
Second, I do not see why we need to do maximum
breakage change if we could just make an identity "hash" function and
support both cases. "Session generation performance" does not have a lot
of meaning here - I'd be very surprised to see any application that is
bound by the speed of generating session IDs.
w/ Patch: Requests per second: 2278.59 [#/sec] (mean)
w/o Patch: Requests per second: 899.36 [#/sec] (mean)
(This is CLI server and "ab -c 20 -n 100000" result on Core i7 4770s Linux)
I didn't expect this much difference, but this is the result. Since
security experts advise to change session ID relatively high frequency
(few minutes to half an hour), this difference may be noticeable apps
returning cached JSON. I know apps that change session ID on every
request. (This should be done with caution. Otherwise, you may
experience lost sessions a lot due to race conditions) Such apps will
see performance gain.
Also, I don't see how use_strict_mode change is related to the hashing.
Could you explain?
We cannot control PRNG behavior. It's enabled for broken PRNG
insurance. use_strict_mode=1 (detecting session ID collisions) is
mandatory, anyway.
Regards,
P.S. Code may be changed so that user can choose raw PRNG and old
hashing. We have to keep old and new INI settings in this case. Anyone
has comment for keeping hash/PRNG related INIs? I would like to remove
hash/PRNG related INIs if not many of us insist.
--
Yasuo Ohgaki
yohgaki@ohgaki.net
PRNG like /dev/urandom is supposed to be secure, but fair point. It
may be good idea keeping old hash based session ID just in case
someone find vulnerability. I suppose it's unlikely with modern PRNGs,
though.
I've come to think that "unlikely" is still a bad precondition with
regards to security... :)
If we have to care about PRNG state exposure, code may be changed to
read random length from RPNG. This would be good enough mitigation. I
would like to hear from PRNG experts if this is good enough. (or not
needed)Second, I do not see why we need to do maximum
breakage change if we could just make an identity "hash" function and
support both cases. "Session generation performance" does not have a lot
of meaning here - I'd be very surprised to see any application that is
bound by the speed of generating session IDs.w/ Patch: Requests per second: 2278.59 [#/sec] (mean)
w/o Patch: Requests per second: 899.36 [#/sec] (mean)
(This is CLI server and "ab -c 20 -n 100000" result on Core i7 4770s Linux)I didn't expect this much difference, but this is the result. Since
security experts advise to change session ID relatively high frequency
(few minutes to half an hour), this difference may be noticeable apps
returning cached JSON. I know apps that change session ID on every
request. (This should be done with caution. Otherwise, you may
experience lost sessions a lot due to race conditions) Such apps will
see performance gain.
This RPS change is the result of just omitting hashing of the session id?
--
Regards,
Mike
Hi
PRNG like /dev/urandom is supposed to be secure, but fair point. It
may be good idea keeping old hash based session ID just in case
someone find vulnerability. I suppose it's unlikely with modern PRNGs,
though.I've come to think that "unlikely" is still a bad precondition with
regards to security... :)
however, if a vulnerability is found in /dev/urandom, that would be a
stop-what-you're-doing-and-patch moment anyways because so much stuff
depends on /dev/(u)random not producing predictable output.
If /dev/urandom is not to be trusted, you have to bring your server
offline right then. The fact that PHP would continue to produce more
secure session IDs won't help you much.
I didn't expect this much difference, but this is the result. Since
security experts advise to change session ID relatively high frequency
(few minutes to half an hour), this difference may be noticeable apps
returning cached JSON. I know apps that change session ID on every
request. (This should be done with caution. Otherwise, you may
experience lost sessions a lot due to race conditions) Such apps will
see performance gain.This RPS change is the result of just omitting hashing of the session id?
if it is, it's really worth considering this change as, again, a
vulnerability in /dev/urandom would be devastating enough to
immediately bring down the machine anyways.
Philip
Hi Philip,
On Tue, Apr 12, 2016 at 5:38 PM, Philip Hofstetter
phofstetter@sensational.ch wrote:
PRNG like /dev/urandom is supposed to be secure, but fair point. It
may be good idea keeping old hash based session ID just in case
someone find vulnerability. I suppose it's unlikely with modern PRNGs,
though.I've come to think that "unlikely" is still a bad precondition with
regards to security... :)however, if a vulnerability is found in /dev/urandom, that would be a
stop-what-you're-doing-and-patch moment anyways because so much stuff
depends on /dev/(u)random not producing predictable output.If /dev/urandom is not to be trusted, you have to bring your server
offline right then. The fact that PHP would continue to produce more
secure session IDs won't help you much.
If there is such severe vulnerability, not only session but also many crypt
related features cannot be trusted.
Anyway, I'll add mitigation that reads random length of bytes from PRNG.
This should be good enough to hide PRNG state. Expert comments on
this is appreciated.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi,
Hi Philip,
On Tue, Apr 12, 2016 at 5:38 PM, Philip Hofstetter
phofstetter@sensational.ch wrote:PRNG like /dev/urandom is supposed to be secure, but fair point. It
may be good idea keeping old hash based session ID just in case
someone find vulnerability. I suppose it's unlikely with modern PRNGs,
though.I've come to think that "unlikely" is still a bad precondition with
regards to security... :)however, if a vulnerability is found in /dev/urandom, that would be a
stop-what-you're-doing-and-patch moment anyways because so much stuff
depends on /dev/(u)random not producing predictable output.If /dev/urandom is not to be trusted, you have to bring your server
offline right then. The fact that PHP would continue to produce more
secure session IDs won't help you much.If there is such severe vulnerability, not only session but also many crypt
related features cannot be trusted.Anyway, I'll add mitigation that reads random length of bytes from PRNG.
This should be good enough to hide PRNG state. Expert comments on
this is appreciated.
How are you going to read a random length of bytes from the randomness
source itself? That's a chicken and egg problem. :)
Cheers,
Andrey.
Hi Andrey,
Hi Philip,
On Tue, Apr 12, 2016 at 5:38 PM, Philip Hofstetter
phofstetter@sensational.ch wrote:PRNG like /dev/urandom is supposed to be secure, but fair point. It
may be good idea keeping old hash based session ID just in case
someone find vulnerability. I suppose it's unlikely with modern PRNGs,
though.I've come to think that "unlikely" is still a bad precondition with
regards to security... :)however, if a vulnerability is found in /dev/urandom, that would be a
stop-what-you're-doing-and-patch moment anyways because so much stuff
depends on /dev/(u)random not producing predictable output.If /dev/urandom is not to be trusted, you have to bring your server
offline right then. The fact that PHP would continue to produce more
secure session IDs won't help you much.If there is such severe vulnerability, not only session but also many
crypt
related features cannot be trusted.Anyway, I'll add mitigation that reads random length of bytes from PRNG.
This should be good enough to hide PRNG state. Expert comments on
this is appreciated.How are you going to read a random length of bytes from the randomness
source itself? That's a chicken and egg problem. :)
If you say so, current implementation is also vulnerable :)
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Michael,
PRNG like /dev/urandom is supposed to be secure, but fair point. It
may be good idea keeping old hash based session ID just in case
someone find vulnerability. I suppose it's unlikely with modern PRNGs,
though.I've come to think that "unlikely" is still a bad precondition with
regards to security... :)
Yes.
Almost all of crypt relies on "unlikely", though.
So issue is how "unlikely" it is.
I suppose almost all crypt experts agree
/dev/urandom and friends are secure enough.
(Except side channel attacks)
If we have to care about PRNG state exposure, code may be changed to
read random length from RPNG. This would be good enough mitigation. I
would like to hear from PRNG experts if this is good enough. (or not
needed)Second, I do not see why we need to do maximum
breakage change if we could just make an identity "hash" function and
support both cases. "Session generation performance" does not have a lot
of meaning here - I'd be very surprised to see any application that is
bound by the speed of generating session IDs.w/ Patch: Requests per second: 2278.59 [#/sec] (mean)
w/o Patch: Requests per second: 899.36 [#/sec] (mean)
(This is CLI server and "ab -c 20 -n 100000" result on Core i7 4770s Linux)I didn't expect this much difference, but this is the result. Since
security experts advise to change session ID relatively high frequency
(few minutes to half an hour), this difference may be noticeable apps
returning cached JSON. I know apps that change session ID on every
request. (This should be done with caution. Otherwise, you may
experience lost sessions a lot due to race conditions) Such apps will
see performance gain.This RPS change is the result of just omitting hashing of the session id?
and changes "session.use_strict_mode" default INI value to 1.
I haven't added code to read random length from PRNG also.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi!
PRNG like /dev/urandom is supposed to be secure, but fair point. It
may be good idea keeping old hash based session ID just in case
someone find vulnerability. I suppose it's unlikely with modern PRNGs,
though.
That assumes we use /dev/urandom directly and it is always available on
all systems and always accessible to PHP. I don't think it is the case
now, is it?
If we have to care about PRNG state exposure, code may be changed to
read random length from RPNG. This would be good enough mitigation. I
would like to hear from PRNG experts if this is good enough. (or not
needed)
We have pretty good way of removing this problem. It's called hashing.
Now we are inventing our own crypto tricks to not use existing and
proven method of doing it. This looks like bad idea to me. We do not
have expertise to even evaluate if it's safe.
w/ Patch: Requests per second: 2278.59 [#/sec] (mean)
w/o Patch: Requests per second: 899.36 [#/sec] (mean)
(This is CLI server and "ab -c 20 -n 100000" result on Core i7 4770s Linux)
My point is it does not matter. Nobody cares if session ID generation
takes 1 ms instead of 2 ms.
request. (This should be done with caution. Otherwise, you may
experience lost sessions a lot due to race conditions) Such apps will
see performance gain.
No they won't. Even if they change session ID on every request (which
sounds extremely weird, I have never seen anybody doing it and would
never recommend doing it) the different would still be unnoticeable if
the application does anything beyond generating session IDs. Unless you
can show speedup on real apps, I don't think this point is worth ever
mentioning again.
We cannot control PRNG behavior. It's enabled for broken PRNG
insurance. use_strict_mode=1 (detecting session ID collisions) is
mandatory, anyway.
If we are assuming broken PRNG, it surely is unsafe to export its state
to the whole world. Either we assume PRNG is safe and sound, or not. And
I really don't like the idea of grouping unrelated changes together.
has comment for keeping hash/PRNG related INIs? I would like to remove
hash/PRNG related INIs if not many of us insist.
I think removing existing INI entries is completely unnecessary and just
creates BC problems without any benefit.
--
Stas Malyshev
smalyshev@gmail.com
Hi Stas,
PRNG like /dev/urandom is supposed to be secure, but fair point. It
may be good idea keeping old hash based session ID just in case
someone find vulnerability. I suppose it's unlikely with modern PRNGs,
though.That assumes we use /dev/urandom directly and it is always available on
all systems and always accessible to PHP. I don't think it is the case
now, is it?
Yes and no.
Patch uses php_random_bytes(), so it uses appropriate PRNG for the system.
php_random_bytes() is supposed to be available always.
If we have to care about PRNG state exposure, code may be changed to
read random length from RPNG. This would be good enough mitigation. I
would like to hear from PRNG experts if this is good enough. (or not
needed)We have pretty good way of removing this problem. It's called hashing.
Now we are inventing our own crypto tricks to not use existing and
proven method of doing it. This looks like bad idea to me. We do not
have expertise to even evaluate if it's safe.
Experts say secure PRNG like /dev/urandom is safe.
w/ Patch: Requests per second: 2278.59 [#/sec] (mean)
w/o Patch: Requests per second: 899.36 [#/sec] (mean)
(This is CLI server and "ab -c 20 -n 100000" result on Core i7 4770s Linux)My point is it does not matter. Nobody cares if session ID generation
takes 1 ms instead of 2 ms.request. (This should be done with caution. Otherwise, you may
experience lost sessions a lot due to race conditions) Such apps will
see performance gain.No they won't. Even if they change session ID on every request (which
sounds extremely weird, I have never seen anybody doing it and would
never recommend doing it) the different would still be unnoticeable if
the application does anything beyond generating session IDs. Unless you
can show speedup on real apps, I don't think this point is worth ever
mentioning again.
Why shouldn't?
It's just a use case in the wild.
The reason why regenerating session ID always is not recommended is
because there is no "Time Stamp" based management in current session
which is declined recently.
If time stamp based session management is used, there is no worries
updating session ID on every request.
We cannot control PRNG behavior. It's enabled for broken PRNG
insurance. use_strict_mode=1 (detecting session ID collisions) is
mandatory, anyway.If we are assuming broken PRNG, it surely is unsafe to export its state
to the whole world. Either we assume PRNG is safe and sound, or not. And
I really don't like the idea of grouping unrelated changes together.
Discussion is based on FUD.
AFAIK, I saw papers state PRNGs are secure enough, but opposite.
(We can safely ignore side channel attack issue, I suppose)
has comment for keeping hash/PRNG related INIs? I would like to remove
hash/PRNG related INIs if not many of us insist.I think removing existing INI entries is completely unnecessary and just
creates BC problems without any benefit.
There is no BC.
Removed INI are just ignored if users are used.
Security concern is endless. We need to trust something, otherwise
endless mitigation is required.
Modern secure PRNGs are good enough to rely on just like other security
related features like hash, encryption, etc. Simple mitigation like reading
random length from PRNG should be good enough for those who are
concerned secure RPNG vulnerability.
Question is "Current session ID is generation is optimal way?" or "Is it
better than proposed one?" If so, why?
Crypto experts say "secure PRNG is safe", why should we care too much
about secure PRNG vulnerability? Why we should invent our own entropy
added random value and take hash of it?
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi!
Yes and no.
Patch uses php_random_bytes(), so it uses appropriate PRNG for the system.
php_random_bytes() is supposed to be available always.
True, but is it always OK to export its state to anybody who asks, on
demand, in unlimited numbers? I'm not so sure.
Experts say secure PRNG like /dev/urandom is safe.
What's "like /dev/urandom"? Each PRNG can have different properties.
Why shouldn't?
It's just a use case in the wild.
If you want to test use case, test on real application, not on
microbenchmark. And by real application I mean one currently used, of
which none regenerate session IDs on every request, and none have
reasons to. Optimizing for narrow use case which doesn't even exist yet
against thousands of apps that already do makes no sense to me.
If time stamp based session management is used, there is no worries
updating session ID on every request.
Of course there are worries, it would generate huge traffic to session
storage which is completely unnecessary. Moreover, many application
would be broken under such model. Of course, you are free to build your
own app using such model, but it's in no way a best practice and it does
not deserve to be target of global optimization of session module for it.
Discussion is based on FUD.
AFAIK, I saw papers state PRNGs are secure enough, but opposite.
(We can safely ignore side channel attack issue, I suppose)
We can't claim both PRNG are secure and PRNG aren't secure. So which is it?
In any case, I don't see how this mandates turning on strict sessions. I
know you want it to be the default, but it doesn't seem to be related to
this topic.
There is no BC.
Removed INI are just ignored if users are used.
But users used them for something. If that something doesn't happen,
then it's broken.
Question is "Current session ID is generation is optimal way?" or "Is it
better than proposed one?" If so, why?
Yes, it's better - it does not export PRNG state needlessly, and it's
already proven to work by thousands of applications. I'm OK with adding
a non-hashed option, for people that want to try it out, and eventually
if everybody ends up using it and nothing bad happens, we could phase
out the hashed ones then. But just dropping them out of the blue and
making non-hashed the only option does not look like a good solution.
Crypto experts say "secure PRNG is safe", why should we care too much
about secure PRNG vulnerability? Why we should invent our own entropy
added random value and take hash of it?
We should not invent our own PRNG. Hashing it though seems like a
reasonable precaution.
Stas Malyshev
smalyshev@gmail.com
Hi Stas,
On Wed, Apr 13, 2016 at 12:50 PM, Stanislav Malyshev
smalyshev@gmail.com wrote:
Yes and no.
Patch uses php_random_bytes(), so it uses appropriate PRNG for the system.
php_random_bytes() is supposed to be available always.True, but is it always OK to export its state to anybody who asks, on
demand, in unlimited numbers? I'm not so sure.Experts say secure PRNG like /dev/urandom is safe.
What's "like /dev/urandom"? Each PRNG can have different properties.
Yes, but all RPNG in major OSes are supposed to be secure PRNG.
Why shouldn't?
It's just a use case in the wild.If you want to test use case, test on real application, not on
microbenchmark. And by real application I mean one currently used, of
which none regenerate session IDs on every request, and none have
reasons to. Optimizing for narrow use case which doesn't even exist yet
against thousands of apps that already do makes no sense to me.If time stamp based session management is used, there is no worries
updating session ID on every request.Of course there are worries, it would generate huge traffic to session
storage which is completely unnecessary. Moreover, many application
would be broken under such model. Of course, you are free to build your
own app using such model, but it's in no way a best practice and it does
not deserve to be target of global optimization of session module for it.
Users updating session ID always do not concern disabling lazy_write,
I suppose.
Discussion is based on FUD.
AFAIK, I saw papers state PRNGs are secure enough, but opposite.
(We can safely ignore side channel attack issue, I suppose)We can't claim both PRNG are secure and PRNG aren't secure. So which is it?
When we discussed about randam_*() functions, links to pages are
posted.
In any case, I don't see how this mandates turning on strict sessions. I
know you want it to be the default, but it doesn't seem to be related to
this topic.
Probability of collision is close to zero, but it's not zero unless it
is validated. It's a precaution for broken PRNG on new OSes, too.
It's closely related to me, different point of view.
There is no BC.
Removed INI are just ignored if users are used.But users used them for something. If that something doesn't happen,
then it's broken.
INI setting is always worked this way. I don't see problem ignoring settings
e.g. register_globals=on, magic_quote_gpc=on
Question is "Current session ID is generation is optimal way?" or "Is it
better than proposed one?" If so, why?Yes, it's better - it does not export PRNG state needlessly, and it's
already proven to work by thousands of applications. I'm OK with adding
a non-hashed option, for people that want to try it out, and eventually
if everybody ends up using it and nothing bad happens, we could phase
out the hashed ones then. But just dropping them out of the blue and
making non-hashed the only option does not look like a good solution.Crypto experts say "secure PRNG is safe", why should we care too much
about secure PRNG vulnerability? Why we should invent our own entropy
added random value and take hash of it?We should not invent our own PRNG. Hashing it though seems like a
reasonable precaution.
If we have to hide PRNG state, skipping random bytes would do
the job. This is much simpler and faster.
We cannot say current implementation is better. SSL/TLS
removed multiple use of hashes because it could be weaker.
Use of additional hashing does not necessary a good thing as
distribution of hashed value (session ID) is biased by hash algorithm.
Only 32 bytes are read from PRNG by default. Therefore, it's close
to direct exposure even with hash.
We probably should discuss php_random_bytes() if it is considered as
crypto secure or not. If yes, we may simply rely on it. (My discussion
is based on this) If not, we need to improve php_random_bytes() implementation.
Regards,
P.S.
Another reason why I would like to remove hashing is availability
of stronger hashes. Hash extension can be disabled, thus there
should be fallback code. It's not clean. Stronger hashes are slower
also.
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi all,
Session module does not require hashing to generate session ID. This
RFC removes hashing from session module and enable use_strict_mode as
an insurance for broken RNG.https://wiki.php.net/rfc/session-id-without-hashing
Comments are appreciated!
It's been a while since last discussion.
I would like to add this change to session module at least for PHP 7.1.
Concern has been discussed is risk of broken PRNG and predictable
session ID. We may insist any platform must have reliable PRNG, but it
would be good idea to have least mitigation. Reading extra bytes
should be good enough for this purpose.
I also changed minimum length of session ID from 32 to 22 for better
compatibility. 22 is the length with MD5 hash and
hash_bits_per_character=6.
PR would be updated soon. I would like to start vote after PR update,
so please post comments if any.
Thank you.
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi!
Concern has been discussed is risk of broken PRNG and predictable
session ID. We may insist any platform must have reliable PRNG, but it
would be good idea to have least mitigation. Reading extra bytes
should be good enough for this purpose.
I still see no reason to change it stated in the RFC except performance
(which is irrelevant in all contexts I know of). It states the change
but omits the reason why this change is necessary. Could you please add
that part?
--
Stas Malyshev
smalyshev@gmail.com
Hi :)
Hi!
Concern has been discussed is risk of broken PRNG and predictable
session ID. We may insist any platform must have reliable PRNG, but it
would be good idea to have least mitigation. Reading extra bytes
should be good enough for this purpose.I still see no reason to change it stated in the RFC except performance
(which is irrelevant in all contexts I know of). It states the change
but omits the reason why this change is necessary. Could you please add
that part?
Same here.
I have to ask again what prevents you to write your own custom session
module and do everything you consider as safe in there. But this kind
of changes sounds not very helpful and not really done for valid
reasons (for that one). I fully understand the goal to secure (and
this is a very open definition) session manage for php but this cannot
be done in step by step basis.
Cheers,
Pierre
@pierrejoye | http://www.libgd.org
Hi Stas,
Concern has been discussed is risk of broken PRNG and predictable
session ID. We may insist any platform must have reliable PRNG, but it
would be good idea to have least mitigation. Reading extra bytes
should be good enough for this purpose.I still see no reason to change it stated in the RFC except performance
(which is irrelevant in all contexts I know of). It states the change
but omits the reason why this change is necessary. Could you please add
that part?
Sure.
The main purpose is clean up.
The reason we have messy session ID creation code for hashing and
generating random bytes is we didn't have reliable cross platform PRNG
code. We have it now, so no reason to keep complex/redundant/inefficient code.
I'll add this.
Thank you.
--
Yasuo Ohgaki
yohgaki@ohgaki.net