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.
Related
I have some problem understanding how to use php 5.5.0+ password_hash and password_verify to protect pages access.
Let me explain what I did.
1) When I create a new user for my webapp, I store username and hashed password in a users table. To hash the password before to store it in the db, I use
$hashedp = password_hash($password, PASSWORD_DEFAULT);
2) On page login I can take the password submitted by the user in the form and 'compare' it with that stored in the database for the same user in this way
$password = the password submitted by the user
$user_hashedp = the hashed password taken from the db
if (password_verify($password, $user_hashedp)) {
// login the user
} else {
// show error
}
3) What I don't understand is how I can check and protect access to other pages, after the user has logged in. Imagine You have another page page1.php that you want to show only if the user is logged correctly.
How can I build this check?
kind regards,
Matt
Like already said in the comments you can use session for this. Below an example.
session_start();
if (password_verify($password, $user_hashedp)) {
// login the user
// create session for logged in user.
$_SESSION['authorized'] = true;
} else {
$_SESSION['authorized'] = false;
// show error
}
Then in authorizedusersonly.php:
session_start();
if($_SESSION['authorized'] === true) {
//content for authorized users
} else {
//content for unauthorized users
}
I'm not entirely sure how late I am to the party, but Daan has the right idea with doing sessions.
I would personally set a username session variable upon a successful login, then on every page, make sure that it is set. If it isn't, redirect them to a certain page, e.g. a login.
if (password_verify($password, $user_hashedp)) {
$_SESSION["user"] = $user; // user being the login username; also verified.
} else {
echo "Invalid credentials!"; // Throw some type of error. That's up to you.
}
On each page, you can either include a file that will house the session verification code, or just copy/paste it onto every one of your pages, like this:
if (!isset($_SESSION["user"])) // If the user has not been verified...
header("Location: login.php"); // Redirect them to a page of your choice, i.e. a login.
You could do it the other way, but the greatest advantage you'd have with this is the fact that if you ever need to obtain the username for something, instead of having to get the username through a query, which might affect performance, you could simply reference the session variable and deal with it from there.
That is how I would personally do it.
I'm new to PHP. I have created a system where the users include user and admin. I login as a user in the system and the URL is localhost/View/user.php.
When I change the URL from localhost/View/user.php to localhost/Admin/admin.php, the user automatically has an admin interface.
My question is - how can I stop the user from being able to change the URL to /admin.php and accessing the admin interface?
Here are some examples:
http://php.net/manual/en/features.http-auth.php
But just know that this is not something you should use for a real website, unless you know all the security issues and how to solve them.
But for learning something about php and playing around this could be a place to start :)
Well you can't force a user to not modify the url in his browser.
What I think you are looking for is some kind of user roles.
So when you already have a login system I assume you store the username and password somewhere (mostly a database).
What you can do now is to add an additional field "roles" and write in "user", "admin" or something to differentiate users.
At your admin-page you could than check if the user has the role "admin", if not you can redirect the user to some other page (e.g. index) or just print out "Access denied"
(There are also a lot of tutorials about login systems and user roles for php out there. I would recommend to take a look at that also)
Simple add flag for user and check weather the flag is set or not if not than through user to error page.
Example
for admin $flag_admin=1;
and store this in session and check if flag is set than allow him to access admin screen else show error page.
A simple answer is that you should store the fact that the user has logged in via $_SESSION (such as $_SESSION['user_id'] = [something from the database]) and that can be tested later (such as isset($_SESSION['user_id']) followed up by looking that user up again in the database to make sure they do actually have admin rights. If they don't you can simply redirect them back to the login page via header('Location: http://whereever.com/login.php') or what-not. This isn't foolproof security, but it's a start.
If the session isn't automatically initialized (unlikely but possible depending on server configurations), you can start it at the beginning of each of your scripts with session_start().
To be more specific. Let's say that you have a script called user.php that takes in user login information. In that you might have something that looks like this...
<?php
session_start();
$login = (isset($_POST['login'])) ? trim($_POST['login']) : '';
$pass = (isset($_POST['pass'])) ? $_POST['pass'] : '';
if ($login !== '') {
$user = [db->lookup_somehow(where=>login is $login)]
if ([the hash of $pass is the same as the hash of the pass in $user]) {
$_SESSION['user_id'] = $user['user_id'];
header('Location: http://wherever.com/admin.php');
} else {
// say "invalid login"
}
} else {
// handle missing input
}
?>
And admin.php might look like...
<?php
session_start();
$user_id = (isset($_SESSION['user_id'])) ? $_SESSION['user_id'] : null;
$user = null;
if ($user_id) {
$user = [look up user from database based on their id];
if (!$user[has credentials to be an admin])
$user = null;
}
if (!$user) {
header('Location: http://wherever.com/user.php');
}
// else do admin stuff
?>
One possible solution to the problem is to check for admin permissions when the user navigates to the admin.php. If the user has adequate permissions, then the admin interface is visible. If the user does not have admin permissions, then they should be redirected back to user.php.
However, the better option would be to have a single login page - login.php. After logging in, the user permissions are checked, and the admin interface is made visible if applicable.
I have the proper solution.
suppose your admin's users id is 'admin' and your other users have other user id.
Then use $_SESSION('login_user') to login.
In your amdin page you want to protect from user you sholud put a condition that
$result = mysql_query("select username from adminlogin where username = '".$_SESSION['login_user']."'");
$result_value = mysql_fetch_array($result);
echo $result_value['username'];
if($result_value['username']!="admin")
{
header("Location: index.php");
}
Now it will check for user id = admin then it allow to access other wise it redirect the page to index.php that is our login page. If you can not understand then you can replay. Thanku
I primarily develop HTML/CSS web-pages, and I'm working on a webpage where the users need to have a page password protected from prying eyes. The page would just be for posting non-confidential information, such as private-member events, and scheduling. I know the basics of PHP, and would like to use that, but I'm concerned about safety. The page will have multiple users, but it only needs one password which would be used by all the users. It's also a fairly low-traffic site, so for the situation it doesn't need to be 100% secure, but I would like it to be as secure as possible without too much hassle.
So far I have a login-page that comes up when the user tries to access the member-page, with a password input field, which posts the result to a page called (example name) verifypassword.php
This file looks something like this:
$password = ("mypass");
$passresult = $_POST["password"];
$passresult = strip_tags($passresult);
$passresult = htmlspecialchars($passresult);
if ($passresult != $password) {
die("Invalid password.");
}
elseif ($passresult == &password) {
setcookie("mycookie");
header("location: member-page.php");
}
else {
die("Unknown Error")
}
Then, at the top of the member page, I have some lines of PHP code as follows:
$userloggedin = $_COOKIE["mycookie"];
if (!isset ($userloggedin)) {
die("Please log in to view this page");
}
The files and values themselves are hidden via the die function if the user isn't logged in, but the password and cookie are still being transferred across the server.
I've tried to read up on salting and hashing a password value, but unfamiliar with this kind of thing. How should I be doing this? Are there any tutorials or resources I can read? I tried looking on Google, php.net, and of course here on stackoverflow, but I couldn't find anything that dealt with passwords other than creating a database to store multiple user-generated passwords, which isn't what I need.
I'm currently using WAMPP.
The top line of your code, if you want to follow best practice, should look like this:
$hash = '$2y$10$zRg5l/v9gzD/aICnp/GUlu/rFv/0ZNvxX/A5v86zjepZmuRWWL6IG';
Notice that we're storing a hash instead of the password in plain text. These hashes are generated in the following manner:
password_hash("test", PASSWORD_DEFAULT);
Why are we doing this? Because if your database (or code, in this case) is accessed somehow, then you don't want your passwords to also be stolen. The built in password handling functions mitigate this as much as possible.
In terms of checking the password, you have to make your peace that the user will have to send the password over the internet one way or another! If this is a big concern for you, you can use SSL to mitigate this - it is best practice to always use SSL for at least authentication. This means that if someone intercepts the connection between your user and your website, they will only be able to see encrypted data. Anyway, you would check it as follows when it arrives:
// Assuming single password:
if ( password_verify( $_POST['password'], $hash ) ) {
// correct!
// the plain text in $_POST['password'] is the same as the plain text used to generate $hash
}
Okay, so, next thing. Cookies are sent between the browser and the server as a header. These can be set arbitrarily by the client. So if you rely on a cookie such as $_COOKIE['mycookie'] to authenticate users, then someone could just send a manually-crafted Cookie header to imitate the effect of being logged in. The solution to this particular problem is to use sessions. At the top of every script, you run session_start() which sets its own cookie. This cookie does not contain any information, just a randomly generated unique ID. PHP stores information and associates it to that ID (by means of a file in the temp folder) - but at no point is the client itself able to see what that information actually is - or change it.
To add information to the session you put it in the $_SESSION superglobal as follows:
$_SESSION['logged_in'] = password_verify( $_POST['password'], $hash );
password_verify will return true if the password matched or false otherwise, so you can rely on this to set the boolean properly.
So you can rewrite your code as follows for login.php:
session_start();
$hash = '$2y$10$zRg5l/v9gzD/aICnp/GUlu/rFv/0ZNvxX/A5v86zjepZmuRWWL6IG';
if ( isset($_POST['password']) ) {
// Assuming single password:
if ( password_verify( $_POST['password'], $hash ) ) {
// correct!
header('Location: /member-page.php');
}
}
// display login form
and at the top of the members page:
session_start();
if (empty($_SESSION['logged_in'])) { // checks if it's set and if it's false
die("Please log in to view this page.");
header('Location: /login.php');
}
n.b. I rewrote my answer because I realised it didn't answer many of your questions very well :)
You probably shouldn't be using Cookies to do this since they can be forged on the client side. A session variable will probably work a little better, but if you want to try and keep it simple I would probably MD5 the password with some salt and store it in the cookie, then check that against your MD5ed password + salt when the tries to access the page again.
So off the top of my head something like this:
<?
$password = ("mypass");
$salt = "makeUpASaltHere";
$passresult = $_POST["password"];
$passresult = strip_tags($passresult);
$passresult = htmlspecialchars($passresult);
if ($passresult != $password) {
die("Invalid password.");
}
elseif ($passresult == &password) {
setcookie("mycookie",md5($password.$salt));
header("location: member-page.php");
}
else {
die("Unknown Error")
}
?>
Put this in a separate file and just use require() to include it at the top of all your member pages.
<?
$password = ("mypass");
$salt = "makeUpASaltHere";
$userloggedin = $_COOKIE["mycookie"];
if ($userloggedin == md5($password.$salt)) {
die("Please log in to view this page");
}
?>
Still not as good as using session variables, but at least someone just couldn't just create "mycookie" out of no where and get in. Also it has the advantage that if you ever were to change the password it would automatically log out everyone that was already logged in.
I need to know how secure is my user authentication code that I am using in my php applications.
This is my login check function
// Is Login
//*********************************************************************************
public function isLogin()
{
$validation = new Validation();
if(!$validation->isEmpty($_SESSION["AdminId"]) && !$validation->isEmpty($_SESSION["AdminUsername"]) && !$validation->isEmpty($_SESSION["AdminName"]))
{
return true;
}
else
{
return false;
}
}
I have a authenticate file which i call from top of every user account's page which is as under
if (!$admin->isLogin())
{
header("Location: index.php?type=warning&msg=" .urlencode(ADMIN_INVALID_LOGIN));
exit();
}
The session values for example Adminusername is the actual username of the admin, adminname is the alphabetical name of the admin and adminid is the record id from mysql table such as $_SESSION["Adminusername"] = administrator though i am storing this value after encypting it.
I need to know is this a secure method to just store the values and check for them or I need to have some kind of advance functionality to make it more secure such as salt or time check etc.
I would appreciate your suggestions and feedbacks. If possible, your authenticate code / class.
Thanks in advance.
Amardeep Singh
use session regenerate id to get a new ID in every request, so u can prevent session hijacking .. read this manual : http://php.net/manual/en/function.session-regenerate-id.php
I am storing this value after encypting it
I don't understand... Why do you crypt your AdministratorName?
As you surely know, the user cannot manipulate his session as he wants, because the session is on the serverSide and your code decide what to write into session-data.
I think, salting or timechecking do not raise your security-level.
Because HTTP is stateless, each session is identified by a id, which ist mostly saved in a cookie on the client side. Each of your request to this server contains this SID, because it's the only way your server could identify a visitor.
If you use HTTP-Transport, your data (end also your SID) is sent through the internet without encryption. So a hacker could read your SessionID and take over your Session (which contains logged in User-Data). To prevent this, you can force HTTPS connection for logged in users.
If you have the possibility to switch all your pages to https-only, do it. If you must switch between http and https (for example https only if user is loggedin) it becomes really difficult to guarante security!
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
}