Hi,
I don't think delaying deletion is a good idea, it just brings more
complexity to the whole process and I can't really imagine how it
would be handled, since PHP is not run as a daemon - this is the
reason why the session GC is triggered by chance instead of running as
some type of a cron job.
Applications usually handle this by not regenerating session ID during
an ajax request. Most JS frameworks would send a 'X-Requested-With:
XMLHttpRequest' header to provide a way for Ajax detection, and PHP
frameworks have helper methods to look for that header. Even if they
don't - anybody can implement a similar solution for their own
application.
With that said, I'd rather give a +1 for changing the
session_regenerate_id()
default action from "don't delete" to
"delete", like you've previously suggested.
Btw, I wouldn't worry about stolen session IDs ... if somebody steals
it once, they'll do it after regeneration as well. Session ID
regeneration is only effective against brute-force attacks.
Cheers,
Andrey.
Hi Andrey,
I don't think delaying deletion is a good idea, it just brings more
complexity to the whole process and I can't really imagine how it
would be handled, since PHP is not run as a daemon - this is the
reason why the session GC is triggered by chance instead of running as
some type of a cron job.Applications usually handle this by not regenerating session ID during
an ajax request. Most JS frameworks would send a 'X-Requested-With:
XMLHttpRequest' header to provide a way for Ajax detection, and PHP
frameworks have helper methods to look for that header. Even if they
don't - anybody can implement a similar solution for their own
application.With that said, I'd rather give a +1 for changing the
session_regenerate_id()
default action from "don't delete" to
"delete", like you've previously suggested.Btw, I wouldn't worry about stolen session IDs ... if somebody steals
it once, they'll do it after regeneration as well. Session ID
regeneration is only effective against brute-force attacks.
Do you realize that stolen session could be used by attackers without
any indication currently? Unlike read_only, this is not about legitimate
user's
request. It's very easy to set up fake router by ARP spoofing. Stripping
HTTPS
is simple task and almost all users don't care about if HTTPS is used or
not.
Script kiddy is enough to steal session ID.
To mitigate regeneration risk and keep session availability at the same
time,
delayed deletion is mandatory. It's also better than immediate deletion
because
it allows to detect possible attack. As you mentioned, if session ID could
be
stolen, session ID may be stolen as many times as attacker wants.
Keeping session ID secure as much as possible is session manager's task.
Current mitigation that relies on GC is far from optimal and not acceptable.
Immediate deletion is worse than delayed deletion.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi,
Hi Andrey,
I don't think delaying deletion is a good idea, it just brings more
complexity to the whole process and I can't really imagine how it
would be handled, since PHP is not run as a daemon - this is the
reason why the session GC is triggered by chance instead of running as
some type of a cron job.Applications usually handle this by not regenerating session ID during
an ajax request. Most JS frameworks would send a 'X-Requested-With:
XMLHttpRequest' header to provide a way for Ajax detection, and PHP
frameworks have helper methods to look for that header. Even if they
don't - anybody can implement a similar solution for their own
application.With that said, I'd rather give a +1 for changing the
session_regenerate_id()
default action from "don't delete" to
"delete", like you've previously suggested.Btw, I wouldn't worry about stolen session IDs ... if somebody steals
it once, they'll do it after regeneration as well. Session ID
regeneration is only effective against brute-force attacks.Do you realize that stolen session could be used by attackers without
any indication currently? Unlike read_only, this is not about legitimate
user's
request. It's very easy to set up fake router by ARP spoofing. Stripping
HTTPS
is simple task and almost all users don't care about if HTTPS is used or
not.
Script kiddy is enough to steal session ID.
You're making it sound easier than it is, but otherwise - yes, I
realize that ... what makes you think that I don't? Why are you even
bringing this up?
To mitigate regeneration risk and keep session availability at the same
time,
delayed deletion is mandatory. It's also better than immediate deletion
because
it allows to detect possible attack. As you mentioned, if session ID could
be
stolen, session ID may be stolen as many times as attacker wants.
How do you detect attacks by delaying deletion? And what do you do if
you detect an attack to protect yourself from it? If it has to allow
valid requests, it will also allow attackers because session ID is the
only thing that you're looking for.
Keeping session ID secure as much as possible is session manager's task.
Nobody said it isn't.
Current mitigation that relies on GC is far from optimal and not acceptable.
I haven't said that it is optimal. I only explained why the GC works
the way it does currently.
Immediate deletion is worse than delayed deletion.
I don't agree with this, but I guess we'll have to agree to disagree on it.
Cheers,
Andrey.
Hi Andrey,
Hi Andrey,
On Mon, Mar 17, 2014 at 8:00 PM, Andrey Andreev narf@devilix.net
wrote:I don't think delaying deletion is a good idea, it just brings more
complexity to the whole process and I can't really imagine how it
would be handled, since PHP is not run as a daemon - this is the
reason why the session GC is triggered by chance instead of running as
some type of a cron job.Applications usually handle this by not regenerating session ID during
an ajax request. Most JS frameworks would send a 'X-Requested-With:
XMLHttpRequest' header to provide a way for Ajax detection, and PHP
frameworks have helper methods to look for that header. Even if they
don't - anybody can implement a similar solution for their own
application.With that said, I'd rather give a +1 for changing the
session_regenerate_id()
default action from "don't delete" to
"delete", like you've previously suggested.Btw, I wouldn't worry about stolen session IDs ... if somebody steals
it once, they'll do it after regeneration as well. Session ID
regeneration is only effective against brute-force attacks.Do you realize that stolen session could be used by attackers without
any indication currently? Unlike read_only, this is not about legitimate
user's
request. It's very easy to set up fake router by ARP spoofing. Stripping
HTTPS
is simple task and almost all users don't care about if HTTPS is used or
not.
Script kiddy is enough to steal session ID.You're making it sound easier than it is, but otherwise - yes, I
realize that ... what makes you think that I don't? Why are you even
bringing this up?
Because I wrote how to handle session regeneration securely in this thread.
To mitigate regeneration risk and keep session availability at the same
time,
delayed deletion is mandatory. It's also better than immediate deletion
because
it allows to detect possible attack. As you mentioned, if session ID
could
be
stolen, session ID may be stolen as many times as attacker wants.How do you detect attacks by delaying deletion? And what do you do if
you detect an attack to protect yourself from it? If it has to allow
valid requests, it will also allow attackers because session ID is the
only thing that you're looking for.
It was written in previous mail in this thread.
Users may set timeout flag in $_SESSION array and check the value if
session could be active or not. In order to do that in user land, one may do
session_start()
// ** check timeout flag **
if (!empty($_SESSION['VALID_UNTIL']) && $_SESSION['VALID_UNTIL'] < time()
) {
session_destroy()
;
trigger_error('Possible session hijack attack detected');
die('Possible session hijack attack detected');
}
// ** set timeout flag **
if ($_SESSION['LAST_REGENERATE'] < time()
+ 600) {
$_SESSION['VALID_UNTIL'] = time()
+ 60; // Shorter is better, but rather
large value is set for lost radio/hand over/etc. Old session is allowed to
use as valid session for 60 seconds.
session_commit()
; // Need to save above data in old session.
session_start()
;
$_SESSION['LAST_REGENERATE'] = time()
; // Update regenerate time here.
session_regenerate_id()
; // New session ID and old session data with old
session ID is left
unset($_SESSION['VALID_UNTIL']; // This session should not be deleted
later.
}
Above example is allowing 60 seconds window for legitimate user and
attacker. If session is hijacked,
- User could know attack if session ID is regenerated by attacker.
- Attacker could know there is hijack protection if session ID is
regenerated by user.
LAST_REGENERATE is better to be NEXT_REGENERATE with 'lazy_write' to
prevent unneeded session writes as I wrote in different mail in this thread.
Exception is easier to handle error. I would like to implemented it with
exception.
Keeping session ID secure as much as possible is session manager's task.
Nobody said it isn't.
Good.
Current mitigation that relies on GC is far from optimal and not
acceptable.I haven't said that it is optimal. I only explained why the GC works
the way it does currently.
OK.
It's not enough and it could be better.
Immediate deletion is worse than delayed deletion.
I don't agree with this, but I guess we'll have to agree to disagree on it.
Letting user and/or attacker to know there is protection against session
hijack
is good for better security. It wouldn't prevent attack, but it mitigates
risk.
It's the same as having surveillance camera for security.
I'm proposing session manager does its task to make session management
as secure as possible. I may agree with you if could explain why immediate
deletion is better than delayed.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi,
How do you detect attacks by delaying deletion? And what do you do if
you detect an attack to protect yourself from it? If it has to allow
valid requests, it will also allow attackers because session ID is the
only thing that you're looking for.It was written in previous mail in this thread.
Users may set timeout flag in $_SESSION array and check the value if session
could be active or not. In order to do that in user land, one may do
session_start()
// ** check timeout flag **
if (!empty($_SESSION['VALID_UNTIL']) && $_SESSION['VALID_UNTIL'] <time()
) {
session_destroy()
;
trigger_error('Possible session hijack attack detected');
die('Possible session hijack attack detected');
}// ** set timeout flag **
if ($_SESSION['LAST_REGENERATE'] <time()
+ 600) {
$_SESSION['VALID_UNTIL'] =time()
+ 60; // Shorter is better, but rather
large value is set for lost radio/hand over/etc. Old session is allowed to
use as valid session for 60 seconds.
session_commit()
; // Need to save above data in old session.
session_start()
;
$_SESSION['LAST_REGENERATE'] =time()
; // Update regenerate time here.
session_regenerate_id()
; // New session ID and old session data with old
session ID is left
unset($_SESSION['VALID_UNTIL']; // This session should not be deleted
later.
}Above example is allowing 60 seconds window for legitimate user and
attacker. If session is hijacked,
- User could know attack if session ID is regenerated by attacker.
- Attacker could know there is hijack protection if session ID is
regenerated by user.LAST_REGENERATE is better to be NEXT_REGENERATE with 'lazy_write' to
prevent unneeded session writes as I wrote in different mail in this thread.Exception is easier to handle error. I would like to implemented it with
exception.
I don't get it ... I thought you were proposing a solution in PHP
itself, not userland code. Am I missing something?
Immediate deletion is worse than delayed deletion.
I don't agree with this, but I guess we'll have to agree to disagree on
it.Letting user and/or attacker to know there is protection against session
hijack
is good for better security. It wouldn't prevent attack, but it mitigates
risk.
It's the same as having surveillance camera for security.
Surveillance cameras may scare off a random criminal in real life, but
this is because it would film them and they'd be easily identified.
We're on the internet here and everybody can hide themselves, alerts
don't scare the kiddies.
- Letting the application developer about an alleged attack is good.
- Letting the user (as in an end user, just somebody using the site)
know about is irrelevant to security and bad from a usability point of
view, nobody likes to see errors in websites, to say the least. - Letting the attacker know about it is not just not good, it's
really bad. It further exposes details about the application to the
attacker; details that can be used to aid them in a more sophisticated
attack. They now know that there's something stopping them at some
point and so they learn how to avoid it.
The first can also be implemented in userland with something like this:
$_SESSION['last_regenerate'] = time()
;
session_regenerate_id(FALSE);
// Later, detection:
if (isset($_SESSION['last_regenerate']) &&
$_SESSION['last_regenerate'] > time()
+ 60)
{
session_destroy()
;
// send email to webmaster
}
I'm proposing session manager does its task to make session management
as secure as possible. I may agree with you if could explain why immediate
deletion is better than delayed.
It's simple - immediate deletion doesn't leave a time window for
attackers to exploit.
But speaking of sessions and security, I'll mail you privately about
something because I didn't see an option in the bug reporting form to
mark it as a private one.
Cheers,
Andrey.
Hi Andrey,
How do you detect attacks by delaying deletion? And what do you do if
you detect an attack to protect yourself from it? If it has to allow
valid requests, it will also allow attackers because session ID is the
only thing that you're looking for.It was written in previous mail in this thread.
Users may set timeout flag in $_SESSION array and check the value if
session
could be active or not. In order to do that in user land, one may do
session_start()
// ** check timeout flag **
if (!empty($_SESSION['VALID_UNTIL']) && $_SESSION['VALID_UNTIL'] <
time()
) {
session_destroy()
;
trigger_error('Possible session hijack attack detected');
die('Possible session hijack attack detected');
}// ** set timeout flag **
if ($_SESSION['LAST_REGENERATE'] <time()
+ 600) {
$_SESSION['VALID_UNTIL'] =time()
+ 60; // Shorter is better, but
rather
large value is set for lost radio/hand over/etc. Old session is allowed
to
use as valid session for 60 seconds.
session_commit()
; // Need to save above data in old session.
session_start()
;
$_SESSION['LAST_REGENERATE'] =time()
; // Update regenerate time here.
session_regenerate_id()
; // New session ID and old session data with
old
session ID is left
unset($_SESSION['VALID_UNTIL']; // This session should not be deleted
later.
}Above example is allowing 60 seconds window for legitimate user and
attacker. If session is hijacked,
- User could know attack if session ID is regenerated by attacker.
- Attacker could know there is hijack protection if session ID is
regenerated by user.LAST_REGENERATE is better to be NEXT_REGENERATE with 'lazy_write' to
prevent unneeded session writes as I wrote in different mail in this
thread.Exception is easier to handle error. I would like to implemented it with
exception.I don't get it ... I thought you were proposing a solution in PHP
itself, not userland code. Am I missing something?
I would like to fix this by PHP. i.e. session module.
Therefore, I'm trying to change session module behavior.
It's an example of proper/reliable session ID regeneration and session
expiration
handling in user land.
Immediate deletion is worse than delayed deletion.
I don't agree with this, but I guess we'll have to agree to disagree on
it.Letting user and/or attacker to know there is protection against session
hijack
is good for better security. It wouldn't prevent attack, but it mitigates
risk.
It's the same as having surveillance camera for security.Surveillance cameras may scare off a random criminal in real life, but
this is because it would film them and they'd be easily identified.
We're on the internet here and everybody can hide themselves, alerts
don't scare the kiddies.
- Letting the application developer about an alleged attack is good.
- Letting the user (as in an end user, just somebody using the site)
know about is irrelevant to security and bad from a usability point of
view, nobody likes to see errors in websites, to say the least.
User is the only one that can identify which connection is legitimate or
not.
Therefore, app developers are advised to implement list/history of active
sessions.
- Letting the attacker know about it is not just not good, it's
really bad. It further exposes details about the application to the
attacker; details that can be used to aid them in a more sophisticated
attack. They now know that there's something stopping them at some
point and so they learn how to avoid it.
Consider which is good for attackers.
Even dummy surveillance camera is good for security. It is good alarm
attackers that they have been watched to prevent further attacks.
The first can also be implemented in userland with something like this:
$_SESSION['last_regenerate'] =
time()
;
session_regenerate_id(FALSE);// Later, detection:
if (isset($_SESSION['last_regenerate']) &&
$_SESSION['last_regenerate'] >time()
+ 60)
{
session_destroy()
;
// send email to webmaster
}
For the regeneration, this is enough.
The code is made to illustrate for both session expire and session
regeneration by session module.
I should have written code for destroying VALID_UNTIL, too. I'll add it in
new RFC.
I'm proposing session manager does its task to make session management
as secure as possible. I may agree with you if could explain why
immediate
deletion is better than delayed.It's simple - immediate deletion doesn't leave a time window for
attackers to exploit.
As you and I point it out. Attackers may steal session ID as many times as
they want.
Immediate deletion would not provide surveillance, hence no mitigation. It
also brings
lost session issue for legitimate users.
But speaking of sessions and security, I'll mail you privately about
something because I didn't see an option in the bug reporting form to
mark it as a private one.
If you choose "security" bug type, it's hidden.
Or if it's related to session module, you might want to send mail directly
to me to discuss.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi,
I don't get it ... I thought you were proposing a solution in PHP
itself, not userland code. Am I missing something?I would like to fix this by PHP. i.e. session module.
Therefore, I'm trying to change session module behavior.It's an example of proper/reliable session ID regeneration and session
expiration
handling in user land.
The userland solution works because it emulates a certain state of the
session between requests. I don't see how you'd do that in PHP itself
and even if you could, it might not be what everybody wants. I for one
would expect if I tell PHP to delete something, that thing to get
deleted immediately.
Immediate deletion is worse than delayed deletion.
I don't agree with this, but I guess we'll have to agree to disagree on
it.Letting user and/or attacker to know there is protection against session
hijack
is good for better security. It wouldn't prevent attack, but it
mitigates
risk.
It's the same as having surveillance camera for security.Surveillance cameras may scare off a random criminal in real life, but
this is because it would film them and they'd be easily identified.
We're on the internet here and everybody can hide themselves, alerts
don't scare the kiddies.
- Letting the application developer about an alleged attack is good.
- Letting the user (as in an end user, just somebody using the site)
know about is irrelevant to security and bad from a usability point of
view, nobody likes to see errors in websites, to say the least.User is the only one that can identify which connection is legitimate or
not.
Therefore, app developers are advised to implement list/history of active
sessions.
Advised != required.
User-accessible history != throwing errors in people's faces
- Letting the attacker know about it is not just not good, it's
really bad. It further exposes details about the application to the
attacker; details that can be used to aid them in a more sophisticated
attack. They now know that there's something stopping them at some
point and so they learn how to avoid it.Consider which is good for attackers.
Even dummy surveillance camera is good for security. It is good alarm
attackers that they have been watched to prevent further attacks.
I already said this: we're on the internet, alarms are tools that can
aid attackers, you don't scare them off with it. Anyway ... I already
said that we'll have to agree to disagree on this, you obviously have
a completely different opinion.
I'm proposing session manager does its task to make session management
as secure as possible. I may agree with you if could explain why
immediate
deletion is better than delayed.It's simple - immediate deletion doesn't leave a time window for
attackers to exploit.As you and I point it out. Attackers may steal session ID as many times as
they want.
Immediate deletion would not provide surveillance, hence no mitigation. It
also brings
lost session issue for legitimate users.
It's up to application developers to decide if and how to implement
"surveilance", mitigation. I already explained previously how the
"lost session" issue is solved currently by many applications and I
see nothing wrong with it, you just can't make it a part of PHP
because any similar solution is unreliable (it assumes
JavaScript-triggered processes, PHP doesn't talk with JS) and
ultimately the app designer's choice (what if my application doesn't
use ajax?).
But speaking of sessions and security, I'll mail you privately about
something because I didn't see an option in the bug reporting form to
mark it as a private one.If you choose "security" bug type, it's hidden.
Or if it's related to session module, you might want to send mail directly
to me to discuss.
Great, I'll post it on bugs.php.net then and I'll mail you to sort out
how we can chat ... we've been going back and forth via mails for way
too long now.
Cheers,
Andrey.
Hi Andrey,
I don't get it ... I thought you were proposing a solution in PHP
itself, not userland code. Am I missing something?I would like to fix this by PHP. i.e. session module.
Therefore, I'm trying to change session module behavior.It's an example of proper/reliable session ID regeneration and session
expiration
handling in user land.The userland solution works because it emulates a certain state of the
session between requests. I don't see how you'd do that in PHP itself
and even if you could, it might not be what everybody wants. I for one
would expect if I tell PHP to delete something, that thing to get
deleted immediately.
Better security is what user wants.
Besides, if session manager does its jobs, then user can concentrate
what is important for them. i.e. Making a good apps.
Immediate deletion is worse than delayed deletion.
I don't agree with this, but I guess we'll have to agree to disagree
on
it.Letting user and/or attacker to know there is protection against
session
hijack
is good for better security. It wouldn't prevent attack, but it
mitigates
risk.
It's the same as having surveillance camera for security.Surveillance cameras may scare off a random criminal in real life, but
this is because it would film them and they'd be easily identified.
We're on the internet here and everybody can hide themselves, alerts
don't scare the kiddies.
- Letting the application developer about an alleged attack is good.
- Letting the user (as in an end user, just somebody using the site)
know about is irrelevant to security and bad from a usability point of
view, nobody likes to see errors in websites, to say the least.User is the only one that can identify which connection is legitimate or
not.
Therefore, app developers are advised to implement list/history of active
sessions.Advised != required.
I would say it's required for security sensitive sites.
User-accessible history != throwing errors in people's faces
Letting user know that there might be possible attack is something user
needs.
If you really don't want to let users know possible attack, you may ignore
it.
i.e. Just ignore errors by your code.
- Letting the attacker know about it is not just not good, it's
really bad. It further exposes details about the application to the
attacker; details that can be used to aid them in a more sophisticated
attack. They now know that there's something stopping them at some
point and so they learn how to avoid it.Consider which is good for attackers.
Even dummy surveillance camera is good for security. It is good alarm
attackers that they have been watched to prevent further attacks.I already said this: we're on the internet, alarms are tools that can
aid attackers, you don't scare them off with it. Anyway ... I already
said that we'll have to agree to disagree on this, you obviously have
a completely different opinion.
I'm sure that ignoring possible attack is what attacker appreciated.
I'm proposing session manager does its task to make session management
as secure as possible. I may agree with you if could explain why
immediate
deletion is better than delayed.It's simple - immediate deletion doesn't leave a time window for
attackers to exploit.As you and I point it out. Attackers may steal session ID as many times
as
they want.
Immediate deletion would not provide surveillance, hence no mitigation.
It
also brings
lost session issue for legitimate users.It's up to application developers to decide if and how to implement
"surveilance", mitigation. I already explained previously how the
"lost session" issue is solved currently by many applications and I
AJAX request is not the only request to web servers.
Besides, many modern applications are made with AJAX only and
using the same session ID is increasing the risk of hijack.
see nothing wrong with it, you just can't make it a part of PHP
because any similar solution is unreliable (it assumes
JavaScript-triggered processes, PHP doesn't talk with JS) and
ultimately the app designer's choice (what if my application doesn't
use ajax?).
Making HTTP session management as secure as possible is session manager's
task.
- Reliable session ID regeneration
- Possible attack detection (if it's feasible)
- Reliable session expiration
I think all of these are session manager's task, not other code/module.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
But speaking of sessions and security, I'll mail you privately about
something because I didn't see an option in the bug reporting form to
mark it as a private one.If you choose "security" bug type, it's hidden.
nope, security bug type only makes it send the bug mail to security@php.net,
only private bugs are protected from public access.
that is something really error-prone, so I remember some discussion about
changing that, and making new security bugs to be private by default, but
AFAIK we never implemented that.
--
Ferenc Kovács
@Tyr43l - http://tyrael.hu
Hi Ferenc,
But speaking of sessions and security, I'll mail you privately about
something because I didn't see an option in the bug reporting form to
mark it as a private one.If you choose "security" bug type, it's hidden.
nope, security bug type only makes it send the bug mail to
security@php.net, only private bugs are protected from public access.
that is something really error-prone, so I remember some discussion about
changing that, and making new security bugs to be private by default, but
AFAIK we never implemented that.
It surprises me.
Thank you for your info.
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi,
If you choose "security" bug type, it's hidden.
nope, security bug type only makes it send the bug mail to security@php.net,
only private bugs are protected from public access.
that is something really error-prone, so I remember some discussion about
changing that, and making new security bugs to be private by default, but
AFAIK we never implemented that.
Actually, somebody did implement it.
Turned out the issue I wanted to report is solved though ... it was
the regression with use_strict_mode in 5.5.3 and for some unknown
reason, Ubuntu is sticking exactly to that version.
On topic: I understand the gains, Yasuo.
But I completely disagree that it's mandatory or that it is PHP's job
at all. If I tell PHP to delete something, I expect it to do so,
immediately.
Cheers,
Andrey.
Hi Andrey,
If you choose "security" bug type, it's hidden.
nope, security bug type only makes it send the bug mail to
security@php.net,
only private bugs are protected from public access.
that is something really error-prone, so I remember some discussion about
changing that, and making new security bugs to be private by default, but
AFAIK we never implemented that.Actually, somebody did implement it.
Turned out the issue I wanted to report is solved though ... it was
the regression with use_strict_mode in 5.5.3 and for some unknown
reason, Ubuntu is sticking exactly to that version.On topic: I understand the gains, Yasuo.
But I completely disagree that it's mandatory or that it is PHP's job
at all. If I tell PHP to delete something, I expect it to do so,
immediately.
https://wiki.php.net/rfc/session_regenerate_id
If you read my RFC, you'll see anyone can do that with
session_start(['regenerate_id_expire'=>0']);
or
ini_set('session.regenerate_id_expire', 0);
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net