Req #67146 [Nab]: PHP sends session info in the clear when secure is enabled
| From: | rasmus@php.net | Date: | Tue, 29 Apr 2014 00:40:52 +0000 |
| Subject: | Req #67146 [Nab]: PHP sends session info in the clear when secure is enabled | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-185488@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=67146&edit=1
ID: 67146
Updated by: rasmus@php.net
Reported by: lightnb at bellsouth dot net
Summary: PHP sends session info in the clear when secure is
enabled
Status: Not a bug
Type: Feature/Change Request
Package: Session related
Operating System: Ubuntu 14.04
PHP Version: 5.5.11
Block user comment: N
Private report: N
New Comment:
Yes, just to reiterate what Stas said here, an extremely common architecture is to terminal SSL at
the load balancer and run non-SSL behind it. Most of these setups have ways to set a special header
informing the backend web servers that the client connection is encrypted, but unfortunately there
is no standard way to do this. You have to do this check yourself at the application level to match
how your SSL-terminating device is passing this on. If we hardcoded some check in PHP we would be
flooded with bug reports about us breaking perfectly secure setups.
You can read a good description here:
http://www.lullabot.com/blog/article/setting-ssl-offloading-termination-f5-big-ip-load-balancer
I work at Etsy and our architecture is similar. I would guess most larger sites are doing something
along these lines.
Previous Comments:
------------------------------------------------------------------------
[2014-04-29 00:11:28] stas@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to
report
a bug at http://bugs.php.net/how-to-report.php
------------------------------------------------------------------------
[2014-04-28 23:55:13] stas@php.net
PHp can not know if the connection is secure or not, since PHP has no idea what network
infrastructure between the end client and PHP looks like. There could be relays, VPNs, multiple
routers and load balancers adding and removing layers of SSL... And PHP code be a responder at the
end of FastCGI protocol which doesn't have any knowledge even of the nearest hop, let alone all
the hops on the road. So checking for SSL on the last hop is useless security-wise, and may break
many valid setups which add SSL layer later.
The secure setting is not for PHP, it is for the browser - that does know if it's using HTTPS
or not to connect. PHP, however, has no good way to know if the browser used HTTPS or not and if it
will be using HTTPS in the future, since PHP may not be talking to the browser directly.
------------------------------------------------------------------------
[2014-04-28 15:30:45] lightnb at bellsouth dot net
Description:
------------
Using session_set_cookie_params() to enable "secure" cookies, PHP will set a cookie with
the secure flag, but does not check if the session_start() occurred over a secure connection to
begin with.
This creates two problems:
1. The SessionID is translated in the clear to the browser, which defeats the purpose of secure
SSL-only Session cookies.
2. Since the cookie is set to secure, it is not submitted when the page is refreshed or another
non-SSL page is navigated to. This is correct, but the result is PHP does not get the cookie and PHP
re-issues a new session ID cookie, which it then again, submits over plain text. When switching
between SSL and non-SSL, this can silently create all sorts of session oddities.
The user can solve this by wrapping the session setup in a block that checks if SSL is enabled, but
if the user does not realize this, they may think they are setting up a secure cookie, when in fact
they end of with a cookie that is transferred in the clear and reset on each non-SSL page.
Test script:
---------------
// Run over a non SSL connection:
session_set_cookie_params(0,'/','domain.com',true,true);
session_start();
Expected result:
----------------
I think this should throw at least a warning if not a fatal exception.
Either refuse to create the session and create a warning: "Session was not created. You asked
for a secure session cookie but this page is running over an unsecured connection".
OR
"Fatal Error: Cannot start secure session over an insecure connection"
Actual result:
--------------
From above:
1. The SessionID is translated in the clear to the browser, which defeats the purpose of secure
SSL-only Session cookies.
2. Since the cookie is set to secure, it is not submitted when the page is refreshed or another
non-SSL page is navigated to. This is correct, but the result is PHP does not get the cookie and PHP
re-issues a new session ID cookie, which it then again, submits over plain text. When switching
between SSL and non-SSL, this can silently create all sorts of session oddities.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=67146&edit=1