Page 1 of 1

include and login securites

Posted: Mon Apr 11, 2005 3:19 am
by pella.d
ok, i've got two questions
I've got a small web app setup, but I don't know a whole lot about the finer details in security
A friend gave this to me when I asked him for a login/password checking script:

Code: Select all

<?
if(isset($HTTP_COOKIE_VARS['username']) && isset($HTTP_COOKIE_VARS['password'])){
	$username = safeString($HTTP_COOKIE_VARS['username']);
	$password = safeString($HTTP_COOKIE_VARS['password']);
}
else if(isset($HTTP_POST_VARS['username']) && isset($HTTP_POST_VARS['password'])){
	$username = safeString($_POST['username']);
	$password = safeString($_POST['password']);
} else {
	include 'login.php';
	exit();
}
include 'dbconnect.inc.php';
$qstr = "SELECT username, password FROM members WHERE username = '".$username."' and password = '".$password."'";
$result = mysql_query($qstr);
if (mysql_num_rows($result)) {
	setcookie("username", $username,0,"/");
	setcookie("password", $password,0,"/");
} else { 
	include 'login.php';
	exit();
}
function safeString($targetVariable) {
  $targetVariable = addslashes(trim($targetVariable));
  return $targetVariable;
}
?>
Now I'm wondering if this is secure at all, I got it working and all, it's included to the top of all the pages that require a logged in user. Which is another point, is it secure to just include that into the top of a page?


and my second question is to deal with a database connection include.
If all the details for the database are in the include, like $host, $db, $dbuser, etc, is that a security issue in itself?
Is it possible to exploit that include somehow and modify the database contents?


If my questions are lacking detail just let me know, and I'll pull up some examples or something.
thanks for any help

Posted: Mon Apr 11, 2005 4:56 pm
by Ambush Commander
It's using antiquated variables mixed with the new ones ( $HTTP_COOKIE_VARS = $_COOKIE ). It also appears that your passwords are not encrypted in any way when inserted into the database. Most people would want to have it hashed and then store the hash. What's worse is that the password is stored, in plaintext, in the Cookie. That's an nightmare.

Personally, I would use a function or login class instead of relying totally on an include. Furthermore, this code doesn't offer optional password remembering (it relies totally on cookies), it doesn't use Sessions, and it doesn't offer a logout function.

Posted: Tue Apr 12, 2005 2:32 am
by pella.d
Wow damn, lots of problems.
So I did a bit of searching, and to encrypt the password should I be using the md5 thing?
Or is there another method?
Should it also be stored encrypted in the cookie?

do you think you could elaborate on a function or login class?

I searched for some tutorials and examples but every single one used a different method so I wasn't so sure as to which one to use.
Do you think you can help point me in the right direction?
thanks

Posted: Tue Apr 12, 2005 3:45 am
by Maugrim_The_Reaper
You need to grab some examples...

Using sessions, you can authenticate the player and set a checking variable like $_SESSION['authenticated'] = 1. There is no need to store passwords or anything else in a cookie.

In your app - to ensure a user is logged in, just check that $_SESSION['authenticated'] is a) set, b) equal to 1.

There's a lot more obviously, but this is the basic idea.

Posted: Tue Apr 12, 2005 8:35 pm
by pella.d
http://www.devshed.com/c/a/PHP/Creating ... in-Script/

So from reading, this one sounds secure, and seems to do what you guys have pointed out
but i have a question about some of the code.

Code: Select all

PEAR::setErrorHandling(PEAR_ERROR_DIE);
Now It says its pointing to a PEAR object, but what is a pear object? Will this work be default or while I need to somehow install some 3rd party pear object thing.
Theres a few other things I'm not too familiar with, like these:

Code: Select all

$dsn = "mysql://$db_user:$db_pass@unix+$db_host/$db_name";
$db = DB::connect($dsn);
im guessing that this is just some other way to connect to the database? Will this work by default also, I'm not sure how much access I have to manipulate the server.
If anyone knows of a better script, by all means.

Posted: Tue Apr 19, 2005 4:24 pm
by nickclarkson
PEAR is a "framework and distribution system for reusable PHP components." (from http://pear.php.net). It's basically a framework consisting of various classes of functions that perform different tasks, e.g. database-related, forms-related etc..I'm no expert, but take a look at the official site if you have the time.

The code you posted is just the PEAR method of connecting to a mysql database. The same can be performed in 'regular' php;

e.g. $link=mysql_connect($db_host, $db_user, $db_pass);

It will mean that you will have to have PEAR on your web server of course, something that I've almost always had problems getting to work myself, but that's probably cos I'm stupid :) but again, see the official page for how to do that (assuming you have access to your server).

Good luck,

Nick

Posted: Tue Apr 19, 2005 10:11 pm
by kantissa
Maugrim_The_Reaper wrote:
Using sessions, you can authenticate the player and set a checking variable like $_SESSION['authenticated'] = 1. There is no need to store passwords or anything else in a cookie.

In your app - to ensure a user is logged in, just check that $_SESSION['authenticated'] is a) set, b) equal to 1.
Correct me if I'm wrong but isn't is possible to start a session in other website and set $_SESSION['authenticated'] = 1 and now enter to this website and what you know, you are already authenticated. This of course would need that someone already knows a part of the original code in order to set this $_SESSION['authenticated'].

This leads to another question, considering that the above is correct. If I have username and password to the website which uses sessions for authentication/identification and I successfully log in (so $_SESSION['authenticated'] = 1 is set) and then directly enter to some other website and use print_r($_SESSION) to find out everything about the session varibles. Now I will have the information about this $_SESSION['authenticated'] and maybe some other information too ($_SESSION['userlevel'] = 3 or something similar).

So the question finally. What could I do to avoid this to happen?

The chances for this to happen is probably low (especially on private websites) but I am interested to know if there is something that can be done for this. Or should I not rely on sessions and use some other techniques for authentication?

Posted: Tue Apr 19, 2005 11:35 pm
by feyd
session variables are stored on the server. Not in the browser. Only the client's session ID is (partly) kept in the browser.

Posted: Thu Apr 21, 2005 4:57 am
by kantissa
Seems i have got something wrong, which in this case is good. Now I tried two things.

1. example1.com, login and then click on to a page in example1.com which has print_r($_SESSION) which gives out something like following

Array ( [username] => kantissa [user_level] => 1 )

This is the situation I was referring earlier. But now i tried this

2. example1.com, login and then click to a page in example2.com to see if I could print out the information again but result was just empty.

Array ( )

And this relieves me. I got it wrong in the first place but now I undertand it better. So I guess session is pretty safe way anyway to save the information, right? But how about this situation in shared hosting places? If I got it right, then the session data is saved in /tmp, so is it same /tmp for all users in the shared hosting place or is there somekind of separation between the users. I don't two have domains in one shared place so I can't try it...

Anyway, thanks for clearing me up.

Posted: Thu Apr 21, 2005 8:44 pm
by bobsta63
Session variables are stored on the server mate.

Posted: Tue May 31, 2005 9:52 pm
by hanji
Hello

I know I'm jumping late into this thread.. but would like to see some more 'chatter' in the security forum.

Code: Select all

$qstr = "SELECT username, password FROM members WHERE username = '".$username."' and password = '".$password."'";
$result = mysql_query($qstr);
if (mysql_num_rows($result)) {
    setcookie("username", $username,0,"/");
    setcookie("password", $password,0,"/");
} else { 
    include 'login.php';
    exit();
}
I have a couple of problems with this bit a code.

Problem #1
Using clear passwords.. this is already mentioned above. Use a md5 crypt.. and compare the crypt value.

Problem #2

Code: Select all

if (mysql_num_rows($result)) {
I see that we're wrapping our input values with a safeString() function.. and doing a 'addslashes()'. I'm glad that there is some input sanitation.. but is it enough to stop SQLInjection? Maybe.. maybe not. The problem to me is that we're just checking for a recordcount for a pass or fail action. All you need to do is trick the query (trick is unknown) to give a record or records back to the condition. I would add another layer of security.. basically comparing values... This example uses the 'clear' password example for simplicity.

Code: Select all

$qstr = "SELECT username, password FROM members WHERE username = '".$username."' and password = '".$password."'";
$result = mysql_query($qstr);
$passFlag = false;
if (mysql_num_rows($result)) {
	$db_username	= mysql_result($result,0,'username');
	$db_password	= mysql_result($result,0,'password');	
	if($db_password == trim($password) && $db_username == trim($username)){
		$passFlag	= true;
	}
}
mysql_free_result($result)

if($passFlag){
	// set up authentication
}else{
	include 'login.php';
	exit();
}
Problem #3

Code: Select all

setcookie("username", $username,0,"/");
setcookie("password", $password,0,"/");
Why are you storing username and password in the cookie? I would go with session and set a 'isAuthenticated' boolean or value.. and check that. Putting those values in a cookie is potentially dangerous with XSS (Cross Site Scripting). If someone is able to steal your cookies.. they would have:
1. The Domain of where the cookie was written
2. The Username
3. The Password

Granted if someone stole your cookie and you were using Sessions. they would be able to hijack your session, but you could put checks to help prevent that (ie: check useragent, IP, etc).

You could store information in the cookie.. and encrypt it using PHP's mcrypt functions as well to tighten things up.

I think a thread like this is great to open up conversations of securing our code. I would like to hear other's ideas on how to implement a 'tighter' grip on logins, etc.

hanji