I'm going through the pain of upgrading PHP on my server from 5.2 to 5.3. Having migrated my old php.ini to the new and upgraded my mysql passwords, my PHP sessions no longer work.
This is my login code below, it executes correctly and even logs my login correctly in the activity log. (updatelog function) I have also posted my session valid check code.
Is there anything obvious in my login code that is no longer valid in PHP 5.3, having previously worked under 5.2?
// Login User///
if(#$_POST["dologin"] == 1)
{
//record login attempt
updatelog("",$_SERVER['REMOTE_ADDR'],"Login Attempt By: ".$_POST['username']);
$user_name = escape($_POST["username"]);
$password = escape(md5(SALT.$_POST["password"]));
$login = $query->GetSingleQuery("--SINGLE","SELECT user_name, id, user_email FROM url_users WHERE user_name='".$user_name."' and user_password='".$password."';",array("user_name","id","user_email"));
if(!isset($login['user_name'])) //failed login
{
$_SESSION['loggedin'] = 0;
//record failure
updatelog("",$_SERVER['REMOTE_ADDR'],"Login Failure By: ".$_POST['username']);
header("Location: index.php?failed=1&user=$user_name");
}else
{
//login valid
//get country details
$getcountry = $query->GetSingleQuery("--SINGLE","SELECT geo_ip.ctry FROM admin_adfly.geo_ip geo_ip WHERE INET_ATON ('".$_SERVER['REMOTE_ADDR']."') BETWEEN geo_ip.ipfrom AND geo_ip.ipto;",array("ctry"));
//set session items
$_SESSION['country'] = $getcountry['ctry'];
$_SESSION['username'] = $login['user_name'];
$_SESSION['userid'] = $login['id'];
$_SESSION['loggedin'] = 1;
$_SESSION['email'] = $login['user_email'];
//session salt
$hsh = md5($_SERVER['HTTP_USER_AGENT'].SALT);
$_SESSION['_XXX(*##!_D#R*&$%(){*#)_D_296']['user_agent'] = $hsh;
//update the ui transaction log
updatelog($login['id'],$_SERVER['REMOTE_ADDR'],"Login Success For: ".$_POST['username']);
// run function to check if any adverts have completed
adcomplete($_SESSION['userid']);
//redirect
header("Location: index.php");
}
}
// Check users login session is valid, this is called on each page I want to restrict by login. ////
if(isset($_SESSION['_XXX(*##!_D#R*&$%(){*#)_D_296']['user_agent']) == $_SERVER['HTTP_USER_AGENT'].SALT)
{
return 1; //session success
}else
{
return 0; //session failure
}
The check for login is not checking the hash of user agent and salt, should be :
if (isset($_SESSION['_XXX(*##!_D#R*&$%(){*#)_D_296']['user_agent']) == md5($_SERVER['HTTP_USER_AGENT'].SALT))
{
return 1; //session success
} else {
return 0; //session failure
}
Edit:
Since the problem persists and it seems to be a php configuration issue I would try to make the simplest php page that uses sessions and try it out in the 5.3 environment to confirm that it is a php configuration problem and use that simple page to test the configuration while trying to fix the issue.
A simple php page:
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
session_start();
if (isset($_SESSION['views']))
$_SESSION['views'] = $_SESSION['views'] + 1;
else
$_SESSION['views'] = 0;
echo '<pre>';
var_dump(session_id()); // I should stay the same
var_dump($_SESSION); // I should start at 0 and increase
echo '</pre>';
Simple solution:
Go to /var/lib/php and set attributes 777 to "session" directory.
EDIT:
Yes, I know it is not recommended solution, but it works. For do it right, you should set owner to php, httpd or nginx - I don't have time to check which it should be
After much messing about, it turns out that the problem was related to the last session name, it was somehow invalidating the entire browser session, removing all data from the session.
After removing "(*##!_D#R*&$%(){*#)_D_296" from the $_SESSION array, my login session started working again.
Related
I've just migrated my website from my local WAMP server to a live HTTPS server on 1and1. It works perfectly on the local server, but on the live server the session variables are being destroyed when I'm trying to log in. I know the database is working fine and all the queries are running successfully after some testing.
The problem is that the session variable is being created when I run the log in script, but once the page reloads and runs a 'session check', the variable no longer exists. Because of this the site just reloads the login form as the if condition is not being met.
Here is the code for both scripts. I don't know why this is happening as the entire website is being run through HTTPS so its not an issue with HTTP/HTTPS etc.
LOGIN SCRIPT
<?php
date_default_timezone_set("Europe/London");
require("db_connect.php");
if ($sql)
{
$email = $_POST['userEmail'];
$password = $_POST['userPassword'];
$checkDetails = mysqli_query($sql, "SELECT * FROM users WHERE email='$email'");
while ($details = mysqli_fetch_array($checkDetails))
{
$hashedPassword = $details['password'];
if(password_verify($password, $hashedPassword))
{
//Passwords Match
//Update last login time in the database
$now = date("Y-m-d H:i:s");
$lastLoginQuery = mysqli_query($sql, "UPDATE users SET lastLogin='$now' WHERE email='$email'");
if ($lastLoginQuery)
{
//Initialise session
session_start();
$_SESSION['user'] = $email;
header("Location: ../");
}
else
{
echo "There was an error logging you in. Please try again!";
}
}
else
{
echo "The details you entered are incorrect. Please return to the login page. If the problem persists, contact an administrator.";
}
}
}
else
{
echo "There was a problem connecting to the database";
}
?>
SESSION CHECKING SCRIPT
<?php
//Check if a session exists and load the page if it does
session_start();
if (isset($_SESSION['user']))
{
//Check if the session has timed out
if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 1800))
{
//Last user action performed more than 30 minutes ago. Log out now.
session_unset();
session_destroy();
header("Location:./");
}
//If the session hasnt timed out. Reset the last activity time.
$_SESSION['LAST_ACTIVITY'] = time();
//Continue to load content
include('./includes/main.php');
}
else
{
// Load login page
include('./includes/login_form.php');
}
?>
Session start must be the very first call in your script. https://www.w3schools.com/php/php_sessions.asp
<?php
session_start();
date_default_timezone_set("Europe/London");
require("db_connect.php");
etc...
Fixed the issue by adding an additional session_start(); directly at the beginning of the index.php file before any html. Seems strange that the login and session_check scripts wouldn't work without this as they also had session_start(); in them too.
I have a working Session management on my platform which I programmed in PHP.
For security reasons I want to regenerate the Session ID at least when a user logs in successfully and if possible with each request to prevent session fixation.
The login part looks like this if the login credentials are correct. If they are not correct or the user has not entered anything yet I do not start a session and as far as I know one old value for the session id is used
session_set_cookie_params(1800, "/", $domain, true, true);
session_start();
session_regenerate_id(true);
Each time I make another request to the server and it checks wether my session is valid I call
session_regenerate_id(true);
I check for a valid session with this code:
$domain = $_SERVER["HTTP_HOST"];
if(session_status() != PHP_SESSION_ACTIVE)
{
session_set_cookie_params(0, "/", $domain, true, true);
session_start();
}
//Check if session has expired
$now = time();
if(isset($_SESSION["discard_after"]) && $now > $_SESSION["discard_after"])
{
session_unset();
session_destroy();
header("Location: https://".$domain."/login.php");
die();
}
session_regenerate_id(true);
$_SESSION["discard_after"] = $now + 120;
if ((!isset($_SESSION["loggedin"]) || !$_SESSION["loggedin"]) &&
basename($_SERVER["PHP_SELF"]) != "login.php")
{
header("Location: https://".$domain."/login.php");
die();
}
I monitored this with Burp and confirmed, that the session id changes when I log in successfully. The session ID also changes when I navigate through the site without any problem and just the way I want to.
However this behaviour is not consitent. I have some user who enter the correct credentials (I know this because of the logs) but have no valid session and can not cross the login page to the home page.
I also have the strange case that one has to log in twice (both times correct credentials) befor a valid session is set. This happens to me unpredictable as well as to other users. I could not see yet when this happens and when not, only that the login should have worked.
Some information about the setup. I have a Ubuntu 14.04 vServer with Apache2 and PHP 5.X. On the client side I use the latest version of Firefox and Chrome on Windows 7 64x. One user who can not login at all even though the credentials are correct and the code above is definitly executed is using Chrome on Windows 7 64x as well (I have no more information regarding this).
I know for sure that the problem is the session_regenerate_id(true); function because if I comment this line out everything works fine but this solution is not satisfactory to me. I also tried a PC from which I certainly never entered the website befor and there everything also works.
I can not see what causes this and the PHP man page did not really help me there. Especially the not determinstic behaviour confuses me.
I might not answer until tomorrow but I will value all useful answers and comments.
EDIT
This is the entire login sequence without unneccessary stuff that is not executed in my scenario or definitly unimportant. I never output anything befor.
if($_SERVER["REQUEST_METHOD"] == "POST" && isset($_POST["inputEmail"],
$_POST["inputPassword"]) && $_POST["inputEmail"] !== "" &&
$_POST["inputPassword"] !== "")
{
$domain = $_SERVER["HTTP_HOST"];
$passwordHash = hash("sha256", $_POST["inputPassword"]."somesecretsalt");
//Own function which definitly works
$connection = connectToDB("standard");
//Get usernames and passwordhashes for checking
$query_getUser = "SELECT id, firstname, lastname, email,
passwordhash FROM user WHERE email = ?;";
if($stmt = mysqli_prepare($connection, $query_getUser))
{
mysqli_stmt_bind_param($stmt, "s", $_POST["inputEmail"]);
mysqli_stmt_execute($stmt);
$userRAW = mysqli_stmt_get_result($stmt);
mysqli_stmt_close($stmt);
}
if(mysqli_num_rows($userRAW) == 1)
{
//State: User exists
$dataset = mysqli_fetch_array($userRAW, MYSQLI_ASSOC);
$now = time();
//This is the crucial part which is definitly executed because the
// log entry in the following if clause is executed
session_set_cookie_params(1800, "/", $domain, true, true);
session_start();
session_regenerate_id(true);
if($dataset["passwordhash"] === $passwordHash)
{
//State: User exists, correct password
$_SESSION["loggedin"] = true;
$_SESSION["id"] = $dataset["id"];
$_SESSION["email"] = $dataset["email"];
$_SESSION["name"] = $dataset["firstname"]." ".$dataset["lastname"];
$comment = $_SESSION["name"]." (ID:".$dataset["id"].") has logged in";
writeToLog("Login success ", $comment, __LINE__);
if ($_SERVER["SERVER_PROTOCOL"] == "HTTP/1.1")
{
if(php_sapi_name() == "cgi")
{
header("Status: 303 See Other");
}
else
{
header("HTTP/1.1 303 See Other");
}
}
header("Location: https://".$domain."/index.php");
mysqli_close($connection);
die();
}
}
mysqli_close($connection);
}
Here is my login.php code snippet:
<?php
session_start();
include 'db_connection.php';
if (isset($_POST['login'])) {
$match_flag = false;
$username = $_POST["username"];
$password = $_POST["password"];
//$_SESSION['username'] = $username;
$query_select = "SELECT admin_username, admin_password FROM users_admin";
$query_result = $conn->query($query_select);
if($query_result){
foreach($query_result as $rows){
if(($rows['admin_username'] == $username)&&($rows['admin_password'] == $password)){
$_SESSION['username'] = $username;
echo "<br> Session ID -> ".SID;
$match_flag = true;
break;
}
}
}
if($match_flag){
echo "1";
}else{
echo "0";
}
exit();
}
?>
And here is my dashboard.php code:
<?php
session_start();
echo "Session is -> ".$_SESSION['username'];
echo "<br> Session ID -> ".SID;
if(!isset($_SESSION['username']))
{
echo '<META HTTP-EQUIV="Refresh" Content="0; URL=http://www.example/login.php">';
exit();
}
?>
After running login.php the session value is set and I get session ID and when I see session file, I found with fine content. But when the dashboard.php runs, I get another but different session id there with an empty session file. It means a new session is being created on running dashboard.php but this is totally unexpectedly. I have searched a lot but did not get satisfy-able answer. Please guide my why session is again started on a new page?
Thankyou in advance!
This is just an educated guess but maybe there is a problem with the way how you provide your session name and session ID. It is crucial that both of your scripts are aware of the same session ID.
There are several ways to do so.
Nowadays most PHP installations are configured to use cookies and only cookies. A few PHP versions ago session parameters were transferred through URL parameters. The way PHP handles these is configured in your php.ini.
You might find the section on session configuration in the PHP Manual helpful: http://php.net/manual/session.configuration.php
Make sure to check out the session.use_cookies and session.use_trans_sid directives. For security reasons I suggest you set everything to the default values. You may look into your current configuration through <?php phpinfo(); ?>.
I built a PHP/MySql login system for a website I am working on and all was working fine. I took a month off from working on it, pulled it up last night, and all of a sudden it doesn't work. It recognizes if a wrong username or password was entered, but if you enter the correct information it redirects you to the login page again. Was there some update somewhere that I am unaware of? I did not change anything in any of my files. It was working perfectly a month ago, and with no change at all it doesn't work now. Any ideas?
UPDATE
It is working if I check the remember me box, but not if I don't I will paste my code below:
Login Script:
<?php
define('INCLUDE_CHECK',true);
require 'connect.php';
require 'functions.php';
session_name('TheLoginSession');
session_start();
// ---------- LOGIN ----------
if($_POST['submit']=='Login')
{
// Checking whether the Login form has been submitted
$err = array();
// Will hold our errors
if(!$_POST['username'] || !$_POST['password'])
$err[] = 'All the fields must be filled in!';
if(!count($err))
{
$_POST['username'] = mysql_real_escape_string($_POST['username']);
$_POST['password'] = mysql_real_escape_string($_POST['password']);
$_POST['remembercheck'] = (int)$_POST['remembercheck'];
$storedsaltquery = mysql_fetch_assoc(mysql_query("SELECT rand FROM members WHERE usr = '".$_POST['username']."'"));
$storedsalt = $storedsaltquery['rand'];
// Escaping all input data
$row = mysql_fetch_assoc(mysql_query("SELECT id,compid,usr,firstName,level,yn FROM members WHERE usr='{$_POST['usernamelog']}' AND pass='".hash("sha256",$_POST['passwordlog'].$storedsalt)."'"));
if($row['id'])
{
// If everything is OK login
$_SESSION['usr']=$row['usr'];
$_SESSION['comp']=$row['compid'];
$_SESSION['id'] = $row['id'];
$_SESSION['name'] = $row['firstName'];
$_SESSION['usrlevel'] = $row['level'];
$_SESSION['new'] = $row['yn'];
$_SESSION['remembercheck'] = $_POST['remembercheck'];
// Store some data in the session
setcookie('Remember','remembercheck',time()+1209600,'/','.domain.com');
}
else $err[]='Wrong username and/or password!';
}
if($err)
$_SESSION['msg']['login-err'] = implode('<br />',$err);
// Save the error messages in the session
echo header("Location: ../index.php");
exit;
}
Index Page:
<?php
define('INCLUDE_CHECK',true);
require 'includes/connect.php';
require 'includes/functions.php';
// Those two files can be included only if INCLUDE_CHECK is defined
session_name('TheLoginSession');
// Starting the session
session_start();
if($_SESSION['id'] && !isset($_COOKIE['Remember']) && !$_SESSION['remembercheck'])
{
// If you are logged in, but you don't have the Remember cookie (browser restart)
// and you have not checked the remembercheck checkbox:
$_SESSION = array();
session_destroy();
// Destroy the session
}
if(isset($_GET['logoff']))
{
$_SESSION = array();
session_destroy();
header("Location: index.php");
exit;
}
if($_SESSION['id'] && $_SESSION['new'] != 1){
header("Location: home.php");
exit;
}
?>
How can there be an update if nothing's changed?
Are you using a CMS or framework?
If it's all your own code, and you haven't changed anything, then nothing would have updated.
I've had an issue like this before but without more information, hard to know if it is the same issue. Mine had the symptom you describe (login with bad creds and get the authentication error, login with good creds and redirect back to login).
Mine was due to failing to include code to remove old session cookies. The login attempt 'works' but an old cookie also read and attempts to authenticate, fails (because it is too old), and kicks the user back to login.
If this is your issue, clear your site cookies and see if you can then log in.
If that works, you'll want to add some cleanup code to your logout and stale session handling. For instance, for logging out:
// per http://www.php.net/manual/en/function.session-destroy.php
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000,
$params["path"], $params["domain"],
$params["secure"], $params["httponly"]
session_destroy();
Again, just guessing at your issue here.
I had this weird issue and I finally realized that it was due to a single session by which I determined whether the user's logged in or not. ($_SESSION['uID']) Everything was working alright until all of a sudden this very session was unavailable in ONLY ONE of my files! I mean it still worked on my localhost but not when I tried to reach it on my actual server.
If sessions are stored in some files, I suspect there might be an issue with the server and still if so, why the session is not available in ONE of my files only?
Edit: The problem is not session_start() as I already have it on my file(s). If I use another name for this session it works again.
Edit 2: This guy (Here: session wiped out between pages) seems to have the same issue but as you can see he could get no answer either. Anyone?
Edit 3: Here's a sample of both working and problematic files:
Session uID is available in this file:
<?php
session_start();
if (!empty($_SESSION['username'])) { // USER Active - SESSION Active
$userLoggedIn = "1"; // login flag
$uID = $_SESSION['uID']; // here it returns a valid value
dbconnect();
// and the rest (this file works ok)
}
?>
And it is not available in the following file
<?php
// Jan 2012
session_start();
if (!empty($_SESSION['username'])) { // SESSION Active
$userLoggedIn = "1"; // login flag
$pID = ""; // initiating
$uID = "";
$NewStat = "1";
$pID = $_POST['pID'];
$uID = $_SESSION['uID']; // This is were it returns null!
// on direct use die
if (!$pID || !$uID || $pID == "" || $uID == "") die("ERROR 33");
require_once ("./functions.php");
dbconnect();
// Getting info from db and stuff...
echo $starFile;
} else {
die("ERROR sd23");
}
?>
This will happen if you don't call session_start() in that file.