Edited:
I am too sad that this question was downvoted, I was stuned by this for many hours.I wish there are a lovely alchemist who can make me back from debuff condition.
I am using codeigniter,I think the problem is when the new session (the session with flash message) is set, the session id (as a cookie) does not send to client, so after redirect to other pages, a fresh new session is created.
There is a problem in my log out function. The logic is simply click "log out", redirect to index page with a flash message--You have been log out.
After inspect, I found these things:the old session is clear with no problems, the new session is created before redirection, the new session do has flash message. Then the strange things comes, when redirected to index, a fresh newer session is created. But, If I do not run redirection after adding flash message, and click browser's refresh, then go to index manually, the session with flash message will be there and displayed perfectly.
I also found before redirection or refresh browser, though the session is recreated, there is no session id in my cookies. The refresh action sends session id to my cookies.
I hope I made the question clear. Thank you.
//auth controller
public function logout()
{
$this->my_auth_lib->logout();
$this->session->set_flashdata('alert','You have been logged out!');
redirect('index');
}
//my_auth_lib
public function logout()
{
return $this->session->sess_destroy();
}
// session library sess_destory method
public function sess_destroy()
{
// get session name.
$name = session_name();
if (isset($_COOKIE[$name])) {
// Clear session cookie
$params = session_get_cookie_params();
setcookie($name, '', time() - 42000, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
unset($_COOKIE[$name]);
}
$this->sess_create();
}
//session library sess_create method
public function sess_create()
{
$_SESSION[$this->sess_namespace] = array(
'session_id' => md5(microtime()),
'last_activity' => time()
);
// Set matching values as required
if ($this->_config['sess_match_ip'] === true) {
// Store user IP address
$_SESSION[$this->sess_namespace]['ip_address'] = $this->ci->input->ip_address();
}
if ($this->_config['sess_match_useragent'] === true) {
// Store user agent string
$_SESSION[$this->sess_namespace]['user_agent'] = trim(substr($this->ci->input->user_agent(), 0, 50));
}
$this->store = $_SESSION[$this->sess_namespace];
}
Try putting an
exit;
statement in the line right after the redirect
Got the idea from here
PHP: session isn't saving before header redirect
Related
I am facing some weird issue of session variable getting reset on action redirect.
I am using Codeigniter and redirecting to dashboard action after login, I am getting data in login action after verifying credentials with DB, but when I use redirect() to redirect to dashboard, session variables gets vanished.
Admin.php
<?php class admin extends CI_Controller
{
function login()
{
$login = $this->Admin_model->login($this->input->post()); // <-- verify data and set to session
if($login)
{
$this->session->set_flashdata("success","Logged in Successfully");
var_dump($_SESSION); // <-- able to fetch data from session
// exit();
redirect("admin/dashboard");
}
else
{
$this->session->set_flashdata("error","Invalid Credentials!! Please Try Again!!");
redirect("admin");
}
}
function dashboard()
{
var_dump($_SESSION); // <-- session data is vanished and not able to get userdata('id')
exit();
if($this->session->userdata('id') != '')
{
$data['active_tab'] = "dashboard";
}
else
{
redirect("admin");
}
}
?>
Admin_model.php
<?php Class Admin_Model extends CI_Model
{
function login($data)
{
$user = $this->db->get_where("users",array("username" => $data['username'],
"password" => md5($data['password']),
"is_active" => "1")
)->row_array();
if(!empty($user))
{
$this->set_user_session($user);
return true;
}
else
{
return false;
}
}
function set_user_session($login)
{
$arr = array();
$arr["id"] = $login["id"];
$arr["username"] = $login["username"];
$this->session->set_userdata($arr);
}
?>
Tried this in xampp and wamp, all browsers but still the issue remains the same, any help would be grateful.
Which version of CodeIgniter are you working with? You can try the following steps.
Go to system/libraries/Session/Session.php
Comment session_start() by adding //. We want to relocate the sessionn_start().
Find (using ctrl + f) a comment that says Security is king. Comment out all the line under that comment until the end of the function. In my case I commented out the line number 315 - 320.
on line number 282 change this line ini_set('session.name', $params['cookie_name']); to ini_set('session.id', $params['cookie_name']);
comment out following lines
line 108 //session_set_save_handler($class, TRUE);
line 290-296
// session_set_cookie_params(
// $params['cookie_lifetime'],
// $params['cookie_path'],
// $params['cookie_domain'],
// $params['cookie_secure'],
// TRUE // HttpOnly; Yes, this is intentional and not configurable for security reasons
// );
line 305 //ini_set('session.gc_maxlifetime', $expiration);
Go to the main index.php, it is the first index.php and located in the same directory with the sub-directories 'application', 'system', 'user_guide', etc.
Put session_start() right after < ?php
Hope this can help you....
You have to use this->session->set_userdata() for setting the session. this->session-> set_ flashdata() is used for setting flash messages which are removed after next action.
The new versions of the browsers might be destroying the session because of the new cookie policy.
References
https://developers.google.com/search/blog/2020/01/get-ready-for-new-samesitenone-secure
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite
Whenever the cookie is required to be sent to server, the browser sees the SameSite attribute to decide if the cookie to be sent to server or blocked. For user actions, it is sent to the server but for auto-redirects, it doesn't if SameSite is set to 'Strict' or 'Lax' (Lax is going to be the default value now).
Solution:
The cookie attribute SameSite can be set to 'None' along with specifying the 'Secure' attribute to 'true'. Setting 'Secure' attribute to 'true' would require your site to run on https. Sites running with http:// protocol will not be able to set 'Secure' cookie.
Please set the 'HttpOnly' attribute to 'true' for making it accessible for http requests to the server only.
In PHP, it can be achieved as below
session_set_cookie_params(0, '/PATH/; SameSite=None', <COOKIE_DOMAIN>, true, true);
In order to increase the security for the logged-in users, after the session_start(); and assigning the other session variables, I also try to store the HTTP_USER_AGENT value, using $_SESSION['agent'] = md5($_SERVER['HTTP_USER_AGENT']); for the login.php page.
Besides, in the login.php page, I redirect logged-in users to the home page if they try to visit it again without logging it out first, using the conditional like this:
if (isset($_SESSION['agent']) OR ($_SESSION['agent'] = md5($_SERVER['HTTP_USER_AGENT']) ) ) {
//redirect to home page
header('location:http://index.php.com');
exit();
}
The question is that in my logout.php page I code the conditional like this:
if (!isset($_SESSION['agent']) OR ($_SESSION['agent'] != md5($_SERVER['HTTP_USER_AGENT']) ) ) {
//Redirect to home page
}else{
$_SESSION = array(); // Destroy the variables.
session_destroy(); // Destroy the session itself.
setcookie (session_name(), '', time()-3600); // Destroy the cookie.
}
Then I came back to visit the login.php page again as a logged-in user (session has been set), it still redirected me to the home page.
Then I tried deleting the cookies in the FF browser, close it, then revisited the login.php page, it still redirected me.
Do you know what I was wrong or missing?
NOTE: I have no problem to destroy the session if not storing **the HTTP_USER_AGENT
You have an assignment where you want to check.
Change:
if (isset($_SESSION['agent']) OR ($_SESSION['agent'] = md5($_SERVER['HTTP_USER_AGENT']) ) ) {
to
if (isset($_SESSION['agent']) OR ($_SESSION['agent'] == md5($_SERVER['HTTP_USER_AGENT']) ) ) {
off topic security tip(maybe helpfull):
public function Start_Secure_Session()
{
// Forces sessions to only use cookies.
ini_set('session.use_only_cookies', 1);
// Gets current cookies params
$cookieParams = session_get_cookie_params();
// Set Cookie Params
session_set_cookie_params($cookieParams["lifetime"], $cookieParams["path"], $cookieParams["domain"], $this->isHTTPS, $this- >deny_java_session_id);
// Sets the session name
session_name($this->session_name);
// Start the php session
session_start();
// If new session or expired, generate new id
if (!isset($_SESSION['new_session']))
{
$_SESSION['new_session'] = "true";
// regenerate the session, delete the old one.
session_regenerate_id(true);
}
}
I've got a small problem with my smarty project, logout problem to be precise. I have a index.php page which is the "main" page and it gets POST data and directs actions based on current data. There`s checking if the session variables has been set. Now when I login I have function like this:
function login($value)
{
$res = $this->sql->checkLogin($value);
if($res)
{
//checks if user is admin
$isadm = $this->sql->isAdm($value);
if($isadm == true)
{
$_SESSION['user'] = $value['name'];
$_SESSION['adm'] = true;
$message = 'Admin';
$this->tpl->assign('var', $message);
if($_SESSION['adm'] == true)
{
//sets some variables for admin users
$navigation = 'navi';
$this->tpl->assign('navigation', $navigation);
}
$this->tpl->display('maint_main.tpl');
}
//user is not admin
else
{
$_SESSION['user'] = $value['name'];
$_SESSION['adm'] = false;
$message = 'Perus';
$this->tpl->assign('var', $message);
if($_SESSION['adm'] == true)
{
$navigation = 'navi';
$this->tpl->assign('navigation', $navigation);
}
$this->tpl->display('maint_main.tpl');
}
}
//login failes, show login form and info
else
{
$message = 'Login failed';
$this->tpl->assign('var', $message);
$this->tpl->display('login_form.tpl');
}
}
and logout function :
function logout()
{
setcookie(session_name(), '', time()-42000, '/');
session_unset();
session_destroy();
$this->tpl->display('login_form.tpl');
}
These work just about the way they are supposed to but the real problem occurs when I log out and redirect to the login_form.tpl. If I use the back button of the browser the POST data with username and password is retrieved and the login goes through again. This causes that those pages behind login are still viewable. As I am not quite familiar with Smarty yet I couldn`t figure out any way to fix this. So basically how to prevent access to that POST data after logout?
I don't think this has anything to do with smarty. This is a browser/http generic issue. Most browsers will re-post form data after confirmation from the user.
One approach to make re-posts of the form invalid would be to pass along a secret code/token (perhaps a guid or your session id) which is also stored in session data. When the user logs out, clear their session (or at least the secret code you're checking). When the user logs in, check to make sure that the confirmation code matches the one for the current session.
This pattern is often used to manage csrf attacks and is often known as a 'synchronizer token'. This blog post provides a good explanation https://blog.whitehatsec.com/tag/synchronizer-token/
I am facing a very strange problem , i am doing CasLogin in my application..
i have successfully implemented CAS, i.e all values are set in $_SESSION variable after all proper validations, and successful login, but when i redirect it from CasLogin() action to Index Action $_SESSION contains nothing..
i am using Yii Frame Work.
here is code.
public function actionCasLogin($CID=NULL)
{
//code to be imported from GMS here
PhpCasControl::setPhpCasContext($CID);
phpCAS::setPostAuthenticateCallback(array($this,'_saveServiceTkt'));
$loginForm = new CasLoginForm;
// validate user input and redirect to the previous page if valid
if ($loginForm->login($CID)) {
if (Yii::app()->user->isGuest){
echo '<br> <br> This shows up..';
var_dump($_SESSION);
}
else{
echo 'Hello at caslogin <br>never shows up';
var_dump(Yii::app()->user->id);
}
$this->redirect(array('index'));
}
else {
throw new Exception("You don't have sufficient permissions to access this service. Please contact Administrator !");
}
}
this function Works Properly and if i put a EXIT; here it will display $_SESSION with all the desired values..
but after redirection... to index..
whose code is this..
public function actionIndex()
{
echo"hello at index";
if (! Yii::app()->user->isGuest) {
//#CASE 1: User is already logged in
$this->redirect(array("site/upload"));
}
else{
//#CASE 2: User is not Logged in
echo '<br>shows up with empty session<br>';
var_dump($_SESSION);
var_dump(Yii::getVersion());
exit;
$this->redirect(array("site/login"));
}
}
here $_SESSION is empty..
any explanation why this might be happening..
i am aware of CAS creating its own session by service ticket name.. i have handled that thing.. by RenameSession function, which i call in CasLoginForm..
whose code is this..
public function rename_session($newSessionId) {
//Store current session variables so that can be used later
$old_session = $_SESSION;
//Destroy current session
session_destroy();
// set up a new session, of name based on the ticket
$session_id = preg_replace('/[^a-zA-Z0-9\-]/', '', $newSessionId);
//start session with session ID as 1) service ticket in case of CAS login, 2) random sTring in case of local login.
session_id($session_id);
session_start();
//echo "<br>new session <br>";
//Restore old session variables
$_SESSION = $old_session;
//var_dump($_SESSION);
}
OK, i think that you should use session_id to change the id.
public function rename_session($newSessionId) {
// set up a new session id, of name based on the ticket
session_id(preg_replace('/[^a-zA-Z0-9\-]/', '', $newSessionId));
}
I'm writing a simple web site php/jquery/mysql etc. Currently I've a pretty simple login system where once the user logs in a session variable is set that is referenced to confirm if they're still logged in on other pages. Code is:
$_SESSION['logged_in'] = TRUE;
$_SESSION['member_id'] = $member_id_for_session;
$_SESSION['handle'] = $user_handle;
I have a variety of functions in util files that make use of this such as:
function echoUserHandle() {
if (isset($_SESSION['handle'])) {
echo "Welcome " . $_SESSION['handle'];
} else {
echo "You are not logged in";
}
}
and
function checkLoggedIn() {
if (isset($_SESSION['logged_in'])) {
return TRUE;
} else {
return FALSE;
}
}
this works fine on my MAMP server on my mac using chrome however when I push it out to my remote server I get inconsistent views of the data even on the same browser I use to dev on. I see this only by the fact that some pages show the status "You are not logged in" whilst some display the correct user id.
Also once a user is logged out the session is destroyed fully using:
unset($_SESSION['logged_in']);
unset($_SESSION['member_id']);
unset($_SESSION['handle']);
$_SESSION = array();
if (ini_get("session.use_cookies")) {
error_log("unsetting cookie:" . session_name(), 0);
$params = session_get_cookie_params();
error_log("cookie params:" . $params, 0);
setcookie(session_name(), '', time() - 42000, $params["path"], $params["domain"], $params["secure"], $params["httponly"]);
}
session_destroy();
this might be overkill but, when I log back in as a different user on some pages it still displays the previous logged in user. This suggests something wrong with the session doesn't it?
Can anyone suggest an approach to debug this, I've done a lot of dev in other fields but php is still new to me.
Many thanks