A better design for authorization/authentication

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
phpwalker
Forum Commoner
Posts: 81
Joined: Sun Apr 23, 2006 12:18 pm

A better design for authorization/authentication

Post by phpwalker »

feyd | Please use

Code: Select all

,

Code: Select all

and [syntax="..."] tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read:  [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url] to learn how to do it too.[/color]


Hi, I'm new here. Hope I'm not posting in the wrong area.

I just started to code in php in 2 weeks time(so am just a newbie), hope can learn more from creating a member site. 

Installed php 4.4.2 and mysql 4.1.X on my machine. Trying to approach older version of php first, coz php 5 is quite tough for a newbie like me now.

So, back to the topic. What I've created on my localhost are register.php, login.php, auth.php, result.php, main.php, user.php, connect.php, install.php, header.php. Hopefully the name tells what are the files containing.

I hope I can list down all my questions before showing all of my codes here.

----------------------------------------------------------------------------------------------------

For login.php
1)Do I need to set session or unset_session() in this page? Or no need? 
2)What if a person is logged in, and he visits login.php, what should I do?
3)Is a client side validation for input required in this particular page? eg Javascript.
4)other than user and pw field, what else should I implement on this login page?

----------------------------------------------------------------------------------------------------

For auth.php (This is the page that process the login.php inputs and output the result.)

Code: Select all

<?php
include 'connect.php';

if(isset($_POST['submit'])){
    $player=$_POST['userid'];
    $password=$_POST['password'];
    $player=strip_tags($player);
    $password=md5($password);
    $query = "select * from gm_users where playername='$player' and password='$password'";
    $result = mysql_query($query) or die("Takda orang ini!") ;
    $result2=mysql_fetch_array($result);
    if($result2)
    {
       session_start();
       $_SESSION['player']=$player;
       //header("Location: http://localhost/web/test/user.php");
       echo '<meta http-equiv="refresh" content="2;url=http://localhost/web/test/user.php" />';
       include 'header.php';
       print "Logged in successfully<br>";
       print "If the browser doesn't redirect, click on ";
       print "<A href='user.php'>User Panel</a>";
       exit();
    }
    else
    {
       include 'header.php';
       print "Wrong username or password or non-activated account.<br />";
       print 'Go back <a href="login.php">login</a> or <a href="main.php">main</a>';
    }
}else{
    include 'header.php';
  //echo "nothing here";
}
?>
1)Can I use include like this? header and connect as well.
2)Should I use meta redirect or Header()?
3)I register using this name '<b>a</b>', it viewed username as 'a' but I can login using '<b>a</b>' or 'a'. Should I use strip_tags in this case? I know there are htmlspecialchars(), preg_replace(), eregi_replace(), htmlentities() out there, I don't quite know when to use them. Could anyone briefly explain each of them and give me some simple examples?
----------------------------------------------------------------------------------------------------

For result.php(process output of register.php)
1)I don't quite know the flow of checking the inputs, hope someone can guide me bout this. But this is what I coded:

Code: Select all

if(password==password2){
   if(!password || !password2)
      //show error no password enter 
   elseif(username>15 ||username<3||username was taken|| !username)
      //show error
   else{
      //md5(password)
      //input data into db
     //session_start();
     //redirect to user.php
     }
}
else
  //show error of password not match
----------------------------------------------------------------------------------------------------
I think I'm writing too much in one post. I'll continue to ask for the next post. Hope I can get some guidances here. Thanks in advance!


feyd | Please use

Code: Select all

,

Code: Select all

and [syntax="..."] tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read:  [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url] to learn how to do it too.[/color]
Last edited by phpwalker on Sun Apr 23, 2006 1:23 pm, edited 1 time in total.
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Re: A better design for authorization/authentication

Post by timvw »

phpwalker wrote: Installed php 4.4.2 and mysql 4.1.X on my machine. Trying to approach older version of php first, coz php 5 is quite tough for a newbie like me now.
Could you elaborate a bit? I thougt everything that almost everything just remained working (apart from the mysql(i) extension that isn't enabled by default anymore)
phpwalker wrote: 1)Do I need to set session or unset_session() in this page? Or no need?
If you are changing the "access level" it's advised to use http://www.php.net/session_regenerate_id in order to prevent session injection attacks (or whatever ppl name that technique).
phpwalker wrote: 2)What if a person is logged in, and he visits login.php, what should I do?
What do you want to do?
phpwalker wrote: 3)Is a client side validation for input required in this particular page? eg Javascript.
Client side validation is a bonus. First make it work on the server-side. Afterwards you can add all the fancy (but not reliable) extra stuff to improve the user experience.
phpwalker wrote: 4)other than user and pw field, what else should I implement on this login page?
What else do you need?
phpwalker wrote:

Code: Select all

$query = "select * from gm_users where playername='$player' and password='$password'";
Despite the fact that you've stripped slashes and used md5 on the data, you've not explicitely prepared the data for use in a (my) sql query: http://www.php.net/mysql_escape_string.
phpwalker wrote:

Code: Select all

//header("Location: http://localhost/web/test/user.php");
If you were planning to do this, make sure to call http://www.php.net/session_write_close first.
phpwalker wrote: 2)Should I use meta redirect or Header()?
Long ago there were browsers that didn't understand the header redirection, but i wonder if there are still browsers out there that really suffer from this problem.
phpwalker wrote: 3)I register using this name '<b>a</b>', it can pass through without any warning. There weren't any problem of viewing the name and no error occured. Only thing is the name changed to 'a' afterall. Someone can tell me what happen?
If you're going to use user-data in your html, prepare it first, just like you have to prepare data for use in a sql query, with an appropriate function. In this case it would be: http://www.php.net/htmlentities.
phpwalker
Forum Commoner
Posts: 81
Joined: Sun Apr 23, 2006 12:18 pm

Post by phpwalker »

First of all, sorry for not using the php-tag. When I realized that, mod has already helped me to changed it, you are so fast, thanks and sorry again.

timvw, thanks for your fast reply.
timvw wrote: Could you elaborate a bit? I thougt everything that almost everything just remained working (apart from the mysql(i) extension that isn't enabled by default anymore)
Er, I thought there is a lot of changes in php5 engines. Such as some functions can or cannot be used in latest php version.
timvw wrote: What do you want to do?
Can I redirect him to index? Which means I need to start a session in login page first? I don't know the theory of this, can you provide me a sample?
timvw wrote: Client side validation is a bonus. First make it work on the server-side. Afterwards you can add all the fancy (but not reliable) extra stuff to improve the user experience.
I see. So this would be a later job.
timvw wrote: What else do you need?
Such as confirmation code? Can prevent brute-forcing? However, I don't know how to code this, would make it for last task.

For the moment, I think I would have to study more on the php manual that you provided first. Once again, thanks a lot for your helps.
phpwalker
Forum Commoner
Posts: 81
Joined: Sun Apr 23, 2006 12:18 pm

Post by phpwalker »

Hi, is me again. I've read about the htmlentities explaination, and try the code in my localhost.

I copied from php manual:

Code: Select all

<?php
$str = "A 'quote' is <b>bold</b>";

// Outputs: A 'quote' is <b>bold</b>
echo htmlentities($str);

// Outputs: A 'quote' is <b>bold</b>
echo htmlentities($str, ENT_QUOTES);

?>
It outputs:

Code: Select all

A 'quote' is <b>bold</b> A 'quote' is <b>bold</b>

What's wrong with it?

Code: Select all

<?php
$new = htmlspecialchars("<a href='test'>Test</a>", ENT_QUOTES);
echo $new; // <a href='test'>Test</a>
?>
The above also giving me output:

Code: Select all

<a href='test'>Test</a>
---------------------------------------------------------------------------------------------------
I read the session_regenerate_id -- Update the current session id with a newly generated one. Why do I need to update the session id? What's the purpose of doing so? When do I need to use it? Is it between the login page and protected pages?

Furthermore, I use fopen, fwrite and fclose, it give me output of this. Is it I didn't chmod the messages.txt? If I don't have ftp on my localhost, how do i chmod it as I'm winxp user? I knew that chmod is a command in linux and unix, but... I don't know how to use linux, *sad*...

Code: Select all

Warning: fopen(./messages.txt): failed to open stream: Permission denied in C:\web\token\session_token.php on line 11

Warning: fwrite(): supplied argument is not a valid stream resource in C:\web\token\session_token.php on line 12

Warning: fclose(): supplied argument is not a valid stream resource in C:\web\token\session_token.php on line 13

I tried

Code: Select all

<?php
chmod("/token/messages.txt", 0666);  // octal; correct value of mode
?>
Out put:

Code: Select all

Warning: chmod(): Permission denied in C:\web\chmoddy.php on line 2
Can someone tell me what to do? Sorry for asking so many questions again.
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post by Maugrim_The_Reaper »

What's wrong with it?
Check the Source view of the output - it should contain the entities not the literal characters. ;) It's also nce to specify a character encoding for htmlentities like UTF-8 to cover potential character encoding hacks. htmlspecialchars() while often recommended is not as exhaustive as htmlentities() when it comes to escaping.
I read the session_regenerate_id -- Update the current session id with a newly generated one. Why do I need to update the session id? What's the purpose of doing so? When do I need to use it? Is it between the login page and protected pages?
There is a risk that some enterprising hacker may be capable of stealing session ids. To prevent such hanger-ons from gaining your authorisation rights whenever you login, or switch authorisation levels, it is recommended you replace the session id whenever a login or authorisation level change is being made. This makes the hacker's current copy of your session id invalid and inconveniences them. Some recommend switching session_ids on a random or constant basis, but it honestly little more security.
Furthermore, I use fopen, fwrite and fclose, it give me output of this. Is it I didn't chmod the messages.txt? If I don't have ftp on my localhost, how do i chmod it as I'm winxp user? I knew that chmod is a command in linux and unix, but... I don't know how to use linux, *sad*...
Need more detail - where's the file? On your PC or on a remote server? Is it chmodded correctly (read up on unix file permissions before you do anything else!)? Windows does not have unix permissions - most of the time it's either writeable/readable or read-only or may have some user specific permissions (seldom used on home PCs in my experience). Test the file before attemting file operations with is_readable() and is_writeable() and similar to catch errors and more info about its permission state.
phpwalker
Forum Commoner
Posts: 81
Joined: Sun Apr 23, 2006 12:18 pm

Post by phpwalker »

Maugrim_The_Reaper wrote: Check the Source view of the output - it should contain the entities not the literal characters. It's also nce to specify a character encoding for htmlentities like UTF-8 to cover potential character encoding hacks. htmlspecialchars() while often recommended is not as exhaustive as htmlentities() when it comes to escaping.
Ah, I see, should look into the source code. :oops: Character encoding means they can input <script> in UTF-8 and use javascript to exploit into my system isn't it? Sorry for asking stupid question here, as I am really new in php.

I try the is_writable:

Code: Select all

<?php
$filename = '/token/messages.txt';
if (is_writable($filename)) {
   echo 'The file is writable';
} else {
   echo 'The file is not writable';
}
?>
output:

Code: Select all

The file is not writable
Except chmod from ftp, what else can do in windows to change the file permission? If not downloading any tools, what can do to change the permission in window xp?
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

Maugrim_The_Reaper wrote:
What's wrong with it?
Check the Source view of the output - it should contain the entities not the literal characters. ;) It's also nce to specify a character encoding for htmlentities like UTF-8 to cover potential character encoding hacks. htmlspecialchars() while often recommended is not as exhaustive as htmlentities() when it comes to escaping.
I read the session_regenerate_id -- Update the current session id with a newly generated one. Why do I need to update the session id? What's the purpose of doing so? When do I need to use it? Is it between the login page and protected pages?
There is a risk that some enterprising hacker may be capable of stealing session ids. To prevent such hanger-ons from gaining your authorisation rights whenever you login, or switch authorisation levels, it is recommended you replace the session id whenever a login or authorisation level change is being made. This makes the hacker's current copy of your session id invalid and inconveniences them. Some recommend switching session_ids on a random or constant basis, but it honestly little more security.
He doesn't have to steal them... Just imagine that he has a link on his site http://victim.example.com?PHPSESSID=666.. And you use that link and logon... Now he knows your session id too ;)
phpwalker
Forum Commoner
Posts: 81
Joined: Sun Apr 23, 2006 12:18 pm

Post by phpwalker »

timvw wrote:
He doesn't have to steal them... Just imagine that he has a link on his site http://victim.example.com?PHPSESSID=666.. And you use that link and logon... Now he knows your session id too ;)
I've read the flicr case study in PDF, it says that they aren't using session in php. So what are they going to use? The cookies? I'm wondering that using cookies is better than session?
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Post by s.dot »

phpwalker wrote:
timvw wrote:
He doesn't have to steal them... Just imagine that he has a link on his site http://victim.example.com?PHPSESSID=666.. And you use that link and logon... Now he knows your session id too ;)
I've read the flicr case study in PDF, it says that they aren't using session in php. So what are they going to use? The cookies? I'm wondering that using cookies is better than session?
It's a personal preference. Some would say sessions are more secure. Others would argue that cookies are just as secure when authenticated properly.

Either way you should check the cookie/session against the database on each page load... at least that's what I do.
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

Basically, cookies are at least as secure as session. (as long as you validate the data)

The problem is that sessions also can work via sessionid's appended to the url or added as hidden field in a form.. Which (can) allow outside users to 'inject' their own sessionid..
Last edited by timvw on Thu Apr 27, 2006 3:23 am, edited 1 time in total.
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

I have read the slides (Apart from the masterdb with innodb engine and the replicas using myisam there wasn't much interesting stuff in them)

It's not described anywhere, but i'm pretty sure they decided not to uses sessions because in that case they have to store all the 'session/cookie data' at the server side instead of at the user-side... (basically, only validating the data the user presents scales much better than storing the data yourself and making it available to all your servers...)
Post Reply