7

For my website, session management mostly works ok. Sessions are created, saved and used later without problems.

But when the code is using session_start(), it always creates new, totally empty session. Code in question below.

header('Content-Type: text/html; charset=UTF-8');

$main_domain = $_SERVER["HTTP_HOST"];
$expld = explode('.', $main_domain);

if(count($expld) > 2) {
   $tld = array_pop($expld);
   $domain = array_pop($expld);
   $main_domain = $domain . "." . $tld;
}

session_set_cookie_params (0, '/', $main_domain);
session_name('sid');
session_start();
echo session_id();
exit;

When this script is executed, in every reload new session is created.

smar@ran ~> ls /tmp/sess_* | wc -l
10
smar@ran ~> ls /tmp/sess_* | wc -l
11
..
smar@ran ~> ls /tmp/sess_* | wc -l
17

But only the one of those sessions has any data inside it, and is used by application.

Output in browser is always same: 87412d5882jr85gh5mkasmngg7, which is id in browser’s cookie and session id in /tmp that has data populated to it.

What could be cause of this behaviour? Those empty files aren’t exactly huge problem, but they do make /tmp (or session dir) quite populated for no reason.

EDIT 1:

Looks like this is server related problem, since it works for some people. My configuration is Gentoo Linux (32 bit) with Apache and PHP 5.3.6.

If I force it to create new session (like removing my own cookie), it creates two session files instead of one. If it reuses old one, it creates “only” one.

EDIT 2:

Session configuration, as requested (all config rows with session.):

session.save_handler = files
session.save_path = "/tmp"
session.use_cookies = 1
session.use_only_cookies = 1
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 0
session.cookie_path = /
session.cookie_domain =
session.cookie_httponly =
session.serialize_handler = php
session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 1440
session.bug_compat_42 = On
session.bug_compat_warn = On
session.referer_check =
session.entropy_length = 0
session.entropy_file =
session.cache_limiter = nocache
session.cache_expire = 180
session.use_trans_sid = 0
session.hash_function = 0
session.hash_bits_per_character = 5

EDIT 3:

Even more strangely, I tried to use sessions from CLI. There, where no session cookies are set, it always created one new session. When setting fixed session value with session_id() stopped new session creation altogether and used old session instead.

This behaviour is identical with Apache, so I’m starting to suspect this is bug in PHP. No new sessions created if name specially set with session_id(), and session correctly used.

Even more absurdly, when I took phpsessid from $_COOKIE["PHPSESSID"] and set that to session_id(), it started to create new (useless empty ones) sessions again.

EDIT 4:

Since I didn’t write it enough clearly: simply having

session_start()

as single argument causes this problem to happen, it is not specific to my code.

Smar
  • 8,109
  • 3
  • 36
  • 48
  • what about session time? and try to comment `session_set_cookie_params (0, '/', $main_domain);` may be other place witch to put session named 'sid' – Subdigger Jul 25 '11 at 11:23
  • And what happens whether you put your session_start before sending the headers... ? – hornetbzz Jul 25 '11 at 11:25
  • 1
    @Subdigger: yup, no avail. Even if it is the place it is, it doesn’t create session before the session stuff, so I suspect this is server configuration related things. *updates the question* – Smar Jul 25 '11 at 11:31
  • I'm running PHP 5.3.3-7+squeeze1 with Suhosin-Patch (cli) (built: Mar 18 2011 20:10:12), similar problem – genesis Jul 25 '11 at 11:35
  • Ain't that a security breach to allow users reading from `/tmp` ? It's shared and the session ID is readable... – Dor Jul 25 '11 at 11:44
  • @Dor: /tmp is default location where PHP saves sessions. I’d guess about 99% of PHP installations saves sessions there. That much for common security. Myself, I don’t run my code in shared host, so the location is as safe as anything *PHP* can read. That’s the security hole to the server most likely anyway. – Smar Jul 25 '11 at 11:48
  • The fact that 99% of the installations do that, doesn't make it correct... Once a man thought the world is round while the rest of the world thought it's flat. Update the question with session configuration options. – Dor Jul 25 '11 at 11:55
  • @Dor I still have to hear a reason for it to be changed. *updates* – Smar Jul 25 '11 at 11:57
  • @Smar: Maybe a configuration change isn't *necessary*. That's what we're trying to find out... – Dor Jul 25 '11 at 11:59
  • @Dor: sorry if I sounded rude, but I am concerned of security, so if there is valid reason for not having sessions in /tmp but in some other reason (for a server no-one but admin can be legally logged in), I’d like to hear it. But maybe that would actually be content of another question... – Smar Jul 25 '11 at 12:04
  • Is your site running on a port ? What you have for `$main_domain` won't run as expected if your domain contains a port. – tftd Jul 25 '11 at 13:13
  • @tftd: Nope, it is standard port. Please also note that simply calling session_start() causes this problem. – Smar Jul 25 '11 at 13:22
  • Can you please try setting `$main_domain` to your domain `$main_domain = '.example.com';` ? I've changed that and your code works fine here. ( http://pastebin.com/iCEV2sWm ) – tftd Jul 25 '11 at 13:59
  • Are you running the scripts on a dedicated/vps server or you're using a shared hosting ? Also are you sure there isn't any additional php.ini files that overwrite the session settings ? – tftd Jul 25 '11 at 16:05
  • There isn’t any scripts that could affect the php... No crons, and I do my scripts with something completely different language than PHP. Nor there should be any PHP overrides, I tested without xdebug already, so it isn’t its fault... – Smar Jul 25 '11 at 16:28
  • Could you please add a php script with ``. Open it from a browser and search for `Configuration File (php.ini) Path`, `Loaded Configuration File`, `Scan this dir for additional .ini files`, `Additional .ini files parsed`. See if you have additional .ini files loaded. My theories are: you have a php.ini file you don't know of; you have an php addon that's causing this;you're php package is bugged somehow - try compiling or installing a new package ( uninstall the previous one before that ). – tftd Jul 26 '11 at 14:32
  • @tftd: I have Gentoo, so basically everything is compiled already. Maybe I could try with minimal useflags or such to see if it happens without any special module... I’ll test those ini files tomorrow. – Smar Jul 26 '11 at 18:25
  • @tftd: The default php.ini (/etc/php/apach2-php5.3/php.ini) is used, and there is no other ini files (except xdebug.ini which I tested without already) There is mention about .user.ini file for user defined ini things, but I think this is default of PHP and nothing Apache sets it itself (I don’t know where to search it from, for start....) – Smar Jul 27 '11 at 10:55
  • Can you post your `uname -a` and PHP and Apache versions? – Scott Arciszewski Feb 20 '14 at 16:27

5 Answers5

2

Cookies are only returned to the vhost / path where they were set from.

Since your path is '/', that implies that the pages are not being requested via $domain . "." . $tld;

e.g. user requests page via www.example.com

cookie is set for example.com

user access subsequent page from www.example.com - the cookie is not in scope.

From RFC 2965

x.y.com domain-matches .Y.com but not Y.com.

Actually, if you read on, the spec does say that the user agent should prefix the host with a dot if none is supplied however you getting into the realm where browser behavuiour varies.

If you simply return the cookie with a vhost matching the request it will work as expected.

symcbean
  • 47,736
  • 6
  • 59
  • 94
  • You are correct about me missing dot at start of the cookie; browsers seems not to require it though. Whole point of this exploding (visible in the example for clarify) is to have cookie set in top level domain so they are also visible in sub level domain. .foo.tld would do this, and it works; sessions works, it just creates those empty files for each reload. – Smar Jul 25 '11 at 12:15
  • This is a very useful bit of information that clarified this issue in my situation and solved the problem of session id's being regenerated on reload. As a note, i could not get it to work by prefixing the host with a . as it seems in most modern browsers that this is interpreted as an invalid url? Thanks symcbean! – Craig van Tonder Apr 29 '15 at 23:08
0

I think powtac is right in a way, but session_start(); should be your first operation you do, even before the header('Content-Type: text/html; charset=UTF-8');

Smar
  • 8,109
  • 3
  • 36
  • 48
Ivan Schrecklich
  • 499
  • 1
  • 4
  • 16
0

This is not exactly about the original cause, but the resolution is exactly same: new session ids gets defined with each reload.

In this case, fault was Varnish, which was set to put every request to pass mode (return (pass)) instead of caching everything. As consequence, every request made it to the backend, where session_start() was called every time.

But when the response was sent through Varnish to the client, cookies were removed from the response. This is due that backend sets cookies (session id, along with others) even when we want to have the site be cached. Anyway, cookies get removed, client does another request and does not pass any cookies (it never received any!) and there PHP goes again calling session_start() without any session id present...

This is more of fault in recognization of error in this case, which appeared as multitude of unnecessary sessions created. Those would’ve not been created in first place if caching was enabled in first place.

There is also another way to manage to create these sessions: have browser not to accept cookies at all. Stupid reason, I know, but it does happen...

For the original problem, I haven’t stumbled it since moving from original development machine away.

Smar
  • 8,109
  • 3
  • 36
  • 48
0

I'd hate to be the stick in the mud, but have you checked that /tmp is both readable and writeable by PHP (in most cases, this means the www-data user)? If not, move the session save location to a location that you can write to.

Scott Arciszewski
  • 33,610
  • 16
  • 89
  • 206
  • Yes, that was not the problem. Session were created without problems, by php, there. – Smar Feb 20 '14 at 11:29
  • Okay, try `phpinfo()` and see if anything overwrites the session cookie domain, etc. or sets secure=1. (I'm assuming the session config above is from php.ini) – Scott Arciszewski Feb 20 '14 at 16:24
  • FWIW, this problem was ages ago and nowadays has disappeared, when switching machine to another, so I can’t test this problem anymore. I’ve never done changes to those flags, and the config I had was Gentoo’s default PHP config at the time, so I doubt that was it either. – Smar Feb 21 '14 at 08:07
0

Use session_start() as first session command, before all other session_*() methods!

powtac
  • 40,542
  • 28
  • 115
  • 170
  • This only disables those cookie settings, and doesn’t solve problem. Already tested, as seen in comments of the question. (I tested again just to be sure) – Smar Jul 25 '11 at 12:44
  • It's not a problem to set the session later in your code but you have to be 1000% sure that you send headers before your session_*() commands and you don't get any error_reporting lines. If you don't have anything like that you can set session_*() wherever you want or need :) – tftd Jul 25 '11 at 13:16
  • simple session_start() as only row in the application causes the problem, so I doubt it’s anything like that. – Smar Jul 25 '11 at 13:53