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);
}
}
Related
I am learning php.
I have a class and a function to start a custom session like the following,
Now how can I use the said custom session_start in every php page?
please help.
my code is like
<?php
// myclass.php
class abcd{
function sec_session_start() {
$session_name = 'sec_session_id'; // I have Set a custom session name
$secure = false;
$httponly = true;
if (ini_set('session.use_only_cookies', 1) === FALSE) {
$err='Could not initiate a safe session (ini_set)';
$err = Encryption::encode($err);
header("Location: ../login.php?error_msg=".$err);
exit();
}
// Gets current cookies params.
$cookieParams = session_get_cookie_params();
session_set_cookie_params($cookieParams["lifetime"],
//session_set_cookie_params(time()+3600,
$cookieParams["path"],
$cookieParams["domain"],
$secure,
$httponly);
// Sets the session name to the one set above.
session_name($session_name);
session_start();
session_regenerate_id(true);
}
}
?>
In this case the following error is showing :
Notice: A session had already been started - ignoring session_start()
myphp page is below -
<?php
// mypage.php
include_once "myclass.php";
$mevalue = new abcd;
$mevalue->sec_session_start();
code code code
?>
Please help me to solve this.
A session should last throughout the page visit and not be renewed on each page,
e.g. a user logs in once and this is stored into a session so the user doesn't need to login again for each new page or click.
Mostly a session starts if someone visits your page and remains until the user leaves the page -> closing the session.
The best way is to check if a session is open for this user and only start a session if the user doesn't have one.
To close a session one can use
session_write_close ( void ) : bool
Source
With this you can update your code to have a get_session function. In this function you can check if a session exists and use that one, if not start a new one
class abcd{
function init_session()
{
if (!isset($_SESSION)) {
$this->sec_session_start();
}
}
function sec_session_start() {....
And in your page
$mevalue->init_session();
Hi I am creating secure login functionality for my site. I have a function called sessionTimeOut() which i call at the top of each page of my site. As you can see within the function, if the user has been inactive for more than 30 mintues, I call a logOut() function and also a secure_session_start() function before redirecting the user back to the login page. I'm wondering will these functions execute fully before the redirect occurs? I'm not sure of the best way to debug the code. any help would be appreciated thanks.
function sessionTimeOut(){
//We implement a session timeout of our own. We use a simple time stamp that denotes the time of the last activity (i.e. request)
//and update it with every request
if(isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 1800)) {
//last request was more than 30 minutes ago
logOut();
//start a new secure session so that we can create a new session variable.
secure_session_start();
//create a session variable to say that the login session has timed out after redirecting to the login page.
$_SESSION['loginTimedOut'] = true;
header('Location: login.php');
exit();
}
$_SESSION['LAST_ACTIVITY'] = time(); //update last activity time stamp
//Now we also use an additional time stamp to regenerate the session ID periodically to avoid attacks on sessions
if(!isset($_SESSION['CREATED'])) {
$_SESSION['CREATED'] = time();
}else if(time() - $_SESSION['CREATED'] > 1800) {
//session started more than 30 minutes ago
session_regenerate_id(true); //change session ID for the current session and invalidate old session ID
$_SESSION['CREATED'] = time(); //update creation time
}
}
logout() function:
function logOut(){
//Unset all session values
$_SESSION = array();
//get session parameters
$params = session_get_cookie_params();
// Delete the actual cookie.
setcookie(session_name(),
'', time() - 42000,
$params["path"],
$params["domain"],
$params["secure"],
$params["httponly"]);
// Destroy session
session_destroy();
}
function secure_session_start() {
/* This is a function to start a PHP session in a secure way.
* This function stops crackers accessing the session id cookie through JavaScript (for example in an XSS attack).
* Also the session_regenerate_id() function, which regenerates the session id on every page reload, helps prevent session hijacking
*/
$session_name = 'secure_session_id'; // Set a custom session name
$secure = false; //set to true if https
//This stops JavaScript being able to access the session id.
$httponly = true;
//Forces sessions to only use cookies.
if(ini_set('session.use_only_cookies', 1) === FALSE) {
header("Location: ../error.php?err=Could not initiate a safe session (ini_set)");
exit();
}
//Gets current cookies params.
$cookieParams = session_get_cookie_params();
session_set_cookie_params($cookieParams["lifetime"],
$cookieParams["path"],
$cookieParams["domain"],
$secure,
$httponly);
//Sets the session name to the one set above.
session_name($session_name);
session_start(); //Start the PHP session
session_regenerate_id(true); //regenerate the session, delete the old one to prevent session fixation attacks.
}
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
I created a relatively small php/mysql based website and hosted it on a server running Red Hat 6.4, Apache/2.2.15. In order to access the site, the users are required to authenticate.
Now comes the weird problem. When I start the server, the site initially runs fine, but after about 12-24 hours, the php sessions stop working. When users try to login, their credentials a successfully retrieved from the database and the login script sets up the session variables, but when they are redirected to the home page - the session variables are lost so the home page thinks they aren't logged in and they are redirected back to the login page. The site is not heavily used, there are about 50 registered users and there are under 100 logins daily. Also, the site requires an invitation code to register, so the probability for bots to be on the site is very small.
Below are the PHP functions used to start a session, to log the users in and to check if they are authenticated (the code was inspired from http://www.wikihow.com/Create-a-Secure-Login-Script-in-PHP-and-MySQL):
function SecSessionStart() {
$session_name = 'sec_session_id'; // Set a custom session name
$secure = false;//https is not enforced
// This stops JavaScript being able to access the session id.
$httponly = true;
// Forces sessions to only use cookies.
if (ini_set('session.use_only_cookies', 1) === FALSE) {
header("Location: ../error.php?err=Could not initiate a safe session (ini_set)");
exit();
}
// Gets current cookies params.
$cookieParams = session_get_cookie_params();
session_set_cookie_params($cookieParams["lifetime"],
$cookieParams["path"],
$cookieParams["domain"],
$secure,
$httponly);
// Sets the session name to the one set above.
session_name($session_name);
session_start(); // Start the PHP session
session_regenerate_id(); // regenerated the session, delete the old one.
}
function Login($username, $password) {
$username=trim($username);
if (CheckUserCredentials($username, $password))
{
$userId=GetUserIdByUsername($username);
$hashedPass=hash("sha512",$password);
$user_browser = $_SERVER['HTTP_USER_AGENT'];
$_SESSION['user_id'] = $userId;
// XSS protection as we might print this value
$username = strtolower($username);
$_SESSION['username'] = $username;
$_SESSION['login_string'] = hash('sha512', $hashedPass.$user_browser);
// Login successful.
session_write_close();
return true;
}
else {
session_write_close();
return false;
}
}
function LoginCheck() {
// Check if all session variables are set
if (isset($_SESSION['user_id'], $_SESSION['username'], $_SESSION['login_string']))
{
$user_id = $_SESSION['user_id'];
$login_string = $_SESSION['login_string'];
$username = $_SESSION['username'];
// Get the user-agent string of the user.
$user_browser = $_SERVER['HTTP_USER_AGENT'];
$hash=GetPasswordHashByUserId($user_id);
if ($hash==null)
{
session_destroy();
session_write_close();
return false;
}
$login_check = hash('sha512', $hash.$user_browser);
if ($login_check == $login_string) {
// Logged In
session_write_close();
return true;
} else {
// Not logged in
session_destroy();
session_write_close();
return false;
}
}
session_destroy();
session_write_close();
return false;
}
In order to test my assumption that the problem was related to the sessions, I made the following php page and I've set up monitoring on it once every 5 minutes on an uptime checker:
<?php
require_once("include/authentication.php");
SecSessionStart();
$_SESSION['sessionCheck'] = "The cookie was successfully saved and retrieved";
session_write_close();
$_SESSION['sessionCheck']="";
SecSessionStart();
if (isset($_SESSION['sessionCheck']))
{
echo($_SESSION['sessionCheck']);
}
session_destroy();
session_write_close();
?>
Just as I suspected, the page returned the right answer for about 20 hours then I got an alert that the page was not displaying the success string. After I got the alert the login part on the site didn't work, either. I've tried to restart the httpd process to bring back to life the sessions, but this did not help. Only after a complete server restart things got back to normal.
I have tried searching on SO and other sites for my problem and I found some questions that were somehow related, but they did not entirely fit my situation. The main difference between my problem and other similar ones its that the site works perfectly fine in the beginning, but after some time the sessions fail all of the time. Other posters had problems where they lost sessions from time to time or the sessions did not work at all.
Any hint on the possible source of this problem would be kindly appreciated. If you need any further information from me that could help, please let me know.
Thank you
I have a PHP website with signup/login system. For security reasons, I want that the users are only able to sign in from one PC at a time. If same ID/Password tries to sign in from another PC while a user is already logged in with that ID/Password, it should generate an error message.
Please tell me how it is possible and what is the best way to do it?
I am using only cookies...
<?php function sec_session_start() {
$session_name = 'sec_session_id'; // Set a custom session name
$secure = false; // Set to true if using https.
$httponly = true; // This stops javascript being able to access the session id.
ini_set('session.use_only_cookies', 1); // Forces sessions to only use cookies.
$cookieParams = session_get_cookie_params(); // Gets current cookies params.
session_set_cookie_params($cookieParams["lifetime"], $cookieParams["path"], $cookieParams["domain"], $secure, $httponly);
session_name($session_name); // Sets the session name to the one set above.
session_start(); // Start the php session
session_regenerate_id(true); // regenerated the session, delete the old one.
}
Here is the code:
if(login($name, $password, $mysqli) == true) {
// Login success
if($name == 'admin'){
if($signin == 'zero'){
$stmt = $mysqli->prepare("UPDATE users SET signin = 'one' WHERE name = 'admin'");
$stmt->execute();
?>
<span class="TextFont"><br /><br />Welcome Admin! Click here to access your Admin Panel! <br /><br /> Logout</span>
<?php }
else{
echo"You are already logged in from some other system! $signin";
}}
else{
// some PHP code
}
else{
// some PHP code
}
if you also add a column session_id in the user table and you store sessions in a database (even more secure) You also could check more easier if user sessions are expired to update the signin column to 0 again and this is more waterproof against users that don't use a signout feature... (upgraded jycr753 solution)
What has worked for me in the past is this.
Add a column to your user table to store the session id.
When a user authenticates update the user record with the session for login.
When you are checking to see if a request is authenticated or not search the database for the user's session id.
Note with session_regenerate_id occuring on each page you will have to update the user record with each request, an alternative would be to store a unique value within the session and have that updated on the user record and confirm an authenticated request by matching values of that.
In pseudo-code
session_start();
session_regenerate_id();
if ($_SESSION["session_key"]);
$user = UserStore::getUserBySessionKey($_SESSION["session_key"]);
if ($user){
// the request is authenticated
} else {
// redirect to the login page
}
And on Login
session_start();
session_regenerate_id();
$user = UserStore::authenticateUser($username, $password);
if ($user){
$sessionKey = uniqid().$user->username;
$user->setSessionkey($sessionKey);
$user->save();
$_SESSION["session_key"] = $sessionKey;
} else {
// show the login form with an error
}