How do I fix this security hole? - php

I have a website that currently works. It has a page that displays information, and another that lets you edit the information sources. Now when you login on index.php it posts the data to view.php through a form. The site doesn't use any cookies. When I click edit, it posts the username, passhash, and the submit request to edit.php. Currently, this button works well, but the current code for the edit button is as follows:
<FORM NAME ="form1" METHOD ="post" ACTION = "edit.php">
<p class="BodyText">
<INPUT TYPE = "Hidden" Name = "Username" Value = "<?php print($username); ?>">
<INPUT TYPE = "Hidden" Name = "PassHash" Value = "<?php print($password); ?>">
<INPUT TYPE = "Submit" Name = "Change" VALUE = "Edit">
</p>
</FORM>
I hadn't noticed before, but now I notice as I look through the code, that it prints the password. I don't really know how else to get the password to the edit page without this, but when I inspect the element in Chrome, I can see the password hash (SHA-1). Firstly, and I assume yes, is this a security hole? Secondly, how to I pass the passhash along to the edit.php page without sending the hash back to the end user. Thirdly, am I doing this wrong entirely? It seems OK to me to login through post, but is that security crazy? I'm kinda new at PHP, and new at security entirely.

This is not a good way to do this (hidden inputs in the form).
Learn about PHP Sessions.
Check out some of the examples from the PHP manual.
You'll want to preserve the user's access across their session between pages and you should never print out their passwords.
You can validate users' passwords to authenticate them, and have the session hold information on who the user is, and whether they are logged in for that session (rather than trying to validate passwords on every single page).
One example flow:
When authenticating (user logs in):
session_start();
// Authenticate user here with the password.
if (someAuthenticationFunction($_POST['user'], $_POST('password') === true) {
$_SESSION['user'] = $user;
$_SESSION['loggedIn'] = true; // Notice we're not saving the password into the session, only whether user is loggedIn.
}
On every other page where you would want to check user's authentication (most likely on edit.php page):
session_start();
if ($_SESSION['loggedIn'] === true) {
$user = $_SESSION['user'];
// Do the actual editing stuff here.
}
Once the user is ready to log out, use session_destroy() (most likely on a logout page).

u can save the password in the $_SESSION variable.
For it you have to write in the page where the login form gets processed:
session_start();//at top of the page
$_SESSION['user'] = $_POST['username'];
$_SESSION['password'] = $_POST['password'];
After this is set you can get the username in every file where
session_start();
is written.

If you don't want to use cookies, you could use some kind of session ID passed in the URL (see php.net/output_add_rewrite_var) and store it in a database, but then you'd be opening a whole new can of worms to do with session hijacking. COokie-based PHP sessions are the way to go.

Related

PHP SESSION Conflicts

I have this in my $_SESSION setting script:
<?php
//----------------------// Start session----------------------
if(!isset($_SESSION))
{
session_start();
}
//------------------------------------------------------------
//------------------// Check if Username $_SESSION is set------------------------------------------
if (!$_SESSION['Username']) { // If not current User
header("Location: ./logout.php"); // Session destroy file that leads to session logout landing page
exit();
}
//------------------------------------------------------------
?>
Now, what I basically do is just check if Username SESSION is set. But, I have come to notice something strange while putting another user through:
If we click the same link at the same time and arrive on the landing page same time, I noticed I can see my Username displayed as his Username and his personal data like email and phone replaced mine in my very own PC! This is really strange to me as we do not even live in the same country or even share same PC.
So, it is obvious I have not secured my SESSION and I have used a lame approach without thinking about security and this can be abused with SESSIONS hijacked.
How do I resolve this conflict? How do I restrict each logged in user to a particular session without conflicts if two or more users access the same resource at the very same time? I need help. I can't sleep since I found this.
After reading your responses, I will now show a snippet of the functions.php file which outputs Use data from DB.
First, I get the UserName value from session using:
$UserName = $_SESSION['Username'];
With this value, I query DB to get more user details:
//------------Get User Info -- All user column
$Get_User_Info = mysqli_query($conn,"SELECT * FROM customers WHERE User='$UserName'");
/************************************************************/
/************************************************************/
$Get_User_Info_row = mysqli_fetch_array($Get_User_Info,MYSQLI_ASSOC);
/************************************************************/
//---- Now list all user rows
$GLOBALS['Skype'] = $Get_User_Info_row['Skype'];
$GLOBALS['Jabber'] = $Get_User_Info_row['Jabber'];
$GLOBALS['ICQ'] = $Get_User_Info_row['ICQ'];
$GLOBALS['Join_Date'] = $Get_User_Info_row['Join_Date'];
$GLOBALS['Join_Date_Time'] = $Get_User_Info_row['Join_Date_Time'];
$GLOBALS['Balance'] = number_format($Get_User_Info_row['Balance'],2);
The above is what is contained in the functions.php which I require with each page I need protected.
As you can see, I barely see where I have done too much wrong there.

loosing data on page refresh php session

I am posting data from one site to another, then turning that posted data into a session.
form from other site
<form action="https://www.122.co.uk/11/" method="POST">
<input type="hidden" name="userid" value="1010101">
<input type="submit" value="Go" style="font-size:14px; padding:20px;">
I then post this data to my new site where I turn it into a variable $userid
then checking that the variable is empty or not, if not show some code.
check variable is not empty
if (!empty($userid)) {
?>
<div class="container">
<?php
echo "<hr>";
echo "You Are Logged In,</br>";
echo "Your User ID is <strong>" . $_POST['userid'] . "</strong>.";
When I refresh the page with a button click I loose the session data, so the code in the check dose not show.
how do I have a button to refresh to page and keep session data ?
button to refresh
<button class="btn btn-primary hidebutton showbuttonv2" role="button" id="homebutton" onClick="history.go(0)">Home</button>
Full code spinet
<?php
session_start();
$_SESSION['userid'] = $_POST['userid'];
$userid = $_SESSION['userid'] = $_POST['userid'];
//$_SESSION["userID"] = $userid;
if (!empty($userid)) {
?>
<div class="container">
<?php
echo "<hr>";
echo "You Are Logged In,</br>";
echo "Your User ID is <strong>" . $_POST['userid'] . "</strong>.";
This is because you're always overwriting the session data with the POST data, even if there isn't anything in the $_POST['userid'] field.
I see that you are very new to programming (PHP), and as such I would recommend you to sit down and think a bit about what you want to do. Then try to write down short item lists of the steps needed to do these things. Remember to be really specific, as that is what you need to be when writing the code. This is called pseudo-code, and is a vital tool in programming.
Once you've done that, read through the code you've written, and really read what it does. Not just what you expect it to. Then you'll learn a lot about how programming works. ;)
Short example, based upon the code you've posted:
Start session.
If user submitted ID -> Store ID in session
If session contains user ID -> Show login confirmation.
: Else -> Show login form
Your code, in "English" form.
// Start the session
session_start ();
// Save the POSTed value from the form in the session array.
$_SESSION['userid'] = $_POST['userid'];
// Save the POSTed value fromthe form in the session array, and a variable of its own.
$userid = $_SESSION['userid'] = $_POST['userid'];
// If we have a (non-empty) value in the user ID variable.
if (!empty ($userid)) {
// Show the login confirmation.
}
As you can see, there is a discrepancy between your expected behavior and the code you wrote. :)
Remember: Details always matter in programming.
Also, using JavaScript's history to create breadcrumb isn't the best option. This will lead to somewhat unpredictable behavior for the users, especially if they come to your page from a web search. (It'll take them to the search engine again, instead of your home page.)
That is why I recommend using proper URLs instead. Either relative, or dynamically created full ones. That way you always have full control where the user ends up when clicking on your links. :)
Edit, Added #2:
Here's how I'd write the code, to perform the tasks outlined by the pseudo-code.
// Using sessions to persist data across page views.
session_start ();
// Check if user has tried to log in.
if ($user = login_user ($username, $password)) {
// He has. Use session to keep him logged in.
$_SESSION['user'] = $user;
}
// If the user is logged in, show confirmation message.
if (!empty ($_SESSION['user']['id'])) {
$page = 'login_confirmed';
} else {
$page = 'login_form';
}
See how the comments, and the code, aligns withe the pseudo-code from the bullet list? And how it describes exactly what you want, in detail? ;)
You probably do not want to set $_SESSION['userid'] to the value of $_POST['userid'] if this last one is empty.
<?php
session_start();
// check that $_POST['userid'] is set
if (isset($_POST['userid'])) {
$_SESSION['userid'] = $_POST['userid'];
$userid = $_SESSION['userid'];
}
if (!empty($userid)) {
?>

Whats the best way to keep a user signed in after their session ends?

I'm working on a simple login page for a class and was planning on using cookies to keep users logged in (if they choose) after closing their browser. I used a checkbox input button as a case to set a cookie. After a user goes to the login page and signs in I send them to a script to check for valid username and passwords where I also check if the button was used
#QotD.php
if(isset($_GET['signed_in'])) #check box value
if($_GET['signed_in']=="on"){
if(isset($_GET['username']))
$username = $_GET['username'];
setcookie('username',$username,time()+10000);#cookie set with username
}
What I thought to do was to have a conditional statement at the beginning of the login page file checking whether a cookie is set and if it is go directly to the main page.
#QotD_homepage.php
if(isset($_COOKIE['username'])){
header("Location: main_page.php");
exit();
}
The problem is that it seems to keep the user signed in whether they check the box off or not. I tried adding a button to unset the cookie but it didn't work. Is there a more efficient way to handle cookies in this manner?
Firstly, for signing in a user, you are going to want to use the POST action method as it hides the information from the url. The GET method contains the information in the url and can be easy copied and hacked.
Secondly, you if statements should look like this
if(isset($_GET['username']))
{
$username = $_GET['username'];
# do something with username...
if(isset($_GET['signed_in']) && $_GET['signed_in']=="on")
setcookie('username',$username,time()+10000);
}
}
To solve your question regarding why user is being logged in every time, even when you don't set the cookie, the reason is probably because you have not unset the cookie. This is usualy done via a logout page.
Create a logout page with the code:
setcookie('username', null, 1);
Then run this page every time you wish to unset the cookie to test the login without ticking the checkbox.
Hope it helps :)
If conditional statement is wrong.Fix it by ending it with end if or using {} brackets. Use the code below
<?php
if(isset($_GET['signed_in'])) { #check box value
if($_GET['signed_in']=="on"){
if(isset($_GET['username']))
$username = $_GET['username'];
setcookie('username',$username,time()+10000);#cookie set with username
}
}
?>
OR
<?php
if(isset($_GET['signed_in'])) : #check box value
if($_GET['signed_in']=="on"){
if(isset($_GET['username']))
$username = $_GET['username'];
setcookie('username',$username,time()+10000);#cookie set with username
}
endif;
?>
Hope this helps you

PHP: Sending a constant through a form and auto-sending it

For a website, I need to route users to their own page. I have a login form, which sends data to a PHP file to check if the user's information is correct, and if so, forwarding the user to their page. The only problem is that I need to validate the user on arrival, to check if they logged in or just typed out the URL. I plan to use this with a POST, but how can I auto-send the constant (i.e. "logged-in")? Is there a way to do that through an HTML form (outputted from an echo) and sending it when the page loads? Thanks in advance!
EDIT 1: I understand that I must use Sessions, but whenever the page redirects it clears the session. The whole reason I was asking this was because I needed a way to keep the session active. How do I redirect in a way that doesn't clear the session?
In the PHP file that validates their credentials, start a "session". You can then apply session variables that can be called at any time while the session is valid. You can do this with POST, which is sounds like you're using, or by querying a database upon validation.
For example, upon validation:
session_start();
$_SESSION['username'] = $_POST['username'];
$security_check = mysql_query("SELECT * FROM userList WHERE username = '$username'");
$row = mysql_fetch_assoc($security_check);
$_SESSION['userId'] = $row['userId'];
$_SESSION['userFullName'] = $row['userFullName'];
On subsequent pages, you can put the following code at the top to check if the user logged in. If not, it will kick them back to the index page; otherwise the $_SESSION variables will be maintained.
<?php
session_start();
if (!isset($_SESSION['userId'])) {
echo "<script> window.location.replace('index.php?login=no') </script>";
}
?>
As suggested in the comments, I would recommend doing some further research on sessions to get a full understanding of how they work.

Are there any session security loopholes in my PHP script?

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
}

Categories