Are Session Variables Vulnerable

tillabong

New Member
Messages
60
Reaction score
0
Points
0
hi i have been thinking about this for quite some time. can session variables be tampered with? if i have a code like this on any members page

PHP:
if (!isset($_SESSION['userid'])
{echo 'You need to log in first before viewing this page';}

will this be anyway subjected to any form of unwanted attacks? or are there any better alternatives to scripting a members page? i've read some articles on the net which mentioned about faking a session id and session files being easily available on shared host. but i couldnt find any articles that elaborated further. can anyone please enlighten me.

thank you very much for your time.
 

as4s1n

New Member
Messages
174
Reaction score
4
Points
0
Assuming this is sometime after a login script, as long as you check the user input value there, you should not have any problems later on.
 

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
will this be anyway subjected to any form of unwanted attacks? ... i've read some articles on the net which mentioned about faking a session id
You're probably referring to session hijacking.

Data stored in sessions is stored on the server, so isn't directly accessible to site visitors (a script can store user input in a session, so session data can be indirectly accessible; access to session data by local users will be considered later). There needs to be a way of associating session data with a visitor; furthermore, the association must be based on information that comes from the client. There isn't naturally enough information in an HTTP request to identify a visitor; this is where session IDs come in. A random string is generated when a new session is created and either stored as a cookie or in the URL as part of the query string. Technically, other HTTP headers could be used to pass the ID, but those are the only two techniques supported on all browsers. Also, there's nothing to gain by using custom headers unless you transmit something other than a session ID. If you're writing the client-side part of authentication as well as the server side, you could implement a challenge-response security protocol (see HTTP digest authentication for an example) using custom headers. Note that in a secure system, both client and server would send challenges to the other.

Session hijacking means someone spoofs the session ID by either figuring out someone else's session ID and using it as their own (along with any other data used to verify the session; more on this in a bit) or by trying a random session ID in the hope that it's valid. This works because the client has complete control over all the data in the request; any of it can be spoofed. Going back to an earlier topic, none of the user input can be trusted. In PHP, that includes the values stored in $_GET, $_POST, $_COOKIE, $_REQUEST, some of the values stored in $_FILES, and anything in $_SERVER with a key beginning "HTTP_".

There are two types of trust used in this post: that the data in question is genuine (i.e. that data isn't spoofed) and that it's benign. In the previously referenced post, only the benign aspect was considered.

To prevent session hijacking, you have to use some genuine data uniquely associated with the client. Now we're back at the same problem we had with session IDs, namely that there isn't any such data. However, we can get something that is nearly unique: the remote IP. Anything in $_SERVER with key beginning "REMOTE_" is associated with the client an fairly trustworthy (it's benign and likely genuine), but only "REMOTE_ADDR" and "REMOTE_HOST" are fairly unique, and the latter is completely determined by the former. I say "fairly trustworthy" because the remote IP can be spoofed, but it's trickier and the client won't receive the response, so it's a blind attack. I say "fairly unique" because the IP isn't uniquely associated with the client's computer when it's behind a proxy or NAT or dynamically assigned, and it isn't uniquely associate with a client when there are multiple users on the computer. "REMOTE_PORT" is associated with the client's connection, but not in any way unique; furthermore, while you can generally trust that it's genuine, the client still gets to pick what port it uses (basically, there's no need to spoof a port). The remote port is trivially genuine.

What you do is store the remote IP in the session. Whenever a request comes in that uses a session, first check that the remote address for the request matches that stored in the session. If they don't match, generate a new session with a new ID so the user has to log in again (leave the old session around so a valid user doesn't get logged off by a hijack attempt). Note you can't assume that a change in IP is a hijack attempt, because the client's IP address may have been reassigned, or they may have switched to or from using a proxy.

There are a few other important techniques to combat hijacking. To prevent lucky guesses, the space for sessions IDs should be huge, so the likelihood of guessing a valid session ID is low. The session handler should do this for you already. Also, sessions should expire after a set period of inactivity. PHP will do this automatically; note "inactivity" means "modification" rather than "access" (you need to change something in the session to prevent it from expiring) for PHP sessions. Lastly, you can use HTTPS to prevent snooping. This requires getting a registered server certificate; search the forums for details on how to do this on X10.

Try a web search for more information on session hijacking. Stackoverflow has numerous questions on the topic (note: if you decide to sign up for SO, read the FAQ and lurk some to learn the format).

and session files being easily available on shared host. but i couldnt find any articles that elaborated further.
In PHP, limiting access to session data is taken care of by the session handler, rather than the session extension. With PHP (and many other server side technologies), session files are usually stored in /tmp or /var/tmp. They should have permission mode 600, which means only the file owner can read them. This will either be the "www" user or (as on X10) the user account for the site. The latter means no other accounts (other than root) can read the session files for your site. If all virtual hosts run as user "www", then anyone can run a script as the "www" user and read your session files.

You don't have to use files for session storage; it's merely the default. You can set your own session handler. For example, you can store data in a MySQL or PostgreSQL database.

Read the PHP manual section on sessions for more.
 
Last edited:

tillabong

New Member
Messages
60
Reaction score
0
Points
0
Thank you so much for replying. i've written a code to prevent session hijacking but it doesnt seem to be working.

everytime a user succesfully logs in this script is executed.
PHP:
 $session = uniqid();
 $_SESSION['session'] = $session;
					 
$query = " UPDATE table
SET session = '$session'
WHERE email = '$email' ";  /*Storing session id*/

$result = (mysql_query($query));

and on the members page i have this
PHP:
$session = mysql_real_escape_string($_SESSION['session']);
$email = mysql_real_escape_string($_SESSION['email']);

$query = "SELECT session FROM table
		WHERE email = '$email'";
$result = mysql_query($query);
$storedsession = mysql_fetch_array($result);
$storedsession = $storedsession["session"];

if (!isset($_SESSION['email']) || $session != $storedsession) 
{echo 'You need to log in first';
session_destroy();
session_unset();}
am i using session_unset and session_destroy correctly? i was thinking if anyone manages to fake a session id, it would be best to unset the session variables. but somehow when i included session_unset and session_destroy, the user never gets logged in on the members page even if the user was already previously logged in.

i've tried a simple code like this
PHP:
session_start();
$_SESSION['test'] = 1;

if(isset($_SESSION['test']))
{session_destroy();
session_unset();}

echo $_SESSION['test'];
however the result ends up as 1. did i miss out on anything?

thank you very much for your time.
 

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
PHP:
 $session = uniqid();
 $_SESSION['session'] = $session;
					 
$query = " UPDATE table
SET session = '$session'
WHERE email = '$email' ";  /*Storing session id*/
[...]
PHP:
$email = mysql_real_escape_string($_SESSION['email']);

$query = "SELECT session FROM table
		WHERE email = '$email'";
This approach won't prevent hijacking. The ID and email stored in the session will always match those stored in the DB, since you update the DB whenever you set the ID. Remember, what you need to do is examine data coming from the client, compare something from the current request to something from the request when the visitor logged in. Comparing data that only exists server side cannot prevent hijacking.

That you're attempting to generate your own session ID (and unsuccessfully at that), along with the fact you use both session_unset and $_SESSION tells me you should take a close look at all the PHP session documentation (which was linked to in my previous post; as it says in my sig, read through all linked documents). After that, research tutorials and articles on preventing session hijacking. Given your lack of experience with security, you shouldn't be attempting to design your own protocols.

PHP:
$session = mysql_real_escape_string($_SESSION['session']);
$session is never fed to an SQL query, so it shouldn't be escaped. With prepared statements, you wouldn't make this mistake.

PHP:
$email = mysql_real_escape_string($_SESSION['email']); 

$query = "SELECT session FROM table 
        WHERE email = '$email'"; 
$result = mysql_query($query);
$storedsession = mysql_fetch_array($result);
$storedsession = $storedsession["session"];

if (!isset($_SESSION['email']) || $session != $storedsession) 
{echo 'You need to log in first';
session_destroy();
session_unset();}
If $_SESSION['email'] isn't set, you shouldn't be using it, as you do when you set $query.

You need to pick a standard indent style and use it. Blocks should be properly indented, otherwise they are harder to read, which leads to typos and bugs.

i was thinking if anyone manages to fake a session id, it would be best to unset the session variables.
This will cause valid users to be logged out if anyone tries to hijack their session. Better to generate and send a new session ID when hijacking is suspected. Note that session_regenerate_id, like session_start, must be called before the cookies header is sent, which is before you output anything other than headers.

but somehow when i included session_unset and session_destroy, the user never gets logged in on the members page even if the user was already previously logged in.
Are you sure the presence of session_destroy and session_unset are the problem? Don't guess; stick to the symptoms.

If something isn't doing what you expect, you need to debug it. The simplest way is to add scaffolding–statements present solely for development purposes, such as printing the current value of a variable. For example, print $session and $storedsession to see what they end up holding. Also, you should do your development on a development server (install XAMPP or WAMP on your own computer) with error reporting set to the highest level. For quicker debugging, use an interactive debugger. You'll need a PHP extension (such as XDEBUG) to support it, along with the debugger itself (XDEBUG lists compatible debuggers).

i've tried a simple code like this
PHP:
session_start();
$_SESSION['test'] = 1;

if(isset($_SESSION['test']))
{session_destroy();
session_unset();}

echo $_SESSION['test'];
however the result ends up as 1.
Which is why you shouldn't mix session_unset (or session_set) with $_SESSION. To empty out the session data, use:
PHP:
$_SESSION=array();
 

tillabong

New Member
Messages
60
Reaction score
0
Points
0
thanks for correcting my mistakes. i will look through everything you posted thoroughly again.
 
Top