Are there any session security loopholes in my PHP script? - php

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
}

Related

PHP is $_SESSION enough to secure the web page?

I am running a simple service where users have to login to be able to operate special functonalities.
My MySQL database stores the username, password and user_id.
When user wants to login, they must provide their username and password which are posted to profile.php.
The profile.php does a simple check:
// Sanity Check
if(empty($_POST['smart_email'])|| empty($_POST['smart_password']))
{
echo 'Sorry, wrong login/passwd';
exit;
}
else
{
//
$smart_email = $_POST['smart_email'];
$smart_password=$_POST['smart_password'];
// Check if registerd and password matches
if(DB_IsAuthorized($smart_email, $smart_password) == true)
{
// Obtain proper UserID from the database
$UserID = DB_GetId($smart_email);
// set the session user_id variable
$_SESSION['user_id'] = $UserID;
//
// Display the User profile page
//
}
}
From that moment, every single page that is user-related has a check for user_id set in $_SESSION to find out if this user was logged in and is authorized.
if (isset($_SESSION['user_id']) && is_numeric($_SESSION['user_id']) && $_SESSION['user_id']>0)
{
// USER IS LOGGED IN
}
The question is: Is this $_SESSION['user_id'] check enough to secure the pages from NON LOGGED IN USERS ?
This question is too broad but simple answer is no.
Firstly, you will need https to make sure you protect users from hackers by using firewalls and other required security tools.
Secondly, you need to use htaccess to change extensions, say show user .html instead of .php
Thirdly, Sessions can be hijacked easy by hackers. So always try to store encrypted session values instead of plain text.
There are a lot more issues to take care of but its too complex and broad.

Is php session unchangeable from user end? [duplicate]

This question already has answers here:
Can a user modify a PHP session?
(3 answers)
Closed 7 years ago.
I am developing my own application which requires user login. All users and passwords (encrypted) are stored in a database. When a user tries to login, then it search in the database the username and password. If all is ok, then I store username in $_SESSION["username"], user role (admin, author etc) in $_SESSION["role"] and user website in $_SESSION["website"] (I need website to be stored because the application is like "multisite" - my applicaton is hosted on client hosting but the administration is on my server).
I read this Can a user alter the value of $_SESSION in PHP? and I don't understand. Is this method secure (of storing data and if user is logged in) in a $_SESSION?
Can the user change the session content? (for example, if user is logged in and $_SESSION["website"] is "example.com", can the user change the session $_SESSION["website"] to "example.org" to ruin another website? If yes, how to avoid or what's the secure alternative of session?).
And please tell me what is session hijacking and how can this affect my site and also, how to make session_id dinamically to change?
Thank you so much!
$_SESSION is saved in the server, so the user cannot modify it ( Except the case of session hijacking)
Session() is server side as #kd0807 noted. For more info on Session Hijacking && Fixation:
http://phpsec.org/projects/guide/4.html
http://php.net/manual/en/session.security.php
Side note...
With the amount of variables I recommend an array for session['user'].
example....
$_SESSION['user'] => Array(
'userid'=> '123',
'username'=> 'some_joe',
'role' => 'customer', // user, customer, admin, moderator etc.
'website' => 'http://www.example.com'
);
// reading variables from array
$userid = $_SESSION['user']['userid'];
$username = $_SESSION['user']['username'];
// etc. etc.
Here are 3 very simplified functions I use.
// determine if session has started
Function HasSessionStarted() {
$result = false; // default to false
// Check if session has started
IF ((session_status() == PHP_SESSION_NONE) || (session_id() == '')) {
$result = true;
}
return $result;
}
// Set a session value
Function Set_Session($name, $value) {
/* #params value: can be a string or an array */
$new_session = HasSessionStarted(); // Check Session Status
IF ((isset($name)) && (isset($value))) {
IF ($new_session) { session_start(); }
$_SESSION[$name] = $value;
IF ($new_session) { session_write_close(); }
}
}
Function Unset_Session($name) {
$new_session = HasSessionStarted(); // Check Session Status
IF (isset($_SESSION[$name])) {
IF ($new_session) { session_start(); }
unset($_SESSION[$name]);
IF ($new_session) { session_write_close(); }
}
}
There is a cookie stored in the browser usually PHPSESSID which identifies which server session the user is using. If a user were able to steal it (this usually happens through XSS vulnerabilities) the user could potentially take control of another users session.
The session data itself is stored on the server and could only be modified if a user were somehow able to upload and execute a malicious script in the server
No, Until and unless the php code itself reveals the PHP session, which can be used to session stealing, and the session could not be changed from the user end until and unless the there is some functionality given by you yourself to change the session from the front end.
`$_SESSION` variables are stored in the server and hence cannot be modified by the user.
One of the best practices is that we must keep changing the session id from our end.
Thats why we use a function called session_regenerate_id().
This function that will replace the current session ID with a new one, and keep the current session information, so the use will not be logged out.
To answer your question in comment:
Whenever you start a session, server will send back a cookie which will contain the session id, the cookie name will be PHPSESSID which is the default name. You can also choose to change it. So this id is what that keeps changing when you use the session_regenerate_id function.
REASON WHY TO USE IT:
This mainly helps in preventing session fixation attacks.In this attack a malicious user will try to fix the session ID (SID) of another user. If he gets successful,the user will get all the access of the original user and will be able to do anything that the legitimate user can do.
So if you regenerate the session id the previous old session id will be no longer valid
You can get more info about session fixation IN OWASP WEBSITE
Can the user change the session content? (for example, if user is logged in and $_SESSION["username"] is "example.com", can the user change the session $_SESSION["username"] to "example.org" to ruin another website?
No. Sessions are stored on your server thus it would be impossible to directly change the session. On the other side, it all depends on the developer and how the interprets the client requests. For example, making
$_SESSION['last_website'] = isset($_SERVER['HTTP_REFERER'])
? $_SERVER['HTTP_REFERER']
: $_SERVER['REQUEST_URI'];
would eventually override the $_SESSION['last_website'].
Yes user cannot change session Variables...
if it hacked it can changed...
you need to get user id to change the $_SESSION["website"] in your current domain and use strict validation...
Otherwise they can hack it....

PHP method to hide link until user logged in

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";
}
?>

PHP session managment, is this ok to do?

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.

Check whether user is logged in or not

I am doing a web-application using PHP for job searching.
I have one query; when user is not logged in and wants to apply for the job given by clicking 'apply' button, he redirects to the login page. If the user is logged in when clicking, he should get directly to the application page. I'm not sure how to implement this.
I'm confused because I'm new to PHP.
Your question is very vague - maybe start with Authentication in PHP
Well, when the user clicks on 'apply' in your application the user is redirected to the login page if he is not logged in(which you can check if user session exists or not), remember when you redirect the page send the url of the current page in parameters to your login page so that when the user logs in he can be redirected back to the previous page and click on apply for that particular job.....
This is how the logic works, if you want the php, mysql explanation it would take some time for you to understand as you yourself conceded you are new to php..
You could store a value in the Session called "Login" and set this when the user logs in. This can also be used to re-direct the user if they haven't been logged in:
<?php
// check that the session variable does exist
// check that the user 'LoggedIn' has been set to 1 (true)
if (!isset($_SESSION['LoggedIn']) && $_SESSION['LoggedIn'] != 1)
{
// redirect to login page for user to authenticate themselves.
// pass page location (with parameters if necessary) to redirect
// the user on successful login.
header("Location: Login.php?redir=ApplyForJob.php?JobID=12345");
}
else
{
// user is logged in
// redirect the user directly to the apply for job page.
header("Location: ApplyForJob.php?JobID=12345");
}
?>
Can you, when the user logs in, assigns a $_Session variable to that user? i.e., after authentication, you set the $_SESSION['user'] variable.
$_SESSION['user']='admin';
So if you want to check whether the user is already log in after that, just use this:
if(isset($_SESSION['user']))
{
// user is login, direct to the job page
}
else
{
// no login, go to the login page
}
On each page set a cookie or session to which page they were just on:
$expire=time()+60*60*24*30;
setcookie("wherewasi","",time() - 1000);
setcookie("wherewasi",$_SERVER['REQUEST_URI'], $expire);
Then after login redirect them:
$loc = ($_COOKIE['wherewasi'])?$_COOKIE['wherewasi']:'index.php';
header("location: ".$loc);
exit();
There are two things that you need to worry about... checking that they've logged in, and then once they've logged in, directing them to the correct page.
This is all about 'saving state' across page requests. To do this you need can use cookies or more usefully sessions (which may be done via cookies or handled by the PHP engine for you automatically).
Sessions are probably a good way to go. To use sessions, every page needs to start with a
<?php session_start(); ?>
at the very least, before any html code that writes to the browser.
Once that's done you can use your the session variable to store
<?php $_SESSION['user']='joe_blow'; ?>
(and check)
<?php
if(isset($_SESSION['user']) && $_SESSION['user']!='' {
// do something
}
?>
whether the user is logged in, and which page they need to be redirected to after login.
<?php header("location: ".$_SESSION['redirect_location']));
But in order to write the any more useful code I think people would need to know what authentication method you were using... (How are you doing your login? Are you storing ID's in a database? Are you using an off-the-shelf package?)

Categories