Protecting PHP script against MySQL injection code.

Discussion in 'PHP' started by Limotek, Jul 28, 2008.

  1. #1
    Hi,

    I've heard a lot about MySQL code injection hacks and am looking for ways to protect my site. I have a very simple logon script at the moment. I've read a little about md5() to encrypt the password and mysql_real_escape_string to stop SQL injection code but I'm starting to get confused as to how to implement it.

    Can someone please point me in the right direction?


    Code for logon.php
    
    <?
    session_start();
     
    $username = $_POST['username'];
    $password = $_POST['password'];
    
    // Connects to your Database 
    include 'inc-dbconnect.php';
    $query='SELECT id, access_level, username FROM user_data where username="'.$username.'" AND password="'.$password.'";';
    $data = mysql_query($query);
    $info = mysql_fetch_array($data);
    $num = mysql_num_rows($data); 
    include 'inc-dbclose.php';
    
    if ($num=="1" )
    {
    $_SESSION['s_userid'] = $info['id']; 
    $_SESSION['s_useraccess'] = $info['access_level']; 
    $_SESSION['s_username'] = $info['username']; 
    header( 'Location: landing_page.php' );
    }
    else
    {
    header( 'Location: index.php?error=1' );
    };
    
    include 'inc-session-close.php';
    ?> 
    Code (PHP):

    And here is part of the HTML
    
    <form method="post" name="logon" id="logon" action="logon.php">
    Username: <input name="username" type="text" id="username"></br>
    Password: <input name="password" type="password" id="password">
    <br />
    <input type="submit" name="Submit" value="Submit">
    <input type="reset" name="Reset" value="Reset">
    </form>
    
    Code (markup):
     
    Limotek, Jul 28, 2008 IP
  2. Dreads

    Dreads Well-Known Member

    Messages:
    1,884
    Likes Received:
    24
    Best Answers:
    0
    Trophy Points:
    150
    #2
    Before that ->
    // Connects to your Database

    You need to use some sort of protection -_- usally
    $username = mysql_real_escape_string($username)
    $password = md5($password)
     
    Dreads, Jul 28, 2008 IP
  3. Mozzart

    Mozzart Peon

    Messages:
    189
    Likes Received:
    3
    Best Answers:
    0
    Trophy Points:
    0
    #3
    
    <?
    session_start();
     
    $username = htmlspecialchars($_POST['username']); // convert the quotes to html entities & < > " '
    $password = htmlspecialchars($_POST['password']);
    
    // Connects to your Database
    include 'inc-dbconnect.php';
    $query='SELECT id, access_level, username FROM user_data where username="'.$username.'" AND password="'.$password.'";';
    $data = mysql_query($query);
    $info = mysql_fetch_array($data);
    $num = mysql_num_rows($data);
    include 'inc-dbclose.php';
    
    if ($num=="1" )
    {
    $_SESSION['s_userid'] = (int) $info['id'];
    $_SESSION['s_useraccess'] = (int) $info['access_level']; // i added (int) but not sure what this contains
    $_SESSION['s_username'] = $info['username'];
    header( 'Location: landing_page.php' );
    }
    else
    {
    header( 'Location: index.php?error=1' );
    };
    
    include 'inc-session-close.php';
    ?>
    
    PHP:
    use ctype functions to detect if they are integers or not etc etc. These are just the basics, sometimes it's hard to cover all bases but that should hold on for a while.

    Remember that sessions can get hijacked.
     
    Mozzart, Jul 28, 2008 IP
  4. Limotek

    Limotek Peon

    Messages:
    165
    Likes Received:
    5
    Best Answers:
    0
    Trophy Points:
    0
    #4
    Hi dreads. Thanks for the reply. I'll try this out.

    When using md5($password), do I need to do anything to the password when first adding it to the database? i.e. does md5 just unhash the password? Is there a method I need to put in a hashed password into MySQL?
     
    Limotek, Jul 28, 2008 IP
  5. Limotek

    Limotek Peon

    Messages:
    165
    Likes Received:
    5
    Best Answers:
    0
    Trophy Points:
    0
    #5
    Hi Mozart. Thanks for that. You're right that access_level is an int.

    I'm trying this out now.
     
    Limotek, Jul 28, 2008 IP
  6. Limotek

    Limotek Peon

    Messages:
    165
    Likes Received:
    5
    Best Answers:
    0
    Trophy Points:
    0
    #6
    Thank you very much. That works really well.

    Is it still worth using the md5() bit on the password or is it not necessary?
     
    Limotek, Jul 28, 2008 IP
  7. Dreads

    Dreads Well-Known Member

    Messages:
    1,884
    Likes Received:
    24
    Best Answers:
    0
    Trophy Points:
    150
    #7
    you would have to md5 the passwords on registery -_-
    so the stored passwords in the database would be md5.

    I also dont think htmlspecialchars will stop MySQL injection, please use escape as well.

    Also to add.. you cant decode md5 as of right now
     
    Dreads, Jul 28, 2008 IP
  8. Mozzart

    Mozzart Peon

    Messages:
    189
    Likes Received:
    3
    Best Answers:
    0
    Trophy Points:
    0
    #8
    mysql_real_escape_string justs add backslashes, just like addslashes() and php.net suggests to use addslashes() when inserting things to a database.

    What I mean is that it doesn't do much of an effect when holding injections. Well, it's a bit hard to know what a hacker's planning to do but oh well


    md5 can be cracked, also use hash('sha256', $passwordSTRINGHERE);
    salt the passwords too. for example

    
    define('SALT', '8D8B8XNIANN3OND'); // you can change the definition
    
    hash('sha256', $passwordstring.SALT);
    
    PHP:
     
    Mozzart, Jul 28, 2008 IP
  9. Ms Grace

    Ms Grace Peon

    Messages:
    5
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #9
    You can run the variables through the following function:

    
    function no_injection($string){
    
    $string = htmlspecialchars($string);
    $string = trim($string);
    $string = stripslashes($string);
    $string = mysql_real_escape_string($string);
    
    return $string;
    }
    
    PHP:
    like this:

    
    $username = no_injection($_POST['username']);
    $password = no_injection($_POST['password']);
    
    PHP:
     
    Ms Grace, Jul 28, 2008 IP
  10. Limotek

    Limotek Peon

    Messages:
    165
    Likes Received:
    5
    Best Answers:
    0
    Trophy Points:
    0
    #10
    Hi all,

    Thanks for your responses so far.

    I've changed the code so it now reads:

    <?
    function no_injection($string)
    {
    $string = htmlspecialchars($string);
    $string = trim($string);
    $string = stripslashes($string);
    $string = mysql_real_escape_string($string);
    return $string;
    }
    
    session_start();
     
    $username = no_injection($_POST['username']);
    $password = no_injection($_POST['password']);
    
    // Connects to your Database 
    include 'inc-dbconnect.php';
    $query='SELECT id, access_level, username FROM user_data where username="'.$username.'" AND password="'.$password.'";';
    $data = mysql_query($query);
    $info = mysql_fetch_array($data);
    $num = mysql_num_rows($data); 
    include 'inc-dbclose.php';
    
    if ($num=="1" )
    {
    $_SESSION['s_userid'] = (int) $info['id']; 
    $_SESSION['s_useraccess'] = (int) $info['access_level']; 
    $_SESSION['s_username'] = $info['username']; 
    print "<script>";
    print "self.location='landing_page.php'";
    print "</script>";
    }
    else
    {
    print "<script>";
    print "self.location='index.php?error=1'";
    print "</script>";
    };
    
    include 'inc-session-close.php';
    ?> 
    Code (PHP):
    The problem is that now no username / password combination seems to allow access. (I know I said it wanted secure but this may be too harsh :) ). Can anyone see why this is happening. There are no special characters in my username and password and I haven't added any md5/hash/SALT stuff yet.

    EDIT: Worth mentioning that when I echo $username and $password, both are now blank.
     
    Limotek, Jul 28, 2008 IP
  11. lfhost

    lfhost Peon

    Messages:
    232
    Likes Received:
    8
    Best Answers:
    0
    Trophy Points:
    0
    #11
    Check what you have stored in your database, if the password is encrypted or not as you havent used the MD5 function on the password.
     
    lfhost, Jul 28, 2008 IP
  12. cakung

    cakung Peon

    Messages:
    113
    Likes Received:
    3
    Best Answers:
    0
    Trophy Points:
    0
    #12
    wew.....you right.so,now you sites have the system securty from hacker. :d
     
    cakung, Jul 29, 2008 IP