PHP Session Authentication of Directory Index - php

The context:
I'm building a PHP 7 web application, it uses a PHP session to login and check to see if the user is logged in on each page. Here is the basic makeup of most pages:
<?php session_start(); ?>
<?php include 'the_header_and_menu.php'; ?>
<p>Page content</p>
<?php include 'the_footer.php'; ?>
At the top of the_header_and_menu.php file is an include to session_check.php which is located outside the site's directory. This PHP process does five checks, the most basic one included below.
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] == 'false') { // If loggedin is not set, or is false, then run this block.
header('Location: http://example.com/index?eject=noLogin'); // Send the user to the eject page.
die(); // Exit the process.
}
Process summary: User logs in, which creates a session and its variables. When the user loads a page, a session check is performed to make sure that the user's account is valid and authorised. If the account or session is no longer valid/authorised, then the user is redirected to the login page (index).
The issue: When someone who's not logged in enters http://example.com/dashboard, they are ejected using the first check (featured above). However, if they enter http://example.com/process/, the checks seem to count for nothing and the user is shown the page. This page does not just include a directory listing, but calls the http://example.com/process/index.php file to represent it instead.
The question: How can I apply the same logic that protects individual pages like dashboard.php, to the case of protecting directory indexes?
Own answer:
The issue here was one which was simple, but overlooked.
At the top of the_header_and_menu.php file is an include to session_check.php which is located outside the site's directory.
Within the header and menu file was the session check include. However, because the session check was located outside the main directory (like much of the back-end), I had referenced to it through a relative path, similar to the one below.
include_once '../mainfolder/php/subfolder/sessioncheck.php';
However, because the file was being included to a subdirectory, it should've included a further ../ operator.
include_once '../../safe/php/users/sessioncheck.php';
The solution: Instead of performing a session check through the header and menu, I am now including it on every page I want to protect. This is by no means a perfect solution and simply acts to get things working again.
Thank you to Daniel Schmidt, who got me looking in the right direction!

Directory indexes don't usually come from PHP - they are served by your webserver (nginx, apache, ..). Today, there is obviously no need to have that indexes enabled.
It looks like you're not sending each request to you're PHP process(es). I tend to suggest checking your webserver configuration.

The issue here was one which was simple, but overlooked.
At the top of the_header_and_menu.php file is an include to session_check.php which is located outside the site's directory.
Within the header and menu file was the session check include. However, because the session check was located outside the main directory (like much of the back-end), I had referenced to it through a relative path, similar to the one below.
include_once '../mainfolder/php/subfolder/sessioncheck.php';
However, because the file was being included to a subdirectory, it should've included a further ../ operator.
include_once '../../safe/php/users/sessioncheck.php';
The solution: Instead of performing a session check through the header and menu, I am now including it on every page I want to protect. This is by no means a perfect solution and simply acts to get things working again.

Related

MYSQL / PHP Authorisation Script

I'm designing a website (as an absolute beginner) and I've encountered an issue. You can easily log in with this script:
http://pastebin.com/0HZkQxXg
That script works fine, however, you can just as easily type in "addressofserver:homepage.html". How do I authorise the log in? Do I need to put a script on my index files to kick people off unless they've logged in first?
How would you do this?
Thank-you.
You need to actually be running the pages as .php not .html as you stated in your question.
You'll also needed to check if the user can/is allowed to access the said page. That means you check the session that you just set:
<?php
session_start();
if(!isset($_SESSION['loggedIn']) || !$_SESSION['loggedIn']) {
die(header("Location: /loginpage.php"));
}
?>
Also, on every page that you need to access any session variables, you will need to start the session with:
session_start();
That means on your login processing script as well (the one you posted).

Prevent direct access using the define and defined function in PHP

I'm trying to use the define function and the defined function in order to avoid hotlinking / direct accessing a PHP script but for some reason it will not work.
The issue I'm having is that it simply will not work and i recieve the "Hotlinking is not allowed" message even if i visit index.php first and follow the link and / or the post form.
Here is an example of what i'm trying to do:
index.php
<?php
define("ACCEPT",TRUE);
?>
<html>
...
core.php
<?php
if (defined('ACCEPT'))
{
// ACCEPT is defined which means the user came here via index.php
}
else
{
// The user is most likely direct accessing core.php, abort.
echo "Hotlinking is not allowed";
exit;
}
Please note that the post "Preventing Direct Access, is it possible to spoof a php define?" does not answer my question nor does the post "define and defined for disallow direct access".
This is what a fair amount of programs do. Just create a header that checks for the definition and redirect/exit if it isn't defined. There is nothing wrong with doing it this way, but it just adds to the amount of lines/code each page will need. This can be confusing because the DEFINE needs to be in one place, then the page requested has to either be included, or needs to include the page that has the define. It is all about structure.
Here is something you can do:
.htaccess - redirects every request to index.php
index.php - Defines a variable, acts as a router that fetches/includes the page to be shown based on request data.
childpage.php - checks if variable exists (meaning it was included) and then does whatever needs to be done.
The other option is to place the sensitive code in am htaccess protected directory.
You can use a framework as well that does a lot of this.
Or, if your host allows you to edit your vhost config, which they probably won't if you only have access to a public directory, you can change the document root to a higher directory.

php authentication best practice...?

I have a simple login page that checks credentials against database and then every page includes auth.php that verifies $_SESSION['logged'] is set and that session isn't expired.
Problem is that every page also includes another page tab.php (something like a menu), which I also need to restrict access to, but including auth.php inside tab.php makes the inclusion occur twice. If I don't include the auth.php in tab.php, though, anyone can access tab.php directly bypassing authentication check and possibly retrieve private information.
Any best practice to solve this situation?
EDIT:
And I forgot to ask, but what path you use to make it relative to site root? As both auth.php and tab.php are in folder and the index.php which includes tab.php is in root - the include function gives an error for either index.php or tab.php according to what path I use ('./includes/auth.php' OR './auth.php') - If you know what I mean. I tried '/includes/auth.php' but that doesn't work.
Use include_once instead of include in your files (or require_once and require). This will insure that your auth.php file will only be included once in the lifetime of the script.
include_once and require_once will definitely assure that you don't have the same file included more than once (at the same time make sure you're authenticated).
What I would do, however, is add your includes in a "include" folder and forbid access - to people who would type in the path manually - through an htaccess file. This way you could keep your includes in one place (whatever your header includes might look like) and keep your include files clean and still out of reach. If you were to do this you'd only have to do what Jan. mentioned in the answer above and check if your $_SESSION['logged'] is set (and whatever other checks you need)
Just check in tab.php if the session is initialized and $_SESSION['logged'] is true. This will work fine, if auth.php is loaded first.
What about using require_once("auth.php");? This makes sure, that auth.php is included (otherwise application will stop) but only includes the file once which seems to be your goal.
Try include_once(). See ( http://php.net/manual/en/function.include-once.php )

Include File - session error

For a small comments widget.
I'm trying to include that widget into any .php file at wish- in the most practical way for the user with just:
<?php include "comments.php"; ?>
I'm trying to create an admin-login-panel right into the widget, to offer the logged admin to delete the posts (and more other options).
The problem is: i have now to start to use the $_SESSION, to prevent the admin having to login over and over again at each change / page-refresh.
But, using sessions inside the widget I can only see header and session WARNINGS ...olready started... ....and so on.
Is NOT an option to force the user to put into his pages top 'session_starts', I'd like to keep things simple. Just php-include the widget.
Can I still keep trying with php sessions or should I try something else?
Thanks in advance for any suggestion.
Alright, with what information you have given us, this is what your problem is: PHP Sessions uses a special cookie that is sent in a header. So you must perform a session_start(); before any other content it sent to the browser, so it can set the cookie in the header. So unfortunately, it looks like you will have to start a session outside of their including of a widget.
Why is starting the session outside of the widget not an option? Do you not have control over the other PHP pages?
It might be possible to configure your site to auto-start the session on each page.
You can typically accomplish this by modifying a PHP configuration value for the directory via a .htaccess file like so:
<IfModule mod_php5.c>
php_flag session.auto_start on
</IfModule>
Also I would recommend referrencing the root path of your website in the include, so you can use that comment include statement on any page without having to add a bunch of '../../../' to the path.
<?php
include($_SERVER['DOCUMENT_ROOT'] . "/header.php");
?>

Diplay page directly with php

What is the best way to "NOT" display a page directly in php?
Edit
There is a page = register.php
a user cant open register.php directly. Only can access from index.php > Register.php
Thanks
Any PHP files containing sensitive data, such as database password, should be stored outside of the document root and included where needed. That way, if an admin makes a serious mistake and the web server starts sending PHP unparsed, that data will be inaccessible.
Edit
You edited your question and it now seems you wish to prevent access to page without them coming from a particular page. You should be able to get some ideas from these questions:
deny direct access to a php file by typing the link in the url
preventing direct access to a php page, only access if redirected
I think you want something like this:
if ( $_SERVER['HTTP_REFERER'] != 'http://YOUR_SITE/index.php' ) {
echo "Can't access this page from this referer";
die();
}
// go on with your register.php code
You can put
die();
or
exit();
At the top of your PHP document. However, your question is unclear as to what you wish to accomplish.
You can start a session in index.php and check for a certain variable from that session in the other pages.
make a file index.php
in it put
<?php
include 'register235235235235.php';
?>
make a file register235235235235.php
put whatever you want in there
As far as securing php includes, I only secure my database.php files which contain usernames and passwords.

Categories