www.webdeveloper.com
Results 1 to 11 of 11

Thread: Problem with MD5

  1. #1
    Join Date
    Oct 2006
    Location
    On the web, working on my website
    Posts
    184

    Problem with MD5

    Good Afternoon! I have been tinkering around my website, trying to get this new login script to work, and have been successful until I added a note for the form to retrieve it. This is what I have so far.

    This is the Process from the Registration
    I thought it was best to keep out the registration page, because it is mega complicated and long.

    PHP Code:
    <?php

    $con 
    mysql_connect("localhost","username","password");
    if (!
    $con)
      {
      die(
    'Could not connect: ' mysql_error());
      }

    $password md5($_POST["password"]);
    $regdate date("Y-m-d");

    mysql_select_db("telpeath_ta"$con);
    $sql="INSERT INTO members (username, password, name, email, webname, url, imageurl, terms, date)
    VALUES
    ('
    $_POST[username]','".$password."','$_POST[name]','$_POST[email]','$_POST[webname]','$_POST[url]','$_POST[imageurl]','$_POST[terms]', '".$regdate."')";
    if (!
    mysql_query($sql,$con))
      {
      die(
    'Error: ' mysql_error());
      }
    header('Location: thankyou.php');
    mysql_close($con)
    ?>
    Then the Login Form:

    HTML Code:
    <form name='form1' method='post' action='checklogin.php'>
    Username:
    <input name='myusername' type='text' id='myusername'>
    &nbsp;
    &nbsp;
    Password:
    <input name='mypassword' type='password' id='mypassword'>
    &nbsp;
    &nbsp;
    <input type='submit' name='Submit' value='Login'>
    </form>
    Then the Check Login Form (This is where I believe the problem is occuring from!)

    PHP Code:
    <?php
    $host
    ="localhost"// Host name 
    $username="username"// Mysql username 
    $password="password"// Mysql password 
    $db_name="telpeath_ta"// Database name 
    $tbl_name="members"// Table name 

    // Connect to server and select databse.
    mysql_connect("$host""$username""$password")or die("cannot connect"); 
    mysql_select_db("$db_name")or die("cannot select DB");

    // username and password sent from form 
    $myusername=$_POST['myusername']; 
    $mypassword=$_POST['mypassword']; 

    // encrypt password 
    $encrypted_mypassword=md5($mypassword);

    $sql="SELECT * FROM $tbl_name WHERE username='$myusername' and password='$encrypted_mypassword'";
    $result=mysql_query($sql);

    // Mysql_num_row is counting table row
    $count=mysql_num_rows($result);
    // If result matched $myusername and $mypassword, table row must be 1 row

    if($count==1){
    // Register $myusername, $mypassword and redirect to file "login_success.php"
    session_register("myusername");
    session_register("mypassword"); 
    header("location:login_success.php");
    }
    else {
    echo 
    "Wrong Username or Password";
    }
    ?>
    Do you have any suggestions to what I am doing wrong. I thank you in advance for helping me out. I am still learning my way around PHP (Much improvement since my last trial against Login scripts, but still young).

    Thanks,

    YoungDesigner

  2. #2
    Join Date
    Nov 2008
    Posts
    2,477
    In your first script, you are inserting the MD5 hash of $_POST['password']. This doesn't exist since your password element's name is mypassword. So what you are inserting is the MD5 hash of an empty string which doesn't match in the second script where you correctly use $_POST['mypassword'].

    A few things to note:

    1. This script is wide open to SQL injection. You should be cleaning and validating all user input.
    2. You should look into using a salt for your passwords. There are dictionaries of encoded strings which an attacker can use to try to gain access to your accounts. A salt goes a very long way to preventing this.
    3. Consider using a more secure algorithm that MD5 - there are many options built into PHP which are safer and just as easy to use.
    4. You don't need to re-assign variables to other variables - it's totally pointless (yet so many people do it!)
    5. If logging someone in comes with a change in access levels (which it does 99&#37; of the time), call session_regenerate_id() to help mitigate session hijacking.

    PHP Code:
    $foo $_POST['foo']; //  <---- no point! 

  3. #3
    Join Date
    Oct 2006
    Location
    On the web, working on my website
    Posts
    184
    I am really not following. I am really new to PHP, and what you just said doesn't really make sense. Could you give examples, or give me links that would lead me to a good place? I am using the code from http://www.phpeasystep.com/workshopview.php?id=6. I understand it is old, and I have heard of this salt, but nowhere is it presented in a simple, easy, php-new friendly manner.

  4. #4
    Join Date
    Nov 2008
    Posts
    2,477
    1. SQL Injection. If I enter the following for my username:

    Code:
    admin';#
    your query now becomes:

    Code:
    SELECT * FROM yourtable WHERE username='admin';#' and password='a56b3c3ghgff32980a56b3c3ghgff32'
    Since everything after the # is treated as a comment by MySQL, I can log in as anyone just by knowing their username.


    2. Salting Passwords. This is really easy but very useful for security. Imagine if I have a dictionary of every word and common passwords (readily available), then I run that dictionary through a program which generates the MD5 hash of each word and tries each of them against a list of usernames on your site. Sooner or later I'm likely to find a weak password and be able to log in. To prevent this, you can use a salt which is just a string appended to everything before encryption:

    PHP Code:
    define('SALT''someRaNdOmStr1ng');

    $password 'password';
    $unsalted =  md5($password);
    echo 
    $unsalted// 5f4dcc3b5aa765d61d8327deb882cf99

    $salted md5(SALT $password);
    echo 
    $salted// a652f59362d9162f1df742de4a44056c 
    Now the MD5 string no longer matches the one for the plain hash of 'password', so any such attack is not going to work. You just need to remember to apply the salt every time you use encryption (you can wrap this in a function to make it easier):

    PHP Code:
    function _md5($string) {
        return 
    md5(SALT $string);
    }
    echo 
    _md5('password'); // a652f59362d9162f1df742de4a44056c 
    An even better approach is to store a unique salt for each user in the database and use that rather than an application-wide salt.


    3. A more secure algorithm. This one is really easy, just use something more secure like sha1:

    PHP Code:
    $ok md5('password');
    $better sha1('password'); 
    It's still important to use a good salt though.

    4. Reassigning Variables. I never get why people do this but it's so common. taking a few lines of your cdode as an example:

    PHP Code:
    // username and password sent from form
    $myusername=$_POST['myusername'];
    $mypassword=$_POST['mypassword'];

    // encrypt password
    $encrypted_mypassword=md5($mypassword); 

    $sql="SELECT * FROM $tbl_name WHERE username='$myusername' and password='$encrypted_mypassword'";
    $result=mysql_query($sql);

    // Mysql_num_row is counting table row
    $count=mysql_num_rows($result); 

    if(
    $count==1){ 
    You are creating unnecessary variables and complicating the code for no reason. These lines can be rewritten to:

    PHP Code:
    $_POST['mypassword'] = md5($_POST['mypassword']);
    $sql "SELECT id FROM users WHERE username='{$_POST['myusername']}' AND password='{$_POST['mypassword']}'";
    $result=mysql_query($sql);
    if (
    $result && mysql_num_rows($result) {
        
    // etc 
    and you have alot less variables to keep track of even though this code also checks that the $result is valid which the previous version did not. NB This still is not safe from SQL injection, input still needs to be filtered and cleaned.


    5. Regenerating Session Id. There are plenty of resources around on session security which explain things much better than I could so I wont attempt to go into things in great detail, but whenever someone changes authorization levels you should regenrate the ID which points to their session. If someone has managed to steal a user's session, then the user logs in and keeps the same session ID, the thief is also logged in with the user's access level. If you regenerate the ID, the session held by the theif is no longer usable. In your code, you just need to make the following modification:

    PHP Code:
    session_register("myusername");
    session_register("mypassword"); 
    becomes:

    PHP Code:
    session_regenerate_id(); // <-- this is the important bit
    // session_register is depreciated
    $_SESSION['myusername'] = $_POST['myusername'];
    $_SESSION['mypassword'] = $_POST['mypassword']; 
    Last edited by Mindzai; 05-29-2009 at 04:39 AM.

  5. #5
    Join Date
    Oct 2006
    Location
    On the web, working on my website
    Posts
    184
    Well, after a bit of research and some learning, I pulled together some scripts to create my own stylized script. However, I am seeming to have problems with my script. Care to help me find the error? I am using a SALT so that could be the problem.

    Functions.php
    PHP Code:
    <?php
    // Salt Generator
    function generate_salt ()

            
    // Declare $salt
         
    $salt '';
         
    // And create it with random chars
         
    for ($i 0$i 3$i++)
         { 
              
    $salt .= chr(rand(35126)); 
         } 
              return 
    $salt;
    }

    function 
    register($username$password)
    {
         
    // Get a salt using our function
         
    $salt generate_salt();

         
    // Now encrypt the password using that salt
         
    $encrypted md5(md5($password).$salt);
         
    // And lastly, store the information in the database
         
    $query "insert into user (username, password, name, email, webname, url, imageurl) values ('$username', '$encrypted', '$name', '$email', '$webname', '$url', '$imageurl')";
         
    mysql_query ($query) or die ('Could not create user.');
    }

    function 
    user_logout()
    {
         
    // End the session and unset all vars
         
    session_unset ();
         
    session_destroy ();
    }

    ?>
    and this is my register.php (where all this information is from . . . except for the form, which is on a different page, which is all validated).

    register.php

    PHP Code:
    <?php
    // Include init file
    include 'functions.php';
    if (!isset(
    $_POST['submit']))
    {
            
    // Show the form
         
    include 'register_form.inc.php';
         exit;
    }
    else
    {
         
    // Check if any of the fields are missing 
         
    if (empty($_POST['username']) || empty($_POST['password']) || empty($_POST['name']) || empty($_POST['email']) || empty($_POST['webname']) || empty($_POST['url']) || empty($_POST['imageurl']))
         {
              
    // Reshow the form with an error
              
    $reg_error '<font color="#ff0000">* One or more fields are missing.</font>';
              include 
    'register_form.inc.php';
              exit;
         }

         
    // Check if the passwords match
         
    if ($_POST['password'] != $_POST['confirmpass'])
         {
              
    // Reshow the form with an error
              
    $reg_error '<font color="#ff0000">* Your passwords do not match</font>';
              include 
    'register_form.inc.php';
              exit;
         }
         
    // Everything is ok, register *POSSIBLE PROBLEM AREA*
         
    register ($_POST['username'], $_POST['password'], $_POST['name'], $_POST['email'], $_POST['webname'], $_POST['url'], $_POST['imageurl']);

        echo 
    'Thank you for registering on our site, <a href="index.php">click here</a> to go back.';
    }
    ?>

    The error that I am receiving is that it cannot create the user, the error caused when the Mysql has an error (which is set in the first file). Can anyone help me figure this out?

  6. #6
    Join Date
    Nov 2008
    Posts
    2,477
    What is the output of mysql_error()? I still don't see any cleaning or validating of input, any one of a number of special characters could be breaking your query, as well as leaving you open to SQL injection still.

    Also you are generating a random salt, but then you are never storing that salt anywhere. When the user comes to log in how are you going to generate a matching hash again if you don't know the salt?

    There is also no need to encrypt the password, then join the salt, then encrypt again. You should just join the salt and the password and encrypt them once.

    With things like user management, you would really do better to learn the theory rather than just picking bits from existing scripts.
    Last edited by Mindzai; 06-02-2009 at 04:02 AM.

  7. #7
    Join Date
    Oct 2006
    Location
    On the web, working on my website
    Posts
    184
    Again, an explanation is in order. I am not sure what in fact I am doing wrong. This isn't the same code as before. It is not two codes combined as I had explained, but the knowledge from two different codes has been put into this. Could you maybe put your explanations into context as you did before.

    Thank you for helping me through this. User management is difficult, and the theory behind it is difficult and complex.

  8. #8
    Join Date
    Oct 2006
    Location
    On the web, working on my website
    Posts
    184
    Okay, So I finally figured out what you meant by an SQL Injection prevention script. SQL Injection is scary and should have been thought about. So, I just need to make sure that each of the things going through the form are protected by the
    PHP Code:
    mysql_real_escape_string() 
    Am I right? (I would still like some of the answers to my previous questions, if you could! )

  9. #9
    Join Date
    Nov 2008
    Posts
    2,477
    mysql_real_escape_string is the minimum you should do. I would also advise validating your data against expected formats. For example, if you are expecting a number, use is_numeric() to ensure it really is a number. If you are expecting data of a given length (for example you might have a username field defined as VARCHAR(50)), make sure it is the correct length. If you know the specific format data shoudl take, eg an email address, or a string of only letters, numbers and underscores, use regular expressions to check that the data is as you expect it. If you are expecting one of a few possible values, use a whitelist array and in_array to make sure that you only get one of those values (even if you use a select element - don't be fooled into thinking that because the user can't type their own value they cannot send a post request manually with whatever data they like). This not only adds another layer of protection, it also helps keep your data clean and tidy.

    The salt issue - you are currently generating a random salt and using it to encrypt the user's password. This is good, but you also need to store that salt in the database with the rest of the user's data, or else you will have no way of ever generating the same hash when you need to check their password again. How would you write code to log a user in with your current set up? It would be impossible, because you would get their salted, hashed password from the database, but you would not know the salt so you would not be able to check the submitted password matches. When you register a user store their unique salt along with their other data in the database table, then when you try to log them in use it to regenerate the same hash:

    PHP Code:
    $sql "SELECT salt FROM users WHERE username = '{$_POST['username']}' LIMIT 1";
    if (
    $result mysql_query($sql)) {
        
    $_POST['password'] = sha1(mysql_result($result0) . $_POST['password']);
        
    $sql "SELECT * FROM users WHERE username = '{$_POST['username']}' AND password = '{$_POST['password']}' LIMIT 1";
        if (
    $result mysql_query($sql)) {
            if (
    mysql_num_rows($result)) {
                
    // log the user in
                
    $userdata mysql_fetch_assoc($result);
            } else {
                
    // login failed
            
    }
        }

    Last edited by Mindzai; 06-03-2009 at 04:15 AM.

  10. #10
    Join Date
    Oct 2006
    Location
    On the web, working on my website
    Posts
    184
    Thank you for your help so far Mindzai! I am so close to figuring this out. Question about the code above...

    PHP Code:
    if ($result mysql_query($sql)) {
        
    $_POST['password'] = sha1(mysql_result($result0) . $_POST['password']);
        
    $sql "SELECT * FROM users WHERE username = '{$_POST['username']}' AND password = '{$_POST['password']}' LIMIT 1";
        if (
    $result mysql_query($sql)) {
            if (
    mysql_num_rows($result)) {
                
    // log the user in
                
    $userdata mysql_fetch_assoc($result);
            } else {
                
    // login failed
            
    }
        }

    What does the $userdata= mysql_fetch_assoc($result); mean? Better yet, what is it used for. When reading over what you made changes to, I have been looking at how you are making things simpler. However, I don't recognize the variable nor this new thing behind it.

  11. #11
    Join Date
    Nov 2008
    Posts
    2,477
    Bear in mind this is just an example of how you might write a login algorithm using a salt, it isn't intended to be used in place of any particular code you have now.

    This row:

    PHP Code:
    $userdata mysql_fetch_assoc($result); 
    Fetches the logged in user's data as an array and assigns it to the $userdata variable. Again this is just a very simplified example, but presumably after logging someone in you will want to store their info somewhere like a session, and this is one way of grabbing that data. After this line, you can access each field of your users table using the array, eg:

    PHP Code:
    echo $userdata['username']; // Mindzai 

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles