Hi all,
I understand why header()
is made to remove all headers of the same
name. This is needed in some cases, but it does not work well for some
cases.
We need to decide what to do with
https://bugs.php.net/bug.php?id=72997
There is 2 issues.
-
header()
removes all headers of the same name including 'Set-Cookie' -
header()
ignores replace flag. (This one is easy to fix)
Since header()
enables 'replace flag' by default, it removes all
'Set-Cookie' headers sent previously by default. It can easily disturb
security related cookies to work. i.e. Session ID cookie, Auto Login
cookie. This bug would be very hard to find for normal users, too.
Restoring older behavior (Removing only one header) cannot be a
resolution because it can still disturb security related cookies.
Possible resolutions:
- Prohibit 'Set-Cookie' for
header()
and force users to usesetcookie()
- Mitigate by disabling replace flag by default. (This is not a good idea, IMO)
Both resolution requires BC, but this is better to be fixed ASAP.
Non-BC resolution could be:
- "Ask users to use
setcookie()
always for 'Set-Cookie'".
I would like to prohibit 'Set-Cookie' by header()
because it may
remove session ID cookie as well as auto login cookie, etc. If we
leave released version as it is now, I would like to prohibit
'Set-Cookie' by header()
in PHP 7.1.
Problem with this may be that user cannot modify 'Set-Cookie' header
line as user want.
$ php -r 'setcookie("REMEMBERME=value; expires=Sat, 03-Sep-2020
05:38:43 GMT; path=/; domain=aaa");'
PHP Warning: Cookie names cannot contain any of the following '=,;
\t\r\n\013\014' in Command line code on line 1
Comments?
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
(Apologies for the dupe, re-sending for the list.)
If the replace flag was fixed, isn’t this then just a case of making sure userland sets replace to false if they want existing set-cookie headers retained?
Removing the ability to write a custom Set-Cookie header introduces a bigger problem than the current one, IMO.
Hi all,
I understand why
header()
is made to remove all headers of the same
name. This is needed in some cases, but it does not work well for some
cases.We need to decide what to do with
https://bugs.php.net/bug.php?id=72997There is 2 issues.
header()
removes all headers of the same name including 'Set-Cookie'header()
ignores replace flag. (This one is easy to fix)Since
header()
enables 'replace flag' by default, it removes all
'Set-Cookie' headers sent previously by default. It can easily disturb
security related cookies to work. i.e. Session ID cookie, Auto Login
cookie. This bug would be very hard to find for normal users, too.Restoring older behavior (Removing only one header) cannot be a
resolution because it can still disturb security related cookies.Possible resolutions:
- Prohibit 'Set-Cookie' for
header()
and force users to usesetcookie()
- Mitigate by disabling replace flag by default. (This is not a good idea, IMO)
Both resolution requires BC, but this is better to be fixed ASAP.
Non-BC resolution could be:
- "Ask users to use
setcookie()
always for 'Set-Cookie'".I would like to prohibit 'Set-Cookie' by
header()
because it may
remove session ID cookie as well as auto login cookie, etc. If we
leave released version as it is now, I would like to prohibit
'Set-Cookie' byheader()
in PHP 7.1.Problem with this may be that user cannot modify 'Set-Cookie' header
line as user want.$ php -r 'setcookie("REMEMBERME=value; expires=Sat, 03-Sep-2020
05:38:43 GMT; path=/; domain=aaa");'
PHP Warning: Cookie names cannot contain any of the following '=,;
\t\r\n\013\014' in Command line code on line 1Comments?
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi all,
I understand why
header()
is made to remove all headers of the same
name. This is needed in some cases, but it does not work well for some
cases.We need to decide what to do with
https://bugs.php.net/bug.php?id=72997There is 2 issues.
header()
removes all headers of the same name including 'Set-Cookie'header()
ignores replace flag. (This one is easy to fix)Since
header()
enables 'replace flag' by default, it removes all
'Set-Cookie' headers sent previously by default. It can easily disturb
security related cookies to work. i.e. Session ID cookie, Auto Login
cookie. This bug would be very hard to find for normal users, too.Restoring older behavior (Removing only one header) cannot be a
resolution because it can still disturb security related cookies.Possible resolutions:
- Prohibit 'Set-Cookie' for
header()
and force users to usesetcookie()
- Mitigate by disabling replace flag by default. (This is not a good idea, IMO)
Both resolution requires BC, but this is better to be fixed ASAP.
Non-BC resolution could be:
- "Ask users to use
setcookie()
always for 'Set-Cookie'".I would like to prohibit 'Set-Cookie' by
header()
because it may
remove session ID cookie as well as auto login cookie, etc. If we
leave released version as it is now, I would like to prohibit
'Set-Cookie' byheader()
in PHP 7.1.Problem with this may be that user cannot modify 'Set-Cookie' header
line as user want.$ php -r 'setcookie("REMEMBERME=value; expires=Sat, 03-Sep-2020
05:38:43 GMT; path=/; domain=aaa");'
PHP Warning: Cookie names cannot contain any of the following '=,;
\t\r\n\013\014' in Command line code on line 1Comments?
An idea for session ID protection.
Following code results in lost session always.
<?php
session_start()
;
session_regenerate_id()
;
header('Set-Cookie: something');
?>
header()
function removes all header of the same name, e.g.
Set-Cookie, Expires, etc, by sapi_remove_header(). This could be very
hard to find the cause.
This risk can be removed w/o much BC. Only BC is when user is
intentionally trying to delete session ID cookie manually. This would
be very rare. We can add code that excludes session ID cookie in
sapi_remove_header().
http://lxr.php.net/xref/PHP-MASTER/main/SAPI.c#593
To do that, we can search string like following
Set-Cookie: PHPSESSID=xxxxxxx
The only issue is we need session global, i.e. PS(session_name), at
least. It's not nice to have dependency from SAPI.c to session, but it
protects session ID from removed by users by mistake.
Any comments?
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Yasuo,
I still have an issue with that. I believe the correct behaviour here is (assuming the replace
argument to header()
is honoured) what you’re seeing. Yes, it might be unexpected for new users, but its also expected by millions of current users/projects.
I would suggest perhaps a warning on the header()
docs page, and perhaps an example to avoid the issue on the Session handling page.
Leaving it as-is, with improved docs means all functionality is possible with the right arguments.
Changing to your proposal means advanced use-cases are impossible with any arguments.
I realise you’re trying to remove WTF cases, but I don’t think removing advanced capabilities is the way to do that.
Cheers
Stephen
Hi all,
I understand why
header()
is made to remove all headers of the same
name. This is needed in some cases, but it does not work well for some
cases.We need to decide what to do with
https://bugs.php.net/bug.php?id=72997There is 2 issues.
header()
removes all headers of the same name including 'Set-Cookie'header()
ignores replace flag. (This one is easy to fix)Since
header()
enables 'replace flag' by default, it removes all
'Set-Cookie' headers sent previously by default. It can easily disturb
security related cookies to work. i.e. Session ID cookie, Auto Login
cookie. This bug would be very hard to find for normal users, too.Restoring older behavior (Removing only one header) cannot be a
resolution because it can still disturb security related cookies.Possible resolutions:
- Prohibit 'Set-Cookie' for
header()
and force users to usesetcookie()
- Mitigate by disabling replace flag by default. (This is not a good idea, IMO)
Both resolution requires BC, but this is better to be fixed ASAP.
Non-BC resolution could be:
- "Ask users to use
setcookie()
always for 'Set-Cookie'".I would like to prohibit 'Set-Cookie' by
header()
because it may
remove session ID cookie as well as auto login cookie, etc. If we
leave released version as it is now, I would like to prohibit
'Set-Cookie' byheader()
in PHP 7.1.Problem with this may be that user cannot modify 'Set-Cookie' header
line as user want.$ php -r 'setcookie("REMEMBERME=value; expires=Sat, 03-Sep-2020
05:38:43 GMT; path=/; domain=aaa");'
PHP Warning: Cookie names cannot contain any of the following '=,;
\t\r\n\013\014' in Command line code on line 1Comments?
An idea for session ID protection.
Following code results in lost session always.
<?php
session_start()
;
session_regenerate_id()
;
header('Set-Cookie: something');
?>
header()
function removes all header of the same name, e.g.
Set-Cookie, Expires, etc, by sapi_remove_header(). This could be very
hard to find the cause.This risk can be removed w/o much BC. Only BC is when user is
intentionally trying to delete session ID cookie manually. This would
be very rare. We can add code that excludes session ID cookie in
sapi_remove_header().
http://lxr.php.net/xref/PHP-MASTER/main/SAPI.c#593To do that, we can search string like following
Set-Cookie: PHPSESSID=xxxxxxxThe only issue is we need session global, i.e. PS(session_name), at
least. It's not nice to have dependency from SAPI.c to session, but it
protects session ID from removed by users by mistake.Any comments?
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Stephen,
I still have an issue with that. I believe the correct behaviour here is (assuming the
replace
argument toheader()
is honoured) what you’re seeing. Yes, it might be unexpected for new users, but its also expected by millions of current users/projects.I would suggest perhaps a warning on the
header()
docs page, and perhaps an example to avoid the issue on the Session handling page.Leaving it as-is, with improved docs means all functionality is possible with the right arguments.
Changing to your proposal means advanced use-cases are impossible with any arguments.
I realise you’re trying to remove WTF cases, but I don’t think removing advanced capabilities is the way to do that.
Yes. Even framework developer(?) seems to have current behavior.
In general, users shouldn't touch session ID. In case of user really
want to modify session ID cookie, following could be done.
<?php
ob_start()
;
session_start()
;
header_remove('Set-Cookie');
header('Set-Cookie: PHPSESSID=xxxx something');
?>
Make header_remove()
able to delete 'Set-Cookie' header. (Current behavior)
Make header()
able to send 'Set-Cookie' header. (Current behavior, but
not remove session ID cookie)
This allows users to send arbitrary session ID cookie when it is
needed really needed, while avoiding accidental session ID cookie
removal.
What do you think?
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Stephen,
I realise you’re trying to remove WTF cases, but I don’t think removing advanced capabilities is the way to do that.
Yes. Even framework developer(?) seems to have current behavior.
To be honest, I didn't have idea what's wrong with user provided code
when I have a look at the bug report. I had to experiment a little to
understand what is going on.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi all,
I still have an issue with that. I believe the correct behaviour here is (assuming the
replace
argument toheader()
is honoured) what you’re seeing. Yes, it might be unexpected for new users, but its also expected by millions of current users/projects.I would suggest perhaps a warning on the
header()
docs page, and perhaps an example to avoid the issue on the Session handling page.Leaving it as-is, with improved docs means all functionality is possible with the right arguments.
Changing to your proposal means advanced use-cases are impossible with any arguments.
I realise you’re trying to remove WTF cases, but I don’t think removing advanced capabilities is the way to do that.
Yes. Even framework developer(?) seems to have current behavior.
In general, users shouldn't touch session ID. In case of user really
want to modify session ID cookie, following could be done.<?php
ob_start()
;
session_start()
;
header_remove('Set-Cookie');
header('Set-Cookie: PHPSESSID=xxxx something');
?>Make
header_remove()
able to delete 'Set-Cookie' header. (Current behavior)
Makeheader()
able to send 'Set-Cookie' header. (Current behavior, but
not remove session ID cookie)This allows users to send arbitrary session ID cookie when it is
needed really needed, while avoiding accidental session ID cookie
removal.What do you think?
Another idea for session ID cookie and Set-Cookie header protection.
Since we have setcookie()
function, how about to have cookie
dedicated functions for cookie header manipulation.
I'm about to create new feature request as follows:
Protect session ID and other cookies from header()
, header_remove()
header()
removes any previously defined headers.
header('Set-Cookie: something') / header_remove()
deletes session ID
and other Set-Cookie headers. Cookies should be protected from
header()
/header_remove().
Instead, create new cookie functions
cookie_set() - Set cookie header (setcookie() alias)
cookie_set_raw() - Set cookie header (setrawcookie alias)
cookie_custom() - Set cookie with custom style.
(The same as header(sprintf('Set-Cookie:
%s', something));
cookie_remove() - Remove all cookie header. $name parameter is cookie
name to be deleted.
Protect Set-Cookie headers from header()
and header_remove()
This implementation is cleaner because core to session
dependency is not required. It is also good to have naming standard
confirming cookie function names. i.e. Cookie functions should be
named cookie_*() according to CODING_STANDARDS.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Yasuo,
I don't think we should do anything about this beyond maybe warning the
user in the manual. header()
is a generic function for setting headers,
it would be surprising if it had different behaviour for cookies or
session cookies. It is possible that use of this function in this way
may be deliberate.
Thanks.
Andrea Faulds
https://ajf.me/
Hi!
There is 2 issues.
header()
removes all headers of the same name including 'Set-Cookie'header()
ignores replace flag. (This one is easy to fix)
We have the flag, so if it doesn't work it should be fixed. Also, one
should use setcookie()
for cookies, usually.
Possible resolutions:
- Prohibit 'Set-Cookie' for
header()
and force users to usesetcookie()
- Mitigate by disabling replace flag by default. (This is not a good idea, IMO)
I don't think we should do either.
I would like to prohibit 'Set-Cookie' by
header()
because it may
remove session ID cookie as well as auto login cookie, etc. If we
leave released version as it is now, I would like to prohibit
'Set-Cookie' byheader()
in PHP 7.1.
I don't think it's a good idea. If somebody is using header()
, it should
work like header()
works. If you don't like how it works, use setcookie.
Problem with this may be that user cannot modify 'Set-Cookie' header
line as user want.$ php -r 'setcookie("REMEMBERME=value; expires=Sat, 03-Sep-2020
05:38:43 GMT; path=/; domain=aaa");'
PHP Warning: Cookie names cannot contain any of the following '=,;
\t\r\n\013\014' in Command line code on line 1
You are using setcookie()
wrong here. See: http://php.net/setcookie
--
Stas Malyshev
smalyshev@gmail.com
Hi Stas,
I posted an an idea for preventing accidental cookie deletion.
'Set-Cookie' is a HTTP header, but provide dedicated functions for it. I pasted
it with a little modification.
What do you think?
Bottom line is I would like to prevent lost session ID by header()
in the future.
Implement cookie_*() functions in 7.x, then prohibit 'Set-Cookie' for
header()
in 8.x
There is 2 issues.
header()
removes all headers of the same name including 'Set-Cookie'header()
ignores replace flag. (This one is easy to fix)We have the flag, so if it doesn't work it should be fixed. Also, one
should usesetcookie()
for cookies, usually.
Another idea for session ID cookie and Set-Cookie header protection.
Since we have setcookie()
function, how about to have cookie
dedicated functions for cookie header manipulation.
I'm about to create new feature request as follows:
Protect session ID and other cookies from header()
, header_remove()
header()
removes any previously defined headers.
header('Set-Cookie: something') / header_remove()
deletes session ID
and other Set-Cookie headers. Cookies should be protected from
header()
/header_remove().
Instead, create new cookie functions
cookie_set() - Set cookie header (setcookie() alias)
cookie_set_raw() - Set cookie header (setrawcookie alias)
cookie_custom() - Set cookie with custom style.
(The same as header(sprintf('Set-Cookie:
%s', $something));
cookie_list() - Mostly the same as headers_list()
cookie_remove([string $name]) - Mostly the same as header_remove()
Remove cookie header. $name parameter is cookie name to be deleted.
Protect Set-Cookie headers from header()
and header_remove()
This implementation is cleaner because core to session
dependency is not required. It is also good to have naming standard
confirming cookie function names. i.e. Cookie functions should be
named cookie_*() according to CODING_STANDARDS.
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi All,
Just to make my earlier point of view crystal clear: As a purely userland party and someone maintaining a PHP framework, I don’t think it’s acceptable to limit which headers header()
/header_remove() can operate on, particularly when the problem you’re trying to ‘solve’ is simply incorrect use of the functions available. It is possible to achieve any outcome desired with correct use of the header, session and cookie functions (and assuming the $replace argument to header()
works correctly).
I still believe the way to solve this issue is with better information about usage, not by removing existing functionality.
So, please do not consider this to be an acceptable solution.
Cheers
Stephen
Hi Stas,
I posted an an idea for preventing accidental cookie deletion.
'Set-Cookie' is a HTTP header, but provide dedicated functions for it. I pasted
it with a little modification.
What do you think?Bottom line is I would like to prevent lost session ID by
header()
in the future.Implement cookie_*() functions in 7.x, then prohibit 'Set-Cookie' for
header()
in 8.xThere is 2 issues.
header()
removes all headers of the same name including 'Set-Cookie'header()
ignores replace flag. (This one is easy to fix)We have the flag, so if it doesn't work it should be fixed. Also, one
should usesetcookie()
for cookies, usually.Another idea for session ID cookie and Set-Cookie header protection.
Since we have
setcookie()
function, how about to have cookie
dedicated functions for cookie header manipulation.I'm about to create new feature request as follows:
Protect session ID and other cookies from
header()
,header_remove()
header()
removes any previously defined headers.
header('Set-Cookie: something') /header_remove()
deletes session ID
and other Set-Cookie headers. Cookies should be protected from
header()
/header_remove().Instead, create new cookie functions
cookie_set() - Set cookie header (setcookie() alias)
cookie_set_raw() - Set cookie header (setrawcookie alias)
cookie_custom() - Set cookie with custom style.
(The same as header(sprintf('Set-Cookie:
%s', $something));
cookie_list() - Mostly the same asheaders_list()
cookie_remove([string $name]) - Mostly the same asheader_remove()
Remove cookie header. $name parameter is cookie name to be deleted.Protect Set-Cookie headers from
header()
andheader_remove()
This implementation is cleaner because core to session
dependency is not required. It is also good to have naming standard
confirming cookie function names. i.e. Cookie functions should be
named cookie_*() according to CODING_STANDARDS.--
Yasuo Ohgaki
yohgaki@ohgaki.net