SitePoint Sponsor

User Tag List

Results 1 to 19 of 19
  1. #1
    SitePoint Wizard
    Join Date
    Jul 2006
    Location
    New Zealand
    Posts
    1,300
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    sql injection problem

    i am trying to protect my login form being sql injected now i tried to do it myself and got it stuck this is what my problem is

    Warning: mysqli_real_escape_string() expects exactly 2 parameters, 1 given in /home/william2/public_html/clansite/login.php on line 8
    SELECT * FROM members WHERE username=''

    on line 8 i have this

    $cQuery="SELECT * FROM members WHERE username='".mysqli_real_escape_string(stripslashes(trim($_POST['username'])))."'";

    and on line 9 i have to define the link to my connection:
    $con;

    What i am missing?

    this is the whole code

    PHP Code:
    <?php
        session_start
    ();
        include(
    "dbconnect.php");
        
    $msg_pass="";
        
    $msg_user="";
        if(
    $_POST['username'] && $_POST['password'])
        {    
            
    $cQuery="SELECT * FROM members WHERE username='".mysqli_real_escape_string(stripslashes(trim($_POST['username'])))."'";
            
    $con;
            echo 
    $cQuery;
            
    $rs=mysqli_query($con,$cQuery);
            if(!
    $rs)
            {
                echo 
    "Unable to excute the query:".mysqli_error($con);
            }
            else
            {
                
    $count=mysqli_num_rows($rs);
                    if(
    $count>0)
                    {
                        
    $data=mysqli_fetch_assoc($rs);
                        if(
    $data['password']=$password)
                        {
                            
    $_SESSION['user']=$_POST['username'];
                            include(
    "consoleincludes/console.inc.php");
                            }
                            else
                            {
                                
    $msg_pass="Wrong Password,Please Try again<br>\n";
                                include(
    "includes/attemptloginfailed.inc.php");
                            }
                        }
                        else
                        {
                            
    $msg_user="Wrong Username,Please Try again<br>\n";
                            include(
    "includes/attemptloginfailed.inc.php");
                        }
                    }
             if(!
    $_SESSION['user'])
             {
                include(
    "includes/header.inc.php");?>
                <fieldset>
                <legend><font color="#FFFFFF">Please Login</font></legend>
                <form name="login" method="post" action="">
                <?
                    
    echo ($msg_user)?"<br/>".$msg_user."<br/>":"";
                
    ?>
                <font color="#FFFFFF">Username:</font><input type="text" name="username" maxlength="14"/><br/>
                <?
                    
    echo($msg_pass)?"<br/>".$msg_pass."<br/>":"";
                
    ?>
                <font color="#FFFFFF">Password:</font><input type="password" name="password" maxlength="12"/><br/>
                <input type="submit" name="login" value="login"/>
                </form></fieldset><?php
            
    }
        }
    ?>
    Does anyone know how i can i fix this?

  2. #2
    SitePoint Member
    Join Date
    Dec 2006
    Posts
    2
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Try using mysql_real_escape_string ?

  3. #3
    SitePoint Addict
    Join Date
    May 2006
    Location
    Amsterdam
    Posts
    206
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm not familiar with mysqli_real_escape_string but according to the manual you need to specify the link and then the string. In the code you posted $con is on its own line by itself. Maybe you originally typed it so that it was part of the mysqli_real_escape_string statement but it got pushed down a line. In anycase, assuming $con represents the link you might want to write that part of your code like this:

    PHP Code:
    if($_POST['username'] && $_POST['password'])
        {    
            
    $username mysqli_real_escape_string($con,stripslashes(trim($_POST['username'])));
    $cQuery="SELECT * FROM members WHERE username='".$username."'"
    Now I'm curious, does htmlentities not protect well enough against an SQL injection attack?
    PHP Code:
     htmlentities(trim($_POST['username']),ENT_QUOTES); 

  4. #4
    reads the ********* Crier silver trophybronze trophy longneck's Avatar
    Join Date
    Feb 2004
    Location
    Tampa, FL (US)
    Posts
    9,854
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Now I'm curious, does htmlentities not protect well enough against an SQL injection attack?
    no, it does not.
    PHP Code:
    $user htmlentities('4 or true');
    $sql "select foo from bar where user = $user";
    echo 
    $sql
    output:
    Code:
    select foo from bar where user = 4 or true
    you've just exposed your entire table bar to the world.

  5. #5
    SitePoint Addict
    Join Date
    May 2006
    Location
    Amsterdam
    Posts
    206
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Nice catch longneck.

    Taking a closer look at mysqli_real_escape_string, it doesn't look like it would take care of the type of attack you mentioned:
    Characters encoded are NUL (ASCII 0), \n, \r, \, ', ", and Control-Z.
    As far as I know, writing the query like this would handle this type of attack:
    PHP Code:
    $sql "select foo from bar where user = '$user'"
    Output:
    Code:
    select foo from bar where user = '4 or true'
    but how would you recommend dealing with it?

  6. #6
    SitePoint Wizard silver trophy
    Join Date
    Mar 2006
    Posts
    6,132
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    strings are escaped. strings must be quoted.

    numbers, are very easy to validate that they are a number. ctype_digit() or just force the value to an integer with intval()




    william, why dont you read the documentation and find out what the 2 parameters for the function are supposed to be? you could also look at the other code you have written, as i know you have used this function successfully before. it looks like you really have not given this much effort.

  7. #7
    Non-Member I87's Avatar
    Join Date
    Mar 2006
    Location
    UK
    Posts
    378
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    danNL, it's very unstandard to escape integer values in sql

    if you know $user will always be an integer, then use something like

    PHP Code:
    $user = (int) $_POST['user']; 

    or if it will vary from time to time, use a function like this (as recommended as best practice by php.net)


    PHP Code:
    <?php
    // Quote variable to make safe
    function quote_smart($value)
    {
       
    // Stripslashes
       
    if (get_magic_quotes_gpc()) {
           
    $value stripslashes($value);
       }
       
    // Quote if not a number or a numeric string
       
    if (!is_numeric($value)) {
           
    $value "'" mysql_real_escape_string($value) . "'";
       }
       return 
    $value;
    }

    // Connect
    $link mysql_connect('mysql_host''mysql_user''mysql_password')
       OR die(
    mysql_error());

    // Make a safe query
    $query sprintf("SELECT * FROM users WHERE user=%s AND password=%s",
               
    quote_smart($_POST['username']),
               
    quote_smart($_POST['password']));

    mysql_query($query);
    ?>

  8. #8
    SitePoint Addict
    Join Date
    May 2006
    Location
    Amsterdam
    Posts
    206
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Thumbs up

    Thanks!

  9. #9
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by I87 View Post
    or if it will vary from time to time, use a function like this (as recommended as best practice by php.net)

    PHP Code:
    // Quote variable to make safe
    function quote_smart($value) {
    (...)

    I wouldn't recommend that. It will work in most situations, but you may corrupt your data. The problem with this function is that it assumes that any data, you insert into a query, necessarily comes from GET/POST. This is often true, but needn't be. You should rather:
    a) Disable magic quotes. You can do this by editing php.ini (preferably) or by undoing the damage as one of the first things in your script.
    b) Escape strings when building queries. Use mysql_real_escape_string for this. Alternatively, if you use PHP5, you can use PDO, which has support for prepared statements. Prepared statements are both faster and safer, and they are easier to use.

  10. #10
    SitePoint Wizard
    Join Date
    Jul 2006
    Location
    New Zealand
    Posts
    1,300
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by danNL View Post
    I'm not familiar with mysqli_real_escape_string but according to the manual you need to specify the link and then the string. In the code you posted $con is on its own line by itself. Maybe you originally typed it so that it was part of the mysqli_real_escape_string statement but it got pushed down a line. In anycase, assuming $con represents the link you might want to write that part of your code like this:

    PHP Code:
    if($_POST['username'] && $_POST['password'])
        {    
            
    $username mysqli_real_escape_string($con,stripslashes(trim($_POST['username'])));
    $cQuery="SELECT * FROM members WHERE username='".$username."'"
    Now I'm curious, does htmlentities not protect well enough against an SQL injection attack?
    PHP Code:
     htmlentities(trim($_POST['username']),ENT_QUOTES); 
    I used this method

    $username = mysqli_real_escape_string($con,stripslashes(trim($_POST['username'])));
    $passowrd = mysqli_real_escape_string($con,stripslashes(trim($_POST['paassword'])));

    i got no errors but when i typed the username and password it would let me login.

  11. #11
    SitePoint Wizard
    Join Date
    Jul 2006
    Location
    New Zealand
    Posts
    1,300
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by clamcrusher View Post
    strings are escaped. strings must be quoted.

    numbers, are very easy to validate that they are a number. ctype_digit() or just force the value to an integer with intval()




    william, why dont you read the documentation and find out what the 2 parameters for the function are supposed to be? you could also look at the other code you have written, as i know you have used this function successfully before. it looks like you really have not given this much effort.
    The other one has no sql protection.

  12. #12
    reads the ********* Crier silver trophybronze trophy longneck's Avatar
    Join Date
    Feb 2004
    Location
    Tampa, FL (US)
    Posts
    9,854
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    sorry, you're right. it wasn't a very good example.

    let's try this instead:
    PHP Code:
    $user htmlentities("longneck' or 'a'='a");
    $sql "select foo from bar where username = '$user'";
    echo 
    $sql
    output:
    Code:
    select foo from bar where username = 'longneck' or 'a'='a'
    to properly protect against SQL injection, strings need to be processed with mysql_real_escape_string() and numerics need to be typecast in the host language.

  13. #13
    SitePoint Wizard
    Join Date
    Jul 2006
    Location
    New Zealand
    Posts
    1,300
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    were you talking to me longneck?

  14. #14
    reads the ********* Crier silver trophybronze trophy longneck's Avatar
    Join Date
    Feb 2004
    Location
    Tampa, FL (US)
    Posts
    9,854
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    it was directed more at danNL.

  15. #15
    SitePoint Wizard silver trophy
    Join Date
    Mar 2006
    Posts
    6,132
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by william232 View Post
    The other one has no sql protection.
    the other what?

  16. #16
    SitePoint Addict
    Join Date
    May 2006
    Location
    Amsterdam
    Posts
    206
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by william232 View Post
    I used this method

    $username = mysqli_real_escape_string($con,stripslashes(trim($_POST['username'])));
    $passowrd = mysqli_real_escape_string($con,stripslashes(trim($_POST['paassword'])));

    i got no errors but when i typed the username and password it would let me login.
    1. Do you mean that you could not log in?
      • There's a typo on 'paassword' is that the variable name you're using?
    2. Or that a test SQL Injection worked?

    In either case, maybe it's worth trying the script I87 recommended instead ...

  17. #17
    SitePoint Wizard REMIYA's Avatar
    Join Date
    May 2005
    Posts
    1,351
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You must open a connection first and pass it to the function. Look at this:

    PHP Code:
    $link mysqli_connect("localhost",  "my_user""my_password",  "world");

    $city  mysqli_real_escape_string($link$city); 



  18. #18
    SitePoint Wizard
    Join Date
    Jul 2006
    Location
    New Zealand
    Posts
    1,300
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    How can i tell if it worked or not? if i am protected?

  19. #19
    SitePoint Addict
    Join Date
    May 2006
    Location
    Amsterdam
    Posts
    206
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm definitely not an expert on this but this Google search on SQL Injection Testing might help.


Bookmarks

Posting Permissions

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