PDA

View Full Version : Security and "login"-scripts



Eikern
July 9th, 2007, 01:04 PM
Hey.
I'm planning on creating a portal where people can register and log on to. The site will have different sections, and the majority of users can't have access to the admin-section so I have to prioritize the security.

What do I want to use and think about when I'm writing the script?

Usually I've just created a $_SESSION with the clearance-level, but I guess this could be edited with the right kind of browser.


Can anyone tell me what the professional and safest way of doing this is? And maybe give me some tips in general?

Thanks!

-Eikern :)

BetaWar
July 9th, 2007, 01:56 PM
What I normally do is keep everything in a database (user levels, permissions, etc.) and then when a user logs in you would check to make sure that hte username is LIKE the database username and that the password is = to the database password. (Like means that is could be upper or lower case, use if the username is NOT case sensitive.) If the user gets both correct you set a session (I typically use cookies though) with only the member's ID being stored. Then on each page load you have a query check to make sure that the user's level is heigh enough to be viewing the page and so on. If you use a cookie though you will want to make it a shorter value (unless you add a remember me button in there) so I would say about 2 hours would be a safe bet for cookies that don't remember the user. Sessions do work wonders for that though...

eirche
July 9th, 2007, 05:57 PM
Usually I've just created a $_SESSION with the clearance-level, but I guess this could be edited with the right kind of browser.

that's not true.

borrob
July 10th, 2007, 05:09 AM
eirche that's not true.

i'm not sure but i do remember reading that it is possible to read session variables.
i will look it up and come back to you oon that....

borrob
July 10th, 2007, 05:18 AM
i'm not sure but i do remember reading that it is possible to read session variables.
i will look it up and come back to you oon that....
ok i looked it up and sessions are not completely save. It's possble to get the sessionid and to manipulate it. ( all from phpfreakz.nl ) it's in dutch and i'm not going to translate it here. But it's definitly not 100% save....

borrob
July 10th, 2007, 05:31 AM
there is a solution thow:
create the file session.inc.php

<?php
// session.inc.php
session_start();
ini_set('session.save_path', '/home/sijmen/tmp');
ini_set('session.name', 'hash'); # try to hide the session name..
if (!isset($_SESSION['ip']))
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
if ($_SESSION['ip'] != $_SERVER['REMOTE_ADDR'];
trigger_error("Session Hijacking detected!", E_USER_WARNING);
?>

instead of session_start() at the beginning do:
<?php
include 'session.inc.php';
// ..
?>

the include will bind the session to an ip adress and will keep others from putting your session variables on there own server. Further more it will put the session variables on
a save dir ( change '/home/sijmen/tmp' to your own save directory ).

Voetsjoeba
July 10th, 2007, 10:40 AM
Binding a session to an IP address is a bad idea. There are many ISPs out there that force their customers to connect through a proxy server, causing the value of $_SERVER['REMOTE_ADDR'] to change all the time. That basically means users behind a proxy (be it forced or not) will not be able to log in to the site at all.

There are two major points concerning session security. The first is server-side, the second is client-side. To understand these, it's important to know how exactly sessions work.

When a session is created on the server, a unique session ID is generated that maps to a specific bit of data on the server's temporary files directory (commonly /tmp on *nix). This is the file that will hold all the data you assign to that specific session.

To be able to associate a client's browser with the correct session again, the client needs to be made aware of this session ID somehow so he can send it back to the server to identify itself. To do this, there is the method of appending the session ID to each URL. This is quite insecure though, since people who do not know how sessions work probably won't mind giving out URLs with their session ID still in it, making it really easy for smart people to trick them into getting their sessions hijacked.

The other method is to send the session ID to the client using a cookie, commonly named "PHPSESSID". This does not expose the session ID in the URL like the previous method did, and is therefore a better solution.

That, in a nutshell, is how sessions work.

Now the first problem arises when you're on shared hosting. If all sessions are stored in the same directory (which is quite possible), then this means that other sites on the same machine also have access to your sessions. Therefore, you must make sure that you store your sessions in a directory that is only accessible by you. The session storage directory can be set in php.ini. If you do not know exactly how to do this, contact your host.

The second problem is the problem of cookie stealing. This happens through XSS, which stands for Cross Site Scripting. The idea is simple: unsecure pages that do not sufficiently check user input are often vulnerable to having javascript injected into the script's output. Since javascript has access to cookies, an attacker can easily inject a piece of javascript that steals your cookie content (that is, your session ID). Then, they take your session ID and forge their own cookie to be exactly like yours. When they then visit the site, the server will recognize them as having your session, and thus they would effectively be logged in as you.

Key to preventing cookies from getting stolen is to make sure no harmful input gets output(ted?). Never ever trust user input. Treat it as extremely dangerous at all times. Be as strict with it as you possibly can. An easy way to prevent a lot of XSS attacks is by escaping all output to html entities (unless you really need it to be HTML, but you usually don't). A simple htmlentities() with ENT_QUOTES enabled will go a long way.

I personally always have two functions in every project I work on: ehtml and html. The first escapes a string for HTML, the other simply echos an escaped string:


function ehtml( $str ){
return htmlentities( $str , ENT_QUOTES );
}
function html( $str ){
echo ehtml( $str );
}

I then simply use html( ) instead of echo( ) everywhere I can.

eirche
July 10th, 2007, 01:08 PM
one can hijack someone else's session by knowing his session cookie id 'PHPSESSID'. but one cannot arbitrarily modifying the $_SESSION variable in the php script.

Eikern
July 10th, 2007, 01:46 PM
But what if I store the sessionid and the username in a $_SESSION and in the database as the last known sessionid. Then checks this on every pageload if the sessionid and username matches with the database within a certain timeperiode and renews this period if the check is true?
I could also use last known IP, but as you said, Voetsjoeba, some ISPs will make that unusable.

raz
July 10th, 2007, 02:06 PM
As for sessions not being 100% safe - nothing is ever safe.. Sessions have worked well for MANY sites in the past.

As for trying to hide the session, stay away from common names? Tamper Data (A FF plugin) can edit cookies and post data, so watch out for that.

My suggestion would be to just have a "checks and balance" deal going on... they load a page, make sure their session/cookie matches the information in the database (except for name and password and that if they're allowed to edit those things).

My .02.

Esherido
July 10th, 2007, 02:23 PM
^ I don't think Tamper Data can edit cookies, I know it can edit GET and POST requests because I use it to try to hack my own sites to make sure they're secure. :D I personally prefer using sessions, in PHP they're a ton easier to manage than cookies. Also like Voetsjoeba said, treat user input like the plague. ;)

Eikern
July 10th, 2007, 05:48 PM
Is there any difference on how I store session data?
I start every page with

session_start();
header("Cache-control: private");
and then set variables like this

$_SESSION['somename'] = array('variables',...);
or something similar.

Is there a better/more safe/more correct way of doing this?

Esherido
July 11th, 2007, 08:44 AM
^ That seems pretty safe to me.