Request for review - cookies and sessions
Posted: Fri Mar 07, 2008 7:41 am
Dear Phpeople,
I am working on a php app, and it will be an app which I will publish at some time... (free to use)
I have some experience writing php stuff, but I am no crack at all. Things work.
But this will be my first app published online, and I am a bit worried about security, so I would like more experienced coders to have a look at some of my ideas...
First, sessions and cookies.
I have written my own "session manager", and it is a cookie only session manager.
It works like this:
All installations of the app will have a unique "key", generated on installation.
When a user logs in, and supplies the right credentials, a session var is generated (the usual 32 char thing) and in the session table a "hashed" (with unique key) var is stored which contains the first 3 numbers of the IP address, the browser agent, language encoding and user_id (from users_table).
The session cookie is stored on the clients PC.
When a page is requested and the session cookie is present, the app checks the hashed user data, if its still correct, the session continues.
So, the session is tied to the users IP (first 3 numbers only) and browser. (I think)
The use of the unique installation key for hashing makes sure that other people who have downloaded the app cannot generate valid cookies for other installations of the app.
Here is the code which checks for a valid user:
session_clean() deletes expired sessions
session_user_hash() checks the hash, see below.
set_cookie sets a cookie, similar to phpbb3
clean_string = general function to clean user input from nasty things.
(Why only first 3 numbers of IP? because of rotating proxies, like AOL)
My question is of course, is this "safe" enough? What do you say?
thanks,
Bert
I am working on a php app, and it will be an app which I will publish at some time... (free to use)
I have some experience writing php stuff, but I am no crack at all. Things work.
But this will be my first app published online, and I am a bit worried about security, so I would like more experienced coders to have a look at some of my ideas...
First, sessions and cookies.
I have written my own "session manager", and it is a cookie only session manager.
It works like this:
All installations of the app will have a unique "key", generated on installation.
When a user logs in, and supplies the right credentials, a session var is generated (the usual 32 char thing) and in the session table a "hashed" (with unique key) var is stored which contains the first 3 numbers of the IP address, the browser agent, language encoding and user_id (from users_table).
The session cookie is stored on the clients PC.
When a page is requested and the session cookie is present, the app checks the hashed user data, if its still correct, the session continues.
So, the session is tied to the users IP (first 3 numbers only) and browser. (I think)
The use of the unique installation key for hashing makes sure that other people who have downloaded the app cannot generate valid cookies for other installations of the app.
Here is the code which checks for a valid user:
session_clean() deletes expired sessions
session_user_hash() checks the hash, see below.
set_cookie sets a cookie, similar to phpbb3
clean_string = general function to clean user input from nasty things.
Code: Select all
function get_session_user() {
global $dbname, $link, $user_auth, $lang, $table_prefix, $sess_lenght ;
$user_auth[user_id]= -1;
$user_auth[user_name] = $lang[GUEST];
$user_auth[user_level] = 0;
session_clean();
$theCook = clean_string($_COOKIE['sess_usr']);
if ($theCook <> "") {
$query = "SELECT * FROM `" . $table_prefix . "sessions` WHERE `s_cookie` = '$theCook' LIMIT 1";
$result = mysql_db_query ($dbname, $query, $link);
$num_rows = mysql_num_rows($result);
if ($num_rows) {
$Row = mysql_fetch_array ($result);
if ($Row[s_hash] == session_user_hash($Row[user_id])) {
$thetime = time();
$query = "UPDATE `" . $table_prefix . "sessions` SET `time`='$thetime' WHERE `user_id` = $Row[user_id]";
$result=mysql_db_query ($dbname, $query, $link);
set_cookie($theCook,$sess_lenght);
$query = "SELECT * FROM `" . $table_prefix . "users` WHERE `user_id` = '$Row[user_id]' LIMIT 1";
$result = mysql_db_query ($dbname, $query, $link);
$Row = mysql_fetch_array ($result);
$user_auth = $Row;
}
}
}
return;
}
Code: Select all
function session_user_hash($usr) {
global $site_data;
$cki = session_ip() . session_browser() . $usr . $site_data[site_hash];
$cki = md5($cki);
return $cki;
}Code: Select all
function session_ip() {
if ($_SERVER['HTTP_X_FORWARDED_FOR']) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip = $_SERVER["REMOTE_ADDR"];
}
$ipArr = explode(".",$ip);
$ip = $ipArr[0] . "." . $ipArr[1] . "." . $ipArr[2] ;
return $ip;
}Code: Select all
function session_browser() {
$browser = $_SERVER['HTTP_USER_AGENT'];
$browser .= $_SERVER['HTTP_ACCEPT_LANGUAGE'];
return $browser;
}My question is of course, is this "safe" enough? What do you say?
thanks,
Bert