I have the following structure:
Index.php
Account.php
Login.php
CheckLogin.php
When someone logs in via login.php it checks the username and password and sets the following session variables
$_SESSION['username'] = $username;
$_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']);
When they access Account.php
that includes the file CheckLogin.php which checks the HTTP_USER_AGENT and also if the username variable is set.
Now here's where I have the problem. If a user went back to index.php (home page) and is logged in I would like to display the account link.
However if the user is not logged in i.e. just visited the site I would like to show the sign up link.
I was thinking I could do the following:
<?php session_start()
if (!isset($_SESSION['username'])) {
// If username is not set destroy the session
session_destroy();
echo ("Sign up");
}
else {
// If username is set
echo ("Sign up");
}
?>
I know this is not fully secure however if someone managed to hijack the session and went to account.php it would do the check which should destroy the session and log them out if they are not legit.
Is this best practice or is there a better way to achieve this desired result. I can't help thinking everyone just visiting the site and creating and destroying sessions is a bad idea. Is it the right thing to do or is there anything else I need to take into consideration?
This is enough for checking. No need to destroy the session on every attempt.
<?php session_start()
if (isset($_SESSION['username'])) {
echo ("Sign up");
}
else {
// If username is not set
echo ("Sign up");
}
?>
If someone is able to hijack the session, he will also be able to access your account.php. As stated above, read a good tutorial on auth systems or use a plugin. Building an authentication without proper knowledge is a bit dangerous.
if your checking is only based on session sure your website will not be secured. and I have a couple of suggestions:
1- use CSRF for more security on every post you have.
2- session should be always encrypted and you should use a salt key with them.
this way you can secure more. and just for information sessions is not always the best way to secure your website.
Related
Found a major problem on my website. I found tha if I login with user A. it sometimes kinda does log in but actually doesn't. Then I login with user B -> enter the site. I log out and then go manually back to url where login is needed and it somehow goes in with user A. It seems that I have two (maybe could have more) session_id cookies on different tabs or there is a ghost session_id that comes active I don't know. Pulling my hairs here.
Also found that, lets say I have a user dashboard and test page. With a little going back and forth with different credentials. I get this result:
Dashboard echoes user A's id, test echoes user B's id or not id at all. What the heck I am doing wrong with my sessions?
Login is done with AJAX. Login validation is the same on every page.
COMMON FUNCTIONS:
function validateUser($userid) {
session_regenerate_id();
$_SESSION['valid'] = 1;
$_SESSION['usersid'] = $userid;
}
function isLoggedIn() {
if (isset($_SESSION['valid']) && $_SESSION['valid'] == 1) {
return true;
} else {
return false;
}
}
function logout() {
$_SESSION = array();
session_unset();
session_destroy();
}
LOGIN/DB:
Login page:
session_start();
include 'include_files.php';
if(isLoggedIn()){
header('Location:loginrequiredpage.php');
die();
}
Login page sends username/password with AJAX to an controller php file that uses db functions as included file. It executes usercheckfunc() which checks user from db and then echoes succes or fail back to ajax.
from db functions - part of user check function
//if user found from db and password hash match
validateUser(**ID FROM DATABASE**);
Back in login page if ajax gets success message back, JS send user to login required url.
Here's where mystery sometimes occur The browser acts like if i just logged in somewhere, but the login page is loaded again. Sometimes I can manually go to login required page via address bar. Sometimes if I logout/idle too long etc. and login with different username/password I get in as a wrong user. Entered as user A, See user B's data OR echo different userids on pages or echo id only on other page.
LOGIN REQUIRED PAGE:
<?php
session_start();
require_once 'include_files.php';
if (!isLoggedIn()) {
logout();
header('Location:login.php');
die();
}
echo $_SESSION['usersid'];
Test page:
<?php
session_start();
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once 'include_files.php';
if (!isLoggedIn()) {
logout();
header('Location:login.php');
die();
}
echo $_SESSION['usersid'];
Is there a "best" way to manage sessions? Help is much appreciated :)
Got rid of the problem by manually setting session cookie parameters everywhere before session_start is executed. Now the session cookie domain doesn't behave unexpectedly. Sorry, no idea why it did that mysterious changeing before.
This cookie parameters sets it to be valid on whole domain. I guess it's no good in situation where you need different sessions on the same domain (different applications etc.). But for me it was the healing patch I needed.
session_set_cookie_params(0, '/', '.example.com');
session_start();
I used this to hide links until after the user is logged in, and was just wondering if this will cause any security issues or other issues in production code? I have been testing it and cannot find an issue so far as the website will not give a session_id until after the user logs on.
if(session_id()){echo ' EWO '...
There is no problem in this code until you put a session check also in the file
if session id is not set then send them back to home page.. Because if user knows the URL then they can navigate to the link
Make sure to add a function which will redirect the users to the login page as soon as the session gets destroyed i.e logout.
Also, as mentioned by #Saeed Ansari, add some logic to your project so only the login page is rendered when there is no active session or the user is not logged in.
HTH.
Either way, if your solution is to simply 'hide this link' until the user has logged in, this is not constructive code.
You should have a user object or user $_SESSION identifier registered in the session for when the user logs on.
For example. User logs on, you set a flag $_SESSION['Username'] = "Bob", where Bob is the user's username.
Then in your code, you could do something along the lines of:
if(array_key_exists('Username', $_SESSION)) { echo ' EWO '; }
Then when a user logs into your site successfully, register their username (atleast) in the $_SESSION, ie
$_SESSION['Username'] = 'Bob';
It is a good idea to have full control over your session by using session variables, rather than just relying on if a session has an ID.
It is never safe to assume, so I would also recommend (if you haven't done so) checking in the ewo.php file for the same thing ... check if the session has a registered Username/etc and if not redirect header('Location: /'); for example, to redirect the user back to the home page.
You could do it via a Session.
If you wanna check if the variable is set (User is logged in) in the session use:
<?php
session_start();
if (isset($_SESSION['username'])) {
echo "Your link here";
} else {
echo "login first";
}
?>
I have a web app I am developing for a school project, I am having issues with the logout page. When a user clicks logout it will send them to a logout.php which just looks like this:
<?php include ("includes/check_authorization.php");
// Unset the session and destroy it
session_unset();
session_destroy();
// Redirect to the home page
echo '<META HTTP-EQUIV="Refresh" Content="0; URL=index.php">';
exit;
?>
It is very simple, but it will unset, then destroy the session, and redirect to the index, which is the login page. However when this is run the index immedietley redirects to a user homepage. The check_authorization page included at the top will redirect someone to login if the username and id are not set and matching in the $_SESSION, so this means that it is setting these for me? I am really confused as to how this is happening. I am using CAS for authentication.
EDIT: the check_authorization.php also initializes the session as well as checking those key values
For like this situation I did as follows, this is working for me all the browsers,
#session_unset();
$old_sessid = #session_id();
#session_regenerate_id();
$new_sessid = session_id();
#session_id($old_sessid);
#session_destroy();
Rather than just unsetting the data, try assigning a dummy value to the session, like:
$_SESSION['authKey'] = '!!INVALID!!';
session_unset();
session_destroy();
Even if the session 'revives', the authentication can't possibly succeed anymore because of the "fake" data.
There are some possibilities :
The most simple possibility : did you include the
session_start();
on top the file? before you include a file? I've been there before, and it pissed me off.
The second possibility : try to put
session_regenerate_id();
on the very top of your file (before you declare session_start();). Because in some Server Hosting, their configuration still using "LINUX" style that i can't explain to you here. But, the point is they always using "cache" when you redirect. In other words, you always redirect into your "cached" page when you rediret to another page. See.. it's hard to explain for you here. But just try the session_regenerate_id(); code, maybe it would work.
I never use the "echo" things in doing redirect things. Try :
header("location:index.php");
i don't know if this working or not. I just simply giving you my analysis based of my assumptions.
Hope these helpful. :)
After I authenticate user login info, i create this session for them:
$_SESSION['username']= $userName;
Then, I redirect them like this:
header('Location:www.domain.com/profile/' . $_SESSION['username'];
I want my website to have a beauty URL, something like: www.domain.com/profile/userName
Thus, in all my redirect links (HTML <a> tag or PHP header() function), I will use:
"www.domain.com/album/" . $_SESSION['username'];
Are there any security loopholes?
Edit:
Do I need to create session id first using session_id()?
So, to check:
if(!isset($_SESSION['id']){
//redirect to login page
}
Normally while using Sessions we also need to be aware of -:
Session Hijacking , Session Fixation
I suggest in your code after user logged in store the username in session variable also store one more unique value such as USER AGENT in a session variable. so that every page the user visit we can check for whether the same USER AGENT and SESSION ID exist this would make it much secure. To make it much more secure do the encryption like MD% on User AGENT so that hackers cant reproduce it.
Quoted from PHP SECURITY GUIDE
<?php
session_start();
if (isset($_SESSION['HTTP_USER_AGENT']))
{
if ($_SESSION['HTTP_USER_AGENT'] != md5($_SERVER['HTTP_USER_AGENT']))
{
/* Prompt for password */
exit;
}
}
else
{
$_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']);
}
?>
Refer :
PHP Security Guide on Session
Another Thread on Session security
What are you protecting? What are you doing to verify that they have authorization? Are you protecting their profile and verifying that they have authorization because they have the session key? You don't ever mention checking that they have a session variable.
You won't even need to know the session ID. That is immaterial to storing whether the user has gotten authentication, that's just the mechanism which indicates what session information they should be using.
When the user logs in, you want to store something like
$_SESSION['authed_user'] = true;
And then, on subsequent attempts to edit information you do:
if ($_SESSION['authed_user']) {
// do something authed users can do
}
And naturally, you'll really probably want some sort of levels of authorization. I recommend you consider using something like SimpleAuth...
You need authorization on the page that allows user to edit their profile. If they'll be editing on the http://www.domain.com/profile/[username] page then you need to check if their $_SESSION['username'] is equal to the profile page they are on.
Otherwise anyone would be able to type in the URL (basically guess a profile number or name) and edit it.
But yes, you should first check if they've logged in AT ALL:
if (IsSet($_SESSION['username'])) {
// Logged in
} else {
// Not logged in
}
How can I prevent a user from accessing a page when they are not logged in? I want him to be redirected to the login page. I know it has something to do with sessions.
It works like this:
Start a session: session_start()
If Session["user"] == null, redirect to the login page, else continue.
In the login page, ask the user for password using a form
Post this form to the login page
Check against your authentication service (e.g. a table in mysql) if the user is authorized
If yes, Session["user"] = $userName, redirect the user to the page. If no, prompt for password again
Of course, this is all very, very simple. In your session, you could keep a complex user object, or anything. Good luck coding.
As Svetlozar Angelov pointed out the following code would work well:
if (!isset($_SESSION['nID']))
header("Location: login.php");
However.. this would not actually secure the page against users who really wanted access. You need to make some adjustments:
if (!isset($_SESSION['nID']))
{
header("Location: login.php");
die();
}
This prevents bots and savy users who know how to ignore browser headers from getting into the page and causing problems. It also allows the page to stop executing the rest of the page and to save resources.
Its also noteworthy that $_SESSION['nID'] can be swapped out for any other variable you are using to store usernames or id's.
When he logs - store a session variable. Then in the beginning of every page
session_start();
if (!isset($_SESSION['nID']))
header("Location: login.php");
If the login is ok
session_start();
$_SESSION['nID'] = 1; //example
Follow these steps:
Create a login.php page accessible to everybody where a user enters her username and password in a form. This form must be submitted to login.php itself. (action='login.php'). Also include a hidden variable in your form which tracks if the form has been submitted.
If the hidden variable is set, check if the username ($_POST['user']) exists in your DB, and that the password matches the username. If it does, store the username in a $_SESSION variable like this:
$_SESSION['username'] = $_POST['user'];
If it does not, reload login.php like this:
echo 'header("login.php")'; //You should not have echoed anything before this
Now include login.php in every user page you create. Suppose you were writing an email application, create an inbox.php like this
include ("login.php")
Now, login.php will check if the session variable 'user' is set and allow access to authorised users only.