PDA

View Full Version : PHP Sessions and Password Salting



Hitman
24-11-2007, 11:39 AM
Hey :)

I used to know quite a reasonal amount of PHP but then I was away from the computer for over 6 months. Therefore, I've forgotten alot but I'm trying to get back into PHP coding by writing little scripts (news script, forum etc...)

Something I didn't learn though, was how to use sessions (secure) and salting passwords (and with md5 encryption).

First I'll talk about the sessions. I don't know much about them in terms of coding. Could anybody post/make a code that enables the session, disables it and what you need on a page to be able to see it with your session. And explain how it works! :D

Now for salting, I don't know much about this. What is the code for salting the password? And then for somebody logging in, how would be do this? I saw this:



<?php md5($salt . $password); ?>


What do we put as the $salt variable? Anything? Like 0@i99SK03#s or does it have to change each time? I wouldn't think so because if your pass is hello and it has the salt it'll be 0@i99SK03#shello in md5 which would take forever to decrypt. Somebody explain about this too!

Thanks to anybody that replies with good info, I will +rep!

Invent
24-11-2007, 01:05 PM
In a database you have 2 columns, one containing the salted md5 hash and in the other column the salt.

Then when someone enters a password it does:



<?php

$query = mysql_query( "SELECT `password`, `salt` FROM `table` WHERE `username` = '".$username."'" );

$rows = mysql_fetch_array( $query );

$encrypted = md5( $password . $rows["salt"] );

if( $encrypted == $rows["password"] )
{

# Correct

}
else
{

# Incorrect

}

?>


As for sessions to start a session you do:



<?php

session_start();

?>


This tells apache/php to enable sessions.

To set a session you do:


<?php

session_start();

$_SESSION["session_var"] = "Whatever";

?>


To remove ONE session you do:


<?php

session_start();

$_SESSION["session_var"] = "Whatever";

unset($_SESSION["session_var"]);

?>


This will destroy that one php session and keep the rest intact.

To destroy ALL sessions you do:



<?php

session_start();

$_SESSION["session_var"] = "Whatever";

unset($_SESSION["session_var"]);

session_destroy();

?>


This ends ALL of the sessions.

Hitman
24-11-2007, 02:36 PM
Thanks VERY much Invent, the info you've given me is great! :D +rep!

So, for login if the password was correct and matches the DB you'd put:

$_SESSION["session_var"] = "Whatever";

How does it check the session? Like on a member page only, how does it know if you've got it or not? Is that all in the session_start();?

EDIT: Must spread rep. >_>

What would you set as the salt? Can you choose random things yourself or what?

RYANNNNN
24-11-2007, 03:53 PM
For the checking the session,

if(isset($_SESSION['id'])) {
// logged in
} else {
// logged out
}

Hitman
24-11-2007, 04:15 PM
Thanks! :)

BTW, Invent or Ryan I need some more help!

On the registration, what code would I use for doing the salt and the password? For making the salt then encrypting it or whatever?

Beau
24-11-2007, 09:42 PM
Do you mean generating a random salt?



function generate_random_string() {
$chars='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP QRSTUVWXYZ0123456789`~!@#$%^&*()_+{}|\-=[]\:",./<>?';

$string = NULL;

for($i = 0; $i <= 4; $i++) {

$string .= $chars[rand(0,strlen($chars)-1)];

}

return $string;

}
That will generate a 5 character random string.

For hashing the password (you're not encrypting it, encrypting generally means you can decrypt it easily, which you generally don't want to do with passwords), just use MD5.



$encrypted_password = md5($salt . $password);

Hitman
24-11-2007, 11:11 PM
Wow, thanks man!

Keep watching this space I may need more help! :P

+rep!

Hitman
24-11-2007, 11:34 PM
I can't edit, but when generating a string it doesn't work. It doesn't come up with anything. o.o; Is it the $string = NULL; that is causing nothing?

Also, what would the var be for $encrypted_password = md5($salt . $password); wouldn't it be $string? Or if I did $salt = $string; ?

I see how it works now, before I didn't.

The salt is added onto the beginning of the pass, so say if the salt is 3$@93k$$%" then the pass is hello1 the whole thing being md5 encypted and stored in the db is 3$@93k$$%"hello1 which is almost impossible to decrypt. Thanks again! ^^

EDIT AGAIN: Bah I've not done it right! Help! :P

Beau
25-11-2007, 03:05 AM
Have the function code above, then have this:




$salt = generate_random_string();

$encrypted_password = md5($salt . $password);



Should work.

Hitman
25-11-2007, 03:16 AM
Yes, it now works! The salt is now being made and going into the db! :D

A question: How do I make the length 8?
And a problem, I've made a simple login. Doesn't work, here's the error:


Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /home/belite/public_html/news/login.php on line 9Here's the code!


<?php
session_start();
include 'config.php';
$username = $_POST[username];
$password = $_POST[password];
if ($_POST['submit']) {
$query = mysql_query( "SELECT `password`, `salt`, FROM `users` WHERE `username` = '".$username."'" );

$rows = mysql_fetch_array( $query );

$encrypted = md5( $password . $rows["salt"] );

if( $encrypted == $rows["password"] )
{
$_SESSION["$username.$encrypted"] = "logged";
echo "Correct password!";

}
else
{

echo "Incorrect password.";

}
}
if (!$_POST['submit']) {

}
echo "
<form action=\"login.php\" method=\"POST\">
Username: <input type=\"text\" size=\"30\" name=\"username\"></br>
Password: <input type=\"password\" size=\"20\" name=\"password\"></br>
<input type=\"submit\" value=\"Login!\" name=\"submit\">
";

?>
The session thing is also, errr, not good.

$_SESSION["$username.$encrypted"] = "logged";

what would go there...? I've put those vars so it's hard to guess the session id. Is that done correctly (don't think so).

Beau
25-11-2007, 10:23 AM
1) Change



$query = mysql_query( "SELECT `password`, `salt`, FROM `users` WHERE `username` = '".$username."'" );


To



$query = mysql_query( "SELECT `password`, `salt` FROM `users` WHERE `username` = '".$username."'" );


You're right, you have done that wrong :P Don't worry about anyone guessing the name to your session. Even if they know it, they won't be able to do anything with it, as it's all server side. Unless you're going to be doing stuff with sessions in the database, I wouldn't bother with a complex logged in session.

Hitman
25-11-2007, 01:29 PM
Yes! It's fixed! ^^; Thanks! No error, but now something else has decided to not work.

I type the correct password in for the username, and it comes up with "Incorrect password."

Here's the code:



<?php
session_start();
include 'config.php';
$username = $_POST[username];
$password = $_POST[password];
if ($_POST['submit']) {
$query = mysql_query( "SELECT `password`, `salt` FROM `users` WHERE `username` = '".$username."'" );

$rows = mysql_fetch_array( $query );

$encrypted = md5($password . $rows["salt"] );

if( $encrypted == $rows["password"] )
{
echo "Correct password!";
$_SESSION["logged"] = "logged";

}
else
{

echo "Incorrect password.";

}
} else {
if (!$_POST['submit']) {

echo "
<form action=\"login.php\" method=\"POST\">
Username: <input type=\"text\" size=\"30\" name=\"username\"></br>
Password: <input type=\"password\" size=\"20\" name=\"password\"></br>
<input type=\"submit\" value=\"Login!\" name=\"submit\">
";
}
}
?>

Without your help, Beau, I wouldn't be going anywhere. :P

Hitman
25-11-2007, 02:45 PM
Can't edit but I fixed it!

Now I may have a problem with sessions, 2 secs.

Yeah, with sessions I think I have a problem.

When I login I get a session, and it's content is random numbers and letters. Even if you get the pass wrong you get a session. The session name is PHPSESSID hmm?



<?php
session_start();
include 'config.php';
$username = $_POST[username];
$password = $_POST[password];
if ($_POST['submit']) {
$query = mysql_query( "SELECT `salt`, `password` FROM `users` WHERE `username` = '".$username."'" );

$rows = mysql_fetch_array( $query );

$encrypted = md5($rows["salt"] . $password );

if( $encrypted == $rows["password"] )
{
echo "Correct password!";
$_SESSION["logged"] = "logged";

}
else
{

echo "Incorrect password.";

}
} else {
if (!$_POST['submit']) {

echo "
<form action=\"login.php\" method=\"POST\">
Username: <input type=\"text\" size=\"30\" name=\"username\"></br>
Password: <input type=\"password\" size=\"20\" name=\"password\"></br>
<input type=\"submit\" value=\"Login!\" name=\"submit\">
";
}
}
?>
That's login.php

Hmm, not sure what's going on.

Beau, I need your good help again! :P

Hitman
25-11-2007, 03:21 PM
* CANT EDIT *

I've fixed it, it's allllll working fine! :D

Beau
26-11-2007, 05:33 AM
Oh good :P Just so you know, PHPSESSID a cookie that is made automatically, that holds your session id. You can rename it, but you can't delete it :P

Hitman
26-11-2007, 03:09 PM
:D Woot, thanks for all your help you're the PHP man. :P

I have one tiny problem, I've made a change pass - I'm not sure what's wrong. :S



<?php
session_start();
include 'config.php';
if ($_SESSION['logged_user'] == true) {
if ($_POST['submit']){
$query = mysql_query("SELECT `salt` FROM `users` WHERE `username` = '".$_SESSION['logged_user']."'");

$rows = mysql_fetch_array( $query );

$encrypted_pass = md5($rows['salt'] . $_POST['password'] );

$query = mysql_query("UPDATE `users` SET `password` = '$encrypted_pass' WHERE `username` = '".$_SESSION['logged_user']."'");

echo "Updated!";
}
}
if ($_SESSION['logged_user'] == false) {
echo "Not logged in!";
} else {
if (!$_POST['submit']){

echo "<form action=\"edit.php\" method=\"POST\"><b>Edit your profile!</b></br></br>Edit password: <input type=\"password\" size=\"20\"><input type=\"submit\" name=\"submit\" value=\"Change!\">";
}
}
?>


It encrypts the password and does something - but it isn't correct.

Mentor
26-11-2007, 03:30 PM
Salting or peppering your md5s is basicly there to stop people useing google to get a pass from the hash.

Basiicly the idea works, becuse alot of wana be hackers write write down the pass that produce certain hashes, then when u google a hash, it can often come up with the assoiated pass. if you salt it, aka add a few charcs before the pass within the hash calcualtion, what you actualy get is saltPassword being hashed, so when an md5 is run, the pass its assoaited with is likley not the pass needed to be entered in order to gain access to the account. A more random hash can be created using the time the registed or some other unchanging value, since then each users pass salting will be differnt adding yet another layer of protection :)

Hitman
26-11-2007, 04:20 PM
Oh boy, I'm a proper noob. LOL. Why you ask? I forgot the name=\"password\" on the form so it was sending the salt only.

Haha, it's all good now. :D Change pass works! :D

Dentafrice,
26-11-2007, 08:57 PM
Oh boy, I'm a proper noob. LOL. Why you ask? I forgot the name=\"password\" on the form so it was sending the salt only.

Haha, it's all good now. :D Change pass works! :D
Thats good :) You seem to be learning fast.

Need help on anything else?

Hitman
26-11-2007, 09:17 PM
Hi Dentafrice!

I have one problem... I've made a page to see all users, with their info like email etc... It only shows my info, not anybody elses... hmm.

Code.



<?php
session_start();
include 'config.php';
if ($_SESSION['logged_user'] == true) {

$query = mysql_query("SELECT `level` FROM `users` WHERE `username` = '".$_SESSION['logged_user']."'");

$rows = mysql_fetch_array( $query );


if ($rows['level'] == 5) {

$query = mysql_query("SELECT * FROM `users`");

$rows = mysql_fetch_array($query2);

echo "Username: ".$rows['username']."</br></br> Email: ".$rows['email']."</br></br>Join date: ".$rows['date']."</BR></BR>Signature: ".$rows['signature']."";

} else {
echo "Don't try and get where you shouldn't be...";
}
}
if ($_SESSION['logged_user'] == false) {
echo "Not logged in. Redirecting... <meta http-equiv=\"REFRESH\" content=\"1;url=./login.php\">";
}
?>


I can't see anything wrong... :( I will learn to spot mistakes though xD

Dentafrice,
26-11-2007, 10:44 PM
Hi Dentafrice!

I have one problem... I've made a page to see all users, with their info like email etc... It only shows my info, not anybody elses... hmm.

Code.



<?php
session_start();
include 'config.php';
if ($_SESSION['logged_user'] == true) {

$query = mysql_query("SELECT `level` FROM `users` WHERE `username` = '".$_SESSION['logged_user']."'");

$rows = mysql_fetch_array( $query );


if ($rows['level'] == 5) {

$query = mysql_query("SELECT * FROM `users`");

$rows = mysql_fetch_array($query2);

echo "Username: ".$rows['username']."</br></br> Email: ".$rows['email']."</br></br>Join date: ".$rows['date']."</BR></BR>Signature: ".$rows['signature']."";

} else {
echo "Don't try and get where you shouldn't be...";
}
}
if ($_SESSION['logged_user'] == false) {
echo "Not logged in. Redirecting... <meta http-equiv=\"REFRESH\" content=\"1;url=./login.php\">";
}
?>
I can't see anything wrong... :( I will learn to spot mistakes though xD


<?php
session_start();
include 'config.php';
if ($_SESSION['logged_user'] == true) {

$query = mysql_query("SELECT `level` FROM `users` WHERE `username` = '".$_SESSION['logged_user']."'");

$rows = mysql_fetch_array( $query );


if ($rows['level'] == 5) {

$query = mysql_query("SELECT * FROM `users`");

while($rows = mysql_fetch_array($query2)) {

echo "Username: ".$rows['username']."</br></br> Email: ".$rows['email']."</br></br>Join date: ".$rows['date']."</BR></BR>Signature: ".$rows['signature']."";
}
} else {
echo "Don't try and get where you shouldn't be...";
}
}
if ($_SESSION['logged_user'] == false) {
echo "Not logged in. Redirecting... <meta http-equiv=\"REFRESH\" content=\"1;url=./login.php\">";
}
?>

Beau
27-11-2007, 05:11 AM
Actually, I think it should be this:



<?php
session_start();
include 'config.php';
if ($_SESSION['logged_user'] == true) {

$query = mysql_query("SELECT `level` FROM `users` WHERE `username` = '".$_SESSION['logged_user']."'");

$rows = mysql_fetch_array( $query );


if ($rows['level'] == 5) {

$query = mysql_query("SELECT * FROM `users`");

while($rows = mysql_fetch_array($query)) {

echo "Username: ".$rows['username']."</br></br> Email: ".$rows['email']."</br></br>Join date: ".$rows['date']."</BR></BR>Signature: ".$rows['signature']."";
}
} else {
echo "Don't try and get where you shouldn't be...";
}
}
if ($_SESSION['logged_user'] == false) {
echo "Not logged in. Redirecting... <meta http-equiv=\"REFRESH\" content=\"1;url=./login.php\">";
}
?>

Hitman
27-11-2007, 05:53 AM
Thanks guys, I know why query2 is there because I was playing around with the querys. :P

Invent
27-11-2007, 06:38 AM
Bored. Bored. Bored.



<?php

session_start();
include('config.php');

if (isset($_SESSION['logged_user']))
{

$query_code = "SELECT `level` FROM `users` WHERE `username` = '".$_SESSION['logged_user']."'"; // Defines the query

$query = mysql_query( $query_code ) or die("Could not perform SQL Query, error: ".mysql_error()); // Executes the query

$rows = mysql_fetch_array( $query ) or die("Could not perform SQL Query, error: ".mysql_error()); // Grabs the relevent SQL Data from the query


if($rows['level'] === 5)
{

$query_code = "SELECT * FROM `users`"; // Defines the query
$query = mysql_query( $query_code ) or die("Could not perform SQL Query, error: ".mysql_error()); // Executes the query

while($rows = mysql_fetch_array($query))
{

echo("Username: ".$rows['username']."</br></br> Email: ".$rows['email']."</br></br>Join date: ".$rows['date']."</BR></BR>Signature: ".$rows['signature']);

}

}
else
{
echo("Don't try and get where you shouldn't be...");
}

}

if (!isset($_SESSION['logged_user'])) // Could've been simpler by doing an elseif statement, but whatever.
{

echo("Not logged in. Redirecting... <meta http-equiv=\"REFRESH\" content=\"1;url=./login.php\">");

}

?>

Want to hide these adverts? Register an account for free!