tsangaris Posted September 20, 2014 Share Posted September 20, 2014 I am trying to learn how to program in PHP. For a long time i was using WAMP and my localhost. When i ran into trouble i searched the web, watched videos and eventually find a solution. Trying to upload my scripts into a shared hosting web server i had some difficulties in basic things, like using $_SESSION superglobal variable. What i want to do is to use a hidden field with a value inside a form, and after submitting the form, to compare the $_SESSION variable to the $_POST variable in order to check for CSRF. <?php //call all custom functions require_once('Custom_Functions/functions.php'); //session must be send before HTML headers secure_session_start(); ?> <!DOCTYPE html> <html lang="en"> <body> <?php if(isset($_POST['submit'])) { $postvalue = $_POST['input1']; $sessionvalue = $_SESSION['hashed_token']; echo '<br />==========================<br />'; echo '<br />AFTER PRESSING SUBMIT<br />'; echo '<br />==========================<br />'; echo 'Value of $_POST["hashed_token"] = '.$postvalue.'<br />'; echo 'Value of $_SESSION["hashed_token"] = '.$sessionvalue.'<br />'; } $hashed_token = hash('sha256', uniqid(mt_rand(), TRUE)); $_SESSION['hashed_token'] = $hashed_token; echo '<br />==========================<br />'; echo '<br />BEFORE PRESSING SUBMIT<br />'; echo '<br />==========================<br />'; echo '<br />Value of $_SESSION["hashed_token"] = '.$hashed_token.'<br />'; ?> <form action="" method="POST"> <input type="hidden" name="input1" value="<?php echo $hashed_token; ?>" /> <p><input type="submit" name="submit" /></p> </form> </body> </html> In this script i have 1 custom function: a) secure_session_start() function secure_session_start(){ //Set a custom session name $session_name = 'TESTSESSID'; ini_set('session.use_only_cookies', 1); ini_set('session.entropy_file', '/dev/urandom'); if (in_array('sha512', hash_algos())) { ini_set('session.hash_function', 'sha256'); } ini_set('session.use_trans_sid', 0); ini_set('session.hash_bits_per_character', 5); ini_set('session.cookie_secure', 1); $secure = TRUE; $httponly = TRUE; $cookieParams = session_get_cookie_params(); session_set_cookie_params($cookieParams['lifetime'], $cookieParams['path'], $cookieParams['domain'], $secure, $httponly); session_name($session_name); ini_set("session.save_path", "/home/SESSIONS"); session_start(); } The procedure goes as follows: FIRST COMMUNICATION WITH THE SERVER: The superglobal variable $_SESSION['hashed_token'] is assigned the random hash value, which is then passed to the hidden input field. I then echo it. RESULT: ==========================BEFORE PRESSING SUBMIT==========================Value of $_SESSION["hashed_token"] = 93438a1b9b72085ce9430291acebdc4cfdee9d001b91a26207aebc22e04689fc SECOND COMMUNICATION WITH THE SERVER: The user press the submit button, the script then checks if the submit button is pressed, and gets in the if statement(because is TRUE). Then i collect the $_POST and $_SESSION values and echo them. New random hash is assigned to the $_SESSION superglobal variable. RESULT: ==========================AFTER PRESSING SUBMIT==========================Value of $_POST["hashed_token"] = 93438a1b9b72085ce9430291acebdc4cfdee9d001b91a26207aebc22e04689fcValue of $_SESSION["hashed_token"] = 8f176aeb3a09a1b30e0ea862c78625d7c11743da933d366cface3fa238388e57==========================BEFORE PRESSING SUBMIT==========================Value of $_SESSION["hashed_token"] = c3442382b146f03394ad86911018247c57fa19d4a653d0bf6bb9bc7506e88ca0 For me this is very weird. The random hash is assigned to the $_SESSION variable, but when i try to call it after the submit is pressed its giving me a complete different value. If i remove the function secure_session_start() and just use session_start() it works: RESULT (using session_start() ) ==========================AFTER PRESSING SUBMIT==========================Value of $_POST["hashed_token"] = a5eaaaa38c428af623a599e664ea9c64a2ff0674e18e9250c54e52bbc586b614Value of $_SESSION["hashed_token"] = a5eaaaa38c428af623a599e664ea9c64a2ff0674e18e9250c54e52bbc586b614==========================BEFORE PRESSING SUBMIT==========================Value of $_SESSION["hashed_token"] = e2d4acc239a747217860d71a80553abd41142dbeb8f6fafab511caff8a081fc4 Any ideas why this is happening? The problem is inside the secure_session_start() function but i cant find out why. Also, when i use the secure_session_start() function and more specifically the ini_set("session.save_path", "/home/SESSIONS"); i am forcing the session to be stored inside the /home/SESSIONS folder. But when i only use the session_start() the session i still gets stored inside that path. I checked my .htaccess and there is nothing storing the sessions in that folder. Why is that? One last thing: When using FIREBUG-->Cookies is see 2 names: the custom one (TESTSESSID) and PHPSESSID(which is the default). Shouldnt i only see the custom session name only? Thanks in advance. Quote Link to comment https://forums.phpfreaks.com/topic/291188-different-session-value-after-submitting-form/ Share on other sites More sharing options...
mac_gyver Posted September 20, 2014 Share Posted September 20, 2014 the code you found that's setting the session parameters is setting the session.cookie_secure setting to a true/1 value. this means that the session id cookie will ONLY be sent to the server when making a https request over an encrypted connection. Quote Link to comment https://forums.phpfreaks.com/topic/291188-different-session-value-after-submitting-form/#findComment-1491678 Share on other sites More sharing options...
tsangaris Posted September 20, 2014 Author Share Posted September 20, 2014 the code you found that's setting the session parameters is setting the session.cookie_secure setting to a true/1 value. this means that the session id cookie will ONLY be sent to the server when making a https request over an encrypted connection. Yes i know, but i have an SSL certificate configured to my domain, and i am forcing each page to use https through .htaccess: #TURNS HTTPS ON RewriteEngine On RewriteCond %{HTTPS} !=on RewriteRule ^(.*) https://%{SERVER_NAME}/$1 [R,L] Is this correct? Thanks for the response. Quote Link to comment https://forums.phpfreaks.com/topic/291188-different-session-value-after-submitting-form/#findComment-1491679 Share on other sites More sharing options...
Jacques1 Posted September 21, 2014 Share Posted September 21, 2014 Are you sure that the code in your first post is actually the one you're using? Are you sure that you're generating the anti-CSRF token only in the form script? And does the problem always occur or only sometimes, maybe after you've switched the browser tab? In any case, regenerating the token on every request is a bad idea in the times of tabbed browsing. The problem you currently have is exactly what will happen to your users if they open your forms in multiple tabs: Once they submit a form, the token in the session changes, and the tokens of all other tabs are out of sync and must be manually refreshed. Otherwise the user gets a token mismatch. This is very annoying and has very little benefit for security. In fact, I have a hard time coming up with a scenario where it would even make sense to refresh the token more often than the session ID. Generate the token once when the session is created and keep it until the end of the session. This may in fact fix your problem immediately. Quote Link to comment https://forums.phpfreaks.com/topic/291188-different-session-value-after-submitting-form/#findComment-1491688 Share on other sites More sharing options...
tsangaris Posted September 21, 2014 Author Share Posted September 21, 2014 Are you sure that the code in your first post is actually the one you're using? Are you sure that you're generating the anti-CSRF token only in the form script? And does the problem always occur or only sometimes, maybe after you've switched the browser tab? In any case, regenerating the token on every request is a bad idea in the times of tabbed browsing. The problem you currently have is exactly what will happen to your users if they open your forms in multiple tabs: Once they submit a form, the token in the session changes, and the tokens of all other tabs are out of sync and must be manually refreshed. Otherwise the user gets a token mismatch. This is very annoying and has very little benefit for security. In fact, I have a hard time coming up with a scenario where it would even make sense to refresh the token more often than the session ID. Generate the token once when the session is created and keep it until the end of the session. This may in fact fix your problem immediately. Thanks for the advice. Its generally a good approach not to regenerate the token in each reload of the page. I can see that know. To bypass this i added the following code at the top, where the session_start() is: secure_session_start(); $current_sessid = $_COOKIE['TESTSESSID']; $new_sessid = session_id(); if($current_sessid != $new_sessid) { $hashed_token = AntiCSRFtoken(); echo $hashed_token; $_SESSION['hashed_token'] = $hashed_token; } The weird part is that, when i use the custom secure_session_start(), i does not work. When i use the default PHPSESSID it works fine. session_start(); $current_sessid = $_COOKIE['PHPSESSID']; $new_sessid = session_id(); if($current_sessid != $new_sessid) { $hashed_token = AntiCSRFtoken(); echo $hashed_token; $_SESSION['hashed_token'] = $hashed_token; } Any ideas why the custom secure_session_start() causes this kind of trouble? And if cant bypass it and i have to use the session_start() how do i make sure that the following options are enabled for my domain? Is the .htaccess reliable for this purpose? ini_set('session.use_only_cookies', 1); ini_set('session.entropy_file', '/dev/urandom'); if (in_array('sha512', hash_algos())) { // Set the has function. ini_set('session.hash_function', 'sha256'); } ini_set('session.use_trans_sid', 0); ini_set('session.hash_bits_per_character', 5); ini_set('session.cookie_secure', 1); $secure = TRUE; $httponly = TRUE; Thanks. Quote Link to comment https://forums.phpfreaks.com/topic/291188-different-session-value-after-submitting-form/#findComment-1491694 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.