Lockign down user access to single page


#1

The problem is this: we send users to a login page, and upon entering credentials, they have access to videos we post. However, once in, the user is able to alter the URL part of “user=XXX” and get access to folders outside. Broken index.php’s don’t work (like the whole “silence is golden” trick), and I’m not sure what to do to add security or to at least prevent users from leaving the page the credentials gave them access to.

Once logged in, the url reads this: /content.php?user=XXX&folder=XXX. All someone has to do is alter anything past .php? and they gain access into the entire parent directory.

The head of this php document seems to contain the security info:

<?php session_start(); include_once 'config/site_config.php'; if($_SESSION['logged_status_fe'] != 1){ header("location:index.php"); exit(); } $cur_folder = $_GET['folder']; ?>

Is there anything I can to add to this that prevents users from navigating away, or altering the url?

Thanks,
Josh


#2

Well, first there is ALWAYS a way to do anything in programming. Just need the knowledge to sort it out.
Quite often, it is simple and you just have to think out of the box a little bit.

So, in your sample, you show the user in the URL. This is not the way I would do it as any beginner hacker
can steel all of your user list. Usually, I hide user ID’s inside session variables. They take just the same
amount of server time to handle and make the site many times better secured. This is how I would do it.
It may mean a lot of small changes in your entire site, but, overall will hide your user’s info better.

First, never use a $_GET to handle user info. On any page where you have ?user=xxx , this exposes the
user’s private info to the world. Also, this means that Google and other robots could grab this info when a
member is on that page if they have plug-in’s in their browsers. A much safer way is to hide that info inside
the SESSION array. Session variables are not available outside the server and browser. Therefore, you can
hide that info very easily. I will explain how I do it and it seems to work very well for me on many sites that
I have helped with.

First, when the user logs into the system, you ask for their username and password. This is validated on
the site, usually using your database of users in a user table. This is done in your log-in page using the PHP
code to check that they are valid. At the end of that code, when they are accepted as a valid member, you
move them to another page. Just before you move them, just save their user info in a session variable.
Something in the form of " $_SESSION[“user”]=$row[“userID”]; " … Simple, in your example, you pass the
user id or name as “user=xxx” so, put the “xxx” into a session variable. I called it “user” to match your
example. Then, do NOT pass that info to the content.php page. It is available to the content page without
sending it out as a $_GET argument. Nobody every sees this data.

Next, in the content.php page, at the top first line, you start your session with “session_start();” which will
make all the session variables available to the page. Then, just grab the user session value instead of the
GET arguments. So, instead of $user=$_GET[“user”]; , you would do $user=$_SESSION[“user”]; which
still grabs the user info, but, it is hidden from all site visitor’s.

What is nice about this process is that visitor’s or user’s that use the site will never see the info on the
URL address line. The data is available, just have to grab it from the session array instead of the passed
argument list. You can also hide the folder=“XXX” variable also. The user’s will never see anything on the
address line except the current page they are on.

Now, looking at your code, you check a session variable called “logged_status_fe”. I will guess you used
that in your log-in process. I would change it to use the user=“XXX” instead. So, in your log-in code, you
set the $_SESSION[‘user’]="" or maybe set it to “NONE” or whatever. Then, if they pass the user-ID and
user-password check, you set the $_SESSION[‘user’]=“user-id-from-database” which would be the “XXX”
part from your sample code. In that way, in the content.php page, your first check can be to see if the
$_SESSION[“user”]!=“NONE” . If it is “NONE” then, the person on the site did not log in and you can send
them to a NOACCESS.php page where they are forced to log in with the correct display explaining why
they were sent to this page. So, I check at the top of every page on the site that the user is logged in.
This prevents hackers from typing in pages on your site with fake date in GET arguments to steal data info.

So, in this manner, you can not only prevent users from altering page arguments because they will never
see the arguments and never have a way to alter them. When they press a button to switch folders or
if their folder is hard-coded, your code can alter it but, hide it from the user.

Hope that helps and hope it is what you were looking for. If not explain further, if so, good luck with your
coding and your site. CYA in the bitstream…


#3

Completely agree and I would go a step further and obscure the session name, 152fd is less known than “user”. Then, in the session variable, hash the data so even if you look and see what is stored there, it isn’t blatantly obvious what it is.


#4

Here are two good websites dealing with security :

Open Web Application Security Project (OWASP)
https://www.owasp.org/index.php/Main_Page

and dealing with PHP Security :
http://phpsecurity.readthedocs.org/en/latest/

I personally just put the bare minimum in sessions, such as username and access level and never password or email address. If I need to access that I pull it from the database. You might want to look into using access tokens (that I put into sessions when the user logins and in a hidden input tag in the form) this helps prevents CRSF attacks.

I try to remember to put put this in my config.php or utilities.inc.php page :
[php]<?php
function generate_secure_token($length = 16) {
/* important! this has to be a crytographically secure random generator */
return bin2hex(openssl_random_pseudo_bytes($length));
}[/php]