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.
Related
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 have got this strange problem. I wanted to make a page which uses a Username to identify which content should be displayed. It seems to work fine, except for one thing. The wrong value is read from the session on one specific page. I have checked the session value in my browser, but there the value seems to be correct. I'll show you the code:
this is my login function, using php:
<?php
//CONNECT TO DATABASE
$db = mysqli_connect("localhost","root","MyPassword","MyDBName");
if($db->connect_errno){
die('connection error: ' . $db->connect_errno);
}
//CHECK IF LOGIN DATA IS SUBMITTED AND IS CORRECT
if(isset($_POST['action'])){
switch($_POST['action']){
case "login":
$pw = $_POST['pw'];
$loginUn = $db->real_escape_string($_POST['loginUn']);
$result = mysqli_query($db,"SELECT `Password` FROM `accounts` WHERE `Username`='" .$loginUn. "'");
if(mysqli_num_rows($result) != 0){
$dbpw = $result->fetch_object();
$VI = explode("-",$dbpw->Password);
$dbpw = openssl_decrypt($VI[1],"blowfish","",0,$VI[0]);
if($pw == $dbpw){
$login = true;
$_SESSION['login'] = true;
$_SESSION['Username'] = $_POST['loginUn'];
$un = $_POST['loginUn'];
}
}
break;
case "logout":
$_SESSION['login'] = false;
$_SESSION['Username'] = "";
break;
}
}else{
if(isset($_SESSION['login'])){
$login = $_SESSION['login'];
$un = $_SESSION['Username'];
}
}
?>
it seems to work fine, since it works in the page it is used.
I have made some dummy accounts in the database, with these usernames: Admin and User.
Here is the code of the page it went wrong:
PHP:
//THIS IS NOT THE SAME PAGE AS THE PREVIOUS PHP CODE
$login = false; //CHECK IF USER HAS LOGGED IN
$un = "";
if(isset($_SESSION['login'])){
$login = $_SESSION['login']; //IF LOGGED IN SET TO SESSION VALUE
$un = $_SESSION['Username']; //SET $UN TO USERNAME IN SESSION
}
Then I used javascript and php to alert the values which the variables contain:
<script type="text/javascript">
alert("$un = <?php echo $un;?>");
</script>
With the login variable seemed to be no problem, since it had the good value, but the variable $un was wrong. When I wasn't logged in, it had no value, which is correct, but when I was logged in, it contained the value Admin, even when I wasn't logged in with Admin. In the browser options the cookie value seemed correct. I've checked the cookie on every page, and it worked just fine, just not on this page. What am I doing wrong that makes the browser(which is firefox by the way) think that it is always Admin that is logged in?
As mentioned earlier in the comments, there are many security risks in your script.
You should take a look at PHP's sessions to build your login. Using sessions, there will be only one cookie storing an ID and all the data will be stored on your server and can't be modified by the user.
Your problem with 'Admin' staying as cookie value could be a caching problem.
I just found out what I did wrong. A piece of code which I found irrelevant, missed a = so the variable wasn't compared, but set to this wrong value.
Hi I am trying to get the user signed in via sessions, here is my code it was working before now it isn't i didnt even change the code.
profile.php (to show after logged in)
<?php
ob_start();
session_start();
$userName = $_SESSION['username'];
$userid = $_SESSION['userid'];
if(isset($_GET['session'])) {
$currentSessionID = $_GET['session'];
$currentSessionID = md5(md5(md5($currentSessionID)));
session_id($currentSessionID);
header("Location:profile.php");
return;
}
if(!isset($userName)){
echo "OUT";
return;
}
...
scripts/signin.php
ob_start();
session_start();
include"config.php";
echo "here";
// check for required fields
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['Username']) && isset($_POST['Password'])) {
$user = mysql_real_escape_string($_POST['Username']);
$pass = mysql_real_escape_string($_POST['Password']);
$decrypt = md5(md5(md5($pass)));
$ensure = "select * from userinfo WHERE Username = '$user' and Password='$decrypt' and status='1'";
$result= mysql_query($ensure);
if(mysql_num_rows($result) > 0) {
echo "here2";
$entry = mysql_fetch_array($result) or die(mysql_error());
$_SESSION['username'] = $entry['Username'];
echo $entry['Username'];
$_SESSION['userid'] = $entry['Id'];
$currentSessionID = session_id();
$currentSessionID = md5(md5(md5($currentSessionID)));
header("Location: http://www.myprocity.com/profile.php?session=".$currentSessionID);
echo "here3";
the reason why im passing in the session id is because im trying to only keep sign in and sign up HTTPS while the other pages HTTP so I can show Google ads, does anyone know how to implement this without security issues (perfectly)
it always goes to OUT even when $_SESSION is my username (database is correct)
In profile.php you are checking for the presence of a session ID, and changing the session ID if you find it. You are doing this after you've set up a session with session_start(), but the PHP manual specifically says you must call session_id() before session_start() for this to work.
You're also hashing $_GET['session'] before sending it, and again before using it. The session ID you're trying to use in profile.php won't match the session ID used in signin.php
The result is that $_SESSION does not have the data in it you are expecting.
You need to rationalise your use of session_id(), and ensure the correct value is passed from page to page. All the hashing with md5() is just complicating matters - drop it. Realistically, I don't see why you need anything more than session_start() at the top of each page and let PHP handle the sessions. You may have an argument for doing what you're doing, but your solution simply won't work.
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.