php - Issue with session_regenerate_id and Chrome prefetch/render -
i have issue session functionality , way chrome prefetching/rendering. attempting interface piece of forum software (esotalk) custom laravel 4.3 app. have authentication event listeners cause laravel create php session (in addition built in laravel session) allows forum , app share authentication details. on access of forum, , if user not logged in - shared information exists (i.e. user has logged in on laravel app), forum log in user using information available in session.
for part works fine except chromes prefetching appears breaking things. if monitor forum using debugger can see when type out forum url before hit enter chrome access forum. following through debugger can see needs , successful in logging in. final step forum regenerates session id stop hijacking. breaks. looks chrome ignores new session id (sent via http setcookie header) when hit enter go forum (and make whole new request) using original session id. id doesn't exist set new 1 , consequently lose logged in status. user looks never got logged in.
i've googled high , low suggestions how can work around this. i'm loath removed session id regeneration serve security purpose. can't disable chrome prefetching/rendering. in appear in bit of pickle.
i have created code replicates this. though relies on prerendering kicking in (so you'll need hit each of files via address bar number of times)
// test1.php <?php function regeneratetoken() { session_regenerate_id(true); $_session["token"] = substr(md5(uniqid(rand())), 0, 13); $_session["useragent"] = md5($_server["http_user_agent"]); } // start session. session_set_cookie_params(0, '/'); session_name("sessionbork_test_session"); session_start(); $_session["sentryuserid"] = '99'; regeneratetoken(); header('content-type: text/plain'); foreach ($_session $k => $v) { echo $k . " = " . $v . "\n"; }
access test1.php followed test2.php , should see bunch of session variable output. prerendering/fetching kicks in you'll start getting broken message.
// test2.php <?php function regeneratetoken() { session_regenerate_id(true); $_session["token"] = substr(md5(uniqid(rand())), 0, 13); $_session["useragent"] = md5($_server["http_user_agent"]); } // start session. session_set_cookie_params(0, '/'); session_name("sessionbork_test_session"); session_start(); if (empty($_session["token"])) regeneratetoken(); // complicate session highjacking - check current user agent against 1 initiated session. if (md5($_server["http_user_agent"]) != $_session["useragent"]) session_destroy(); // log in user based on sentryuserid // ... logging in, setting userid, regenerating session $_session["userid"] = '10'; regeneratetoken(); header('content-type: text/plain'); foreach ($_session $k => $v) { echo $k . " = " . $v . "\n"; } if ( ! isset($_session['sentryuserid'])) echo "\n--\nprerendering brokeded me.";
if can hooked xdebug in ide or should see hidden prerender hit test2.php (which looks absolutely correct in response) , subsequent actual hit when press enter it's forgotten are.
one way around issue detect pre-fetches, , not generate new session id on loads. see stack overflow information on detecting prefetching in various browsers: http header detect preload request google chrome
additionally, argue there better ways go prevention of session hijacking (e.g. tying session ip address, browser signature, etc.)
additionally, there may second bug in code: calling session_destroy()
destroys session , closes out user's session. need call session_start()
prior calling session_regenerate_id()
. see documentation here , examples here.
Comments
Post a Comment