Page 1 of 1

Access Security Problem

Posted: Fri Jul 09, 2004 1:23 am
by AGISB
Hi

for a bigger project I am programming an access control. The access is checked against a MySQL table with User_ID, Nickname and password. After this the status (inactive, cancelled, deleted etc.) is checked and the user gets forwarded to the appropriate page and different memberships (e.g. Newsletter, Webmaster) are forwarded to their pages as well. Only an active member will see the page html without being forwarded. The below code is a file that will be included in all member php pages. It works but as I am pretty new to php I am not sure about any security risks I introduce when implementing this solution. Do I e.g. have to filter any possible mailcious code form the http-authentication ?
Any suggestions on what to make better are appreciated as well. (Error handling will of course be different in the final version)

Thanks

authent.inc

Code: Select all

<?php
function connect()
{
mysql_connect("localhost", "user", "pass") or die("No connection to SQL server");
mysql_select_db("test") or die("Can't select database: ".mysql_error() . ") ");
}
//Authentifzierung starten
function authenticate()
{
Header("WWW-authenticate: basic realm="Test"");
Header("HTTP/1.0 401 Unauthorized");
echo "No Access";
exit;
}
function verify_user($user, $pass)
{
$pw_querystring ="select * from userdata where User_ID='$user' or Nickname='$user' and passwd=password('$pass')";
$result = mysql_query($pw_querystring);
if (!$result) die("<br><b>$PHP_SELF</b>: ".mysql_error());
else if(!mysql_num_rows($result)) authenticate();
else return $result;
} 
// Connect to database
//include("./db_auth.inc");
connect();
$auth_ok = 0;
$user = $_SERVER['PHP_AUTH_USER'];
$pass = $_SERVER['PHP_AUTH_PW'];
// See if $PHP_AUTH_USER exist
// on no force authenticate
if (!isset($user)) authenticate();
else {
	if ($result=verify_user($user, $pass)) {
		$querystring ="select Nickname, MSort_ID, AStatus_ID, Country_ID from Customer where Customer_ID='$user' or Nickname='$user'";
		$result1 = mysql_query($querystring);
		$row = mysql_fetch_row($result1);
		$nick = $row[0];
		$MemSort = $row[1];
		$Stat = $row[2];
		$CountryID = $row[3];
		switch ($Stat) {
			case 1:
				$auth_ok = 1;
				break;
			case 2: 
				header('Location: http://www.test.net/members/passive.php');
				exit();
				break;
			case 3: 
				header('Location: http://www.test.net/members/welcome.php');
				exit();
				break;
			case 4: 
				header('Location: http://www.test.net/members/cancelled.php');
				exit();
				break;
			case 5: 
				authenticate();
				break;
			case 6: 
				authenticate();	
				break;
			case 7: 
				header('Location: http://www.test.net/members/review.php');
				exit();
				break;
			case 8: 
				header('Location: http://www.test.net/members/fraud.php');
				exit();
				break;
			default: 
				header('Location: http://www.test.net/members/error.php');
				exit();
		}
		switch ($MemSort) {
			case 2:			
				header('Location: http://www.test.net/members/newsletter.php');
				exit();
				break;
			case 3:
				header('Location: http://www.test.net/members/webmaster.php');
				exit();
				break;
			case 4:
				header('Location: http://www.test.net/members/agent.php');
				exit();
				break;
			case 1:
			
				break;
			case 5:
			
				break;	
			default:
				header('Location: http://www.test.net/members/error.php');
				exit();
		}
	}
	else {
		authenticate();
	}
}
?>



feyd | Please use

Code: Select all

tags when posting code. Read:  [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url][/color]

Posted: Fri Jul 09, 2004 9:38 am
by pickle
I used to use this type of authentication for my CMS, until an co-worker and I found a problem. It seems that Mozilla "caches" the PHP_AUTH_USER and PHP_AUTH_PW variables. This will enable third parties to use those credentials if the primary user leaves their computer. On our system, it would break if:
  • - A user authenticates
    - Their session times out (which will pop up a new auth window upon page load).
    - They press 'Cancel' (which doesn't re-write their username and password)
    - A third party can come in, press 'Back', then 'Forward'
    - PHP_AUTH_USER and PHP_AUTH_PW exist, so PHP uses those stored values to authenticate
I can see you've got that same check:

Code: Select all

// See if $PHP_AUTH_USER exist
// on no force authenticate
if (!isset($user)) authenticate();
so you will have that same problem. Please note though that this problem can be rendered moot if you slap the hands of every user who leaves their browser window open when they leave, or if all users use IE.


Also: put your code in PHP tags, which will colour your code, rather than CODE tags.

Posted: Fri Jul 09, 2004 3:44 pm
by AGISB
Now I have a problem I cannot quite understand:

I want to make the script secure from SQL injection and I did the following to above code:

Code: Select all

<?php

connect();
$auth_ok = 0;
$user = mysql_escape_string($_SERVER['PHP_AUTH_USER']);
$pass = mysql_escape_string($_SERVER['PHP_AUTH_PW']);

?>
My querry checks against the User_ID or a Nickname and works if I tye in a nickname but if I choose to login with a user_ID < 1001'# > I get following query:

select * from userdata where User_ID='1001\\''#' or Nickname='1001\\''#' and passwd=password('')

Which lets anyone in.

Can anyone shedd light on what is happening here?