I'm currently in the process of developing a simple CMS for ONE user (this is unlikely to ever change). Therefore I'm storing login details in a .ini file (when live, will be stored outside root). Then using sessions to detect if the correct user has logged in, and if not, redirect them back to the login page using Header('Location: login.php') I'm curious as to how secure this actually is? Below is a draft of what I've got so far
Login Page:
<?php
session_start();
if ($_GET) {
header("Location: login.php");
die();
}
if (isset($_SESSION['user'])) {
header('Location: admin/index.php');
}
$config = parse_ini_file("login.ini", true);
$user = htmlentities($_POST['user']);
$password = htmlentities($_POST['pass']);
if ($user == $config['login']['user'] && $password == $config['login']['password']) {
$_SESSION['user'] = $_POST['user'];
header('Location: admin/index.php');
}
?>
<form action="login.php" method="POST">
<h2>Username:</h2>
<input type="text" name="user" />
<h2>Password:</h2>
<input type="password" name="pass" />
<input type="submit" Value="Login" />
</form>
Then there would be a check on every page in the admin area for the session, if not redirect to the login using the header location, like so:
Admin Welcome Page
<?php
session_start();
if (!isset($_SESSION['user'])) {
header('Location: ../login.php');
die();
}
And a logout page, would destroy the session.
I understand this is fairly simple and doesn't use a database. But are there any major secruity flaws to this design, using header location a lot, and storing sensitive date in the .ini file. Or for a simple application, is this well suited / not outdated?
Related
I am trying to make a very simple website, where you can go to the main page and log in, of which the code is here example.org/login/index.php:
<?php
session_start();
$warning = $_GET['warning'];
$nolog = $_GET['nolog'];
$username = "Welcome, please log in";
if ($warning) {
$username = "Wrong Username/Password Combination";
}
if ($nolog) {
$username = "Page inaccessible: Login required";
}
if ($logout) {
$username = "Thank you for your session";
}
?>
<!DOCTYPE html>
<body>
<div class="center">
<span class="warning"><?= $username ?></span>
<form action="submit.php" method="post">
<span class="formField">Username:</span><br>
<input type="text" name="user" class="field">
<br>
<span class="formField">Password:</span><br>
<input type="password" name="password" class="field">
<br>
<br>
<input type="submit" name="submit" value="Submit" class="field">
</form>
</div>
</body>
</html>
The submit page looks like this (when I get this to work I won't have the username and password hard coded like this, it's just to be concise for now) example.org/login/submit.php:
<?php
session_start();
$username = $_POST['user'];
$password = $_POST['password'];
if ($username == "admin" && $password == "12345") {
$_SESSION['loggedin'] = TRUE;
header("Location: http://www.example.org/welcome/");
die();
}
else {
$_SESSION['loggedin'] = FALSE;
header("Location: http://www.example.org/login/index.php?warning=true");
die();
}
?>
And the welcome page looks like this example.org/welcome/index.php:
<?php
session_start();
if(!isset($_SESSION["loggedin"]) || $_SESSION["loggedin"] == FALSE){
unset($_SESSION);
session_destroy();
header("Location: http://www.example.org/login/index.php?nolog=true");
}
?>
<!DOCTYPE html>
<body>
Hi
</body>
</html>
I know this is a lot of code, but when I try running it the first time around the welcome page returns an error saying that it is inaccessible, and sends me back to the login page, but the second time around it seems to work fine and logs me in. Can anyone understand why that would be?
EDIT:
After looking more into it, I discovered that the problem ONLY exists in Google Chrome and Firefox, but does not exist in other browsers such as Internet Explorer or Apple Safari. This now goes into the rendering engine of the browsers. Does anyone perhaps know of another way that I can use session ID's that might bypass this whole issue on all browsers, perhaps another way of validating a user?
Try to use the following
define('BASE_URL', 'http://www.example.org/');
if ($username == "admin" && $password == "12345") {
$_SESSION['loggedin'] = TRUE;
header("Location:".BASE_URL."welcome.php");
exit();
} else {
header("Location:".BASE_URL."index.php");
exit();
}
Add the following in the begining of welcome page
session_start();
if(!isset($_SESSION['loggedin'])){
header("Location:".BASE_URL."index.php");
exit();
}
If you pay attention to the names of the files that I mentioned, I was saying that I was directing my browser to example.org/login/submit.php and then forwarding that to www.example.org/welcome/index.php.
In Google Chrome and Mozilla Firefox, they care about the difference between having a www before the website or not, whereas in Internet Explorer and Safari they do not care about the difference. On my server the website www.example.org and example.org are mirrors of each other (this is a separate security issue) and therefore Google Chrome and Mozilla Firefox will treat them differently and give them different $_SERVER global variables, whereas Internet Explorer and Safari don't care about that difference.
We call it html1 for simplicity.
When a user goes to html1, there's a login2.php login page to enable access to client.php which is the hidden page.
It then goes to checklogin.php...if the password and user name matches...it then goes to the hidden client.php page...if not..it goes back to homepage.
The user has to login to be able to view the contents of hidden client.php page.
However the user can access client.php by typing in ..../client.php on the address bar...therefore bypassing the auth page and rendering it useless. I can just type servername/client.php...and it still shows me the contents of client.php...but I want client.php...to be private!
How do I prevent this from happening?
thanks.
first login page...
<html>
<head>
<title>Login Form</title>
</head>
<body>
<h2>Login Form</h2>
<table>
<form method="post" action="checklogin2.php">
<div id="name">User Id: <input type="text" name="****"></div>
<div id="password">Password: <input type="password" name="*******"></div>
<div class="button"><input type="submit" value="Login"></div>
</form>
</table>
</body>
</html>
then it goes to....
checklogin2.php
<?php
$*** = $_POST['****'];
$***** = $_POST['***'];
if($uid == '****' and $***** == '*****')
{
session_start();
$_SESSION['sid']=session_id();
header("location:securepage.php");
}
else
{
header("location:index.html");
}
?>
Then it goes to...
securepage.php
<?php
session_start();
if($_SESSION['sid']==session_id())
{
header("location:client.php");
echo "<a href='logout.php'>Logout</a>";
}
else
{
header("location:login.php");
}
?>
In the beginning of your every page you have to check if user is authorized.
On checklogin.php if user entered correct login and password, just set something like
$_SESSION['authorized'] = TRUE;
...and on other pages just check if user is authorized:
if (isset($_SESSION['authorized']) && $_SESSION['authorized'] === TRUE) {
// Alright, let's show all the hidden functionality!
echo "Psst! Hey! Wanna buy some weed?";
} else {
// User is not authorized!
header('Location: login.php');
exit();
}
Note that you don't have to mess with cookies, session IDs etc. - just add session_start() before everything and freely use $_SESSION var.
This is the main pro of sessions (and $_SESSION variable in particular): you can remember some data among different pages on same website.
All pages has to check if the user is authed. I would recommend using objects, and always inherit a class that checks this for you. It's not fun to have the same code everywhere, doing the same thing.
if($_SERVER["PHP_SELF"] == '/yourpagefolder/yourpage.php' && !isset($_SESSION['login_user'])){
header('location: login.php');
}
I have user sessions for the user to login. The problem is that anyone can open the server side links directly.
For example : http://mylink.com/foldername/json/json_example.php
If anyone browse the above link it opens directly.So I want to make secure to the database operations(some stores through JSON) and my server side PHP files by using sessions.I need to check user session before performing database operations and before opening of every page in server side.
The below code i used for User Sessions:
<?php
ob_start();
session_start();
if(isset($_SESSION['user'])){
header('Location: home.php');}
?>
<html>
<head>
<body>
<section class="container">
<div class="login">
<form method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>">
<p><input type="text" name="username" placeholder="Username" id="username"></p>
<p><input type="password" name="password" placeholder="Password" id="password"></p>
<p class="submit"><input type="submit" name="login" value="Login"></p>
</form>
</div>
<?php
if(isset($_POST['login'])) {
require_once('db/connection.php');
$username=$_POST['username'];
$password=md5(mysql_real_escape_string($_POST['password']));
$query=mysql_query("select * from tablename where username='$username' and password='$password'");
$row=mysql_num_rows($query);
if ($row == 1){
session_start();
$a=mysql_fetch_array($query);
$_SESSION['user']=$a['username'];
$_SESSION['pref']=$a['preference'];
header("location: home.php");
} else {
echo "wrong username/password";
}
}
?>
</section>
Please help in resolving the issue.
Thank you.
For blocking the access to the files that are included in others and should not be accessed directly: add this to the pages that are directly accessed, like index.php:
//This will prevent loading the included scripts as stand alone scritps.
define('SECURE', true);
and this to the scripts you don't want to be accessed by anyone directly
//Security check
!defined('SECURE') and exit("You should not be here.<br>Go back to the <a href='index.php'>home</a> page.");
For blocking access to any kind of file to the users that are not logged in, add this:
if (!isset($_SESSION['user']))
exit("You should not be here.<br>Go back to the <a href='index.php'>home</a> page.");
Is this something you are looking forward?
if(!isset($_SESSION['user'])){
header('Location: login.php');}
Note the ! at the beginning of isset. This means that if the user variable is not set inside the session, it will redirect to login.php.
In the application I'm developing I'm having a bug where I direct my browser to my app's index.php, and is then properly redirected to login.php if there is no current session. My problem is that after I type in my correct details on login.php and click submit, I am linked to another login.php screen (instead of returning to index.php with an active session) and required to put in my details again. The first screen has the same CSS formatting as index.php, while the second screen doesn't.
After entering my details on the second screen and clicking login, the sessions seem to function normally. Also, many times I will be presented with one logon screen, ill login and the user's correct Home screen data will be displayed (which requires successful queries from the login data), but if I navigate away from index.php to another screen that requires an active session, it will present the unformatted login.php screen.
If I logout, navigate to a different non-restricted page, and attempt to log back in again within the same browser session, the logon functions correctly with only one screen.
Here are snippets from the relevant files:
index.php
<?php
include_once 'db_functions.php';
require_once 'access.php';
if (isset($_POST['action'])) {
if (userIsLoggedIn()) {
header('Location: http://www.myapp.com/index.php'); //prevents users from having to confirm form resubmission if they refresh the page
}
}
if (!userIsLoggedIn()) {
include 'login.php';
exit();
}
login.php:
login.php
<body>
<h1>Log In</h1>
<?php
if (isset($loginError)) {
echo $loginError;
}
?>
<form action="" method="post">
<div>
<label for="email">Email: <input type="text" name="email" id="email" /> </label>
</div>
<div>
<label for="password">Password: <input type="password" name="password" id="password" /></label>
</div>
<div>
<input type="hidden" name="action" value="login" />
<input type="submit" value="Log in" />
</div>
</form>
</body>
access.php:
<?php
function userIsLoggedIn() {
if (isset($_POST['action']) and $_POST['action'] == 'login') {
if (!isset($_POST['action']) or $_POST['email'] == '' or
!isset($_POST['password']) or $_POST['password'] == '') {
$GLOBALS['loginError'] = 'Please fill in both fields';
return FALSE;
}
$email = $_POST['email'];
$password = $_POST['password'];
if (databaseContainsAuthor($email, $password)) {
session_start(); //LINE 17
$_SESSION['loggedIn'] = TRUE;
$_SESSION['email'] = $email;
$_SESSION['password'] = $password;
return TRUE;
}
else {
session_start();
unset($_SESSION['loggedIn']);
unset($_SESSION['email']);
unset($_SESSION['password']);
$GLOBALS['loginError'] = 'The specified email address or password was incorrect.';
return FALSE;
}
}
if (isset($_POST['action']) and $_POST['action'] == 'logout') {
session_start();
unset($_SESSION['loggedIn']);
unset($_SESSION['email']);
unset($_SESSION['password']);
header('Location: ' . $_POST['goto']);
exit();
}
session_start();
if (isset($_SESSION['loggedIn'])) {
return databaseContainsAuthor($_SESSION['email'], $_SESSION['password']);
}
}
function databaseContainsAuthor($email, $password) {
include_once './db_functions.php';
$db = new DB_Functions();
$result = $db->accountExists($email, $password);
return $result;
}
?>
Any help would be greatly appreciated!
UPDATE:
Error logs are showing multiple occurances of this error:
PHP Notice: A session had already been started - ignoring session_start() in /home3/monitot5/public_html/app/access.php on line 17
Access.php line 17:
if (databaseContainsAuthor($email, $password)) {
session_start(); //LINE 17
$_SESSION['loggedIn'] = TRUE;
What you should do is to use
session_start();
at the beginning of access.php file and don't use this function any more.
You should also completely change login of your access.php file. The first thing you should always do in this file is checking if there's a valid session for this user. Now you check it at the end of file and probably earlier you clear it because you unset session if there are no $_POST data.
In addition you shouldn't also use password in your session. It's rather very insecure. You should simple store login for your system when user filled in form valid username/email and password and unset it if user has logged out.
Sorry, but I won't write the whole code for you. You should simple look at some examples of code in Google to check how to handle user login/logout in PHP.
I am doing a project in school, I need to know a simple way to stop poeple from entering the site without a session. I have alot of pages I don't believe I spent the time pasting code on every page. Also I have menu bar that is included in every page thanks to php, so i was wondering wat type of code would I have to put in the menu to block user without a session. The rest of the content code is on the pages that I want to hide. I believe that you can login by typing out the url and allow users to see hidden pages that are for logged in users.
Please do not use a plain cookie. Sessions are the way to go. Or if can't use sessions and must use a cookie, sign the cookies first to be able to verify that your application was really the one to set it.
<?php
session_start();
if (!isset($_SESSION['authenticated'])) {
header('Location: login.php');
exit;
}
... whatever logged in users should see ..
If you don't want to use session, then use cookie.
<?php
/*Just add this piece of PHP code to top of any page you
don't want not-logged in users to see */
if (!isset($_COOKIE['logged']))
header("Location: login.php"); //It redirects the user to your login page
?>
<html>
<body>
...
</body>
</html>
Login page could be like this:
<?php
if (isset($_COOKIE['logged']))
header("home.php");
if ($_POST['submit']) {
//get username and password
$uname = $_POST['uname'];
$pass = $_POST['password'];
if ($uname=="correct" && $pass=="correct"){ //EDIT
setcookie('logged','1');
header("Location: home.php"); //Redirect to home page
}
else echo "Wrong combinaton!";
}
?>
<html>
<body>
<form action="login.php" method="post">
<label>Username</label><input type="text" name="uname" /><br />
<label>Password</label><input type="password" name="pass" /><br />
<input type="submit" name="submit" value="Login" />
</form>
</body>
</html>