SitePoint Sponsor

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 25 of 33
  1. #1
    SitePoint Enthusiast
    Join Date
    Apr 2003
    Location
    PHP World
    Posts
    57
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    is this SQL Injection ?

    Hello ..

    is this query SQL injection :

    PHP Code:
    $query mysql_query("SELECT * FROM table WHERE title='" $_GET['title'] . "'"); 
    $_GET['title'] equal any string ?

  2. #2
    get into it! bigduke's Avatar
    Join Date
    May 2004
    Location
    Australia
    Posts
    847
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    without the $_GET['title'] being sanitized and without magic quotes enabled, yes this is a candidate for sql injection

  3. #3
    SitePoint Wizard
    Join Date
    Jan 2001
    Location
    Grand Rapids, MI
    Posts
    1,284
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yes, use htmlentities on it first to clear it of any code.

  4. #4
    SitePoint Enthusiast
    Join Date
    Apr 2003
    Location
    PHP World
    Posts
    57
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    ok htmlentities() will protect me ? i think it's only for Cross script ?

  5. #5
    Scary's On The Wall
    Join Date
    Apr 2003
    Location
    PA
    Posts
    518
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm fairly sure all you have to do is make sure you do addslashes() on it, or otherwise have magic_quotes on... You don't want to have 2x addslashes.

    Here's some code to "force" magic_quotes to be on, without requiring it to be enabled on the server (from phpBB code library):

    PHP Code:
    //
    // addslashes to vars if magic_quotes_gpc is off
    // this is a security precaution to prevent someone
    // trying to break out of a SQL statement.
    //
    if( !get_magic_quotes_gpc() )
    {
        if( 
    is_array($HTTP_GET_VARS) )
        {
            while( list(
    $k$v) = each($HTTP_GET_VARS) )
            {
                if( 
    is_array($HTTP_GET_VARS[$k]) )
                {
                    while( list(
    $k2$v2) = each($HTTP_GET_VARS[$k]) )
                    {
                        
    $HTTP_GET_VARS[$k][$k2] = addslashes($v2);
                    }
                    @
    reset($HTTP_GET_VARS[$k]);
                }
                else
                {
                    
    $HTTP_GET_VARS[$k] = addslashes($v);
                }
            }
            @
    reset($HTTP_GET_VARS);
        }

        if( 
    is_array($HTTP_POST_VARS) )
        {
            while( list(
    $k$v) = each($HTTP_POST_VARS) )
            {
                if( 
    is_array($HTTP_POST_VARS[$k]) )
                {
                    while( list(
    $k2$v2) = each($HTTP_POST_VARS[$k]) )
                    {
                        
    $HTTP_POST_VARS[$k][$k2] = addslashes($v2);
                    }
                    @
    reset($HTTP_POST_VARS[$k]);
                }
                else
                {
                    
    $HTTP_POST_VARS[$k] = addslashes($v);
                }
            }
            @
    reset($HTTP_POST_VARS);
        }

        if( 
    is_array($HTTP_COOKIE_VARS) )
        {
            while( list(
    $k$v) = each($HTTP_COOKIE_VARS) )
            {
                if( 
    is_array($HTTP_COOKIE_VARS[$k]) )
                {
                    while( list(
    $k2$v2) = each($HTTP_COOKIE_VARS[$k]) )
                    {
                        
    $HTTP_COOKIE_VARS[$k][$k2] = addslashes($v2);
                    }
                    @
    reset($HTTP_COOKIE_VARS[$k]);
                }
                else
                {
                    
    $HTTP_COOKIE_VARS[$k] = addslashes($v);
                }
            }
            @
    reset($HTTP_COOKIE_VARS);
        }

    EDIT: For strings, you have to make sure you have quotes around the $_POST or $_GET variable (exactly like you have in your example). If you're checking a number, use (int)$_GET['blah'] and you don't need quotes (and really shouldn't use them either).

  6. #6
    SitePoint Addict
    Join Date
    Aug 2004
    Location
    Chicago
    Posts
    296
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    $HTTP_POST_VARS???

    But, anyway, wouldn't it just be easier to do this?
    PHP Code:
    <?php
    if (get_magic_quotes_gpc)
        
    $_GET['title'] = stripslashes($_GET['title'])

    $_GET['title'] = mysql_real_escape_string($_GET['title']);

    $query mysql_query("SELECT * FROM table WHERE title='" $_GET['title'] . "'");
    ?>
    Last edited by bjcffnet; Jun 25, 2005 at 22:31. Reason: Typo
    Why's (Poignant) Guide to Ruby
    learn ruby with foxes, wizards, and chunky bacon

  7. #7
    SitePoint Wizard Mike Borozdin's Avatar
    Join Date
    Oct 2002
    Location
    Edinburgh, UK
    Posts
    1,743
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well, I must admit that SQL injection with PHP & MySQL are hard because mysql_query() doesn't allow you to execute you more than one command per function runnning.

  8. #8
    SitePoint Addict
    Join Date
    Oct 2004
    Location
    Brooklyn, NY
    Posts
    359
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by PHPBoy
    is this query SQL injection :

    PHP Code:
    $query mysql_query("SELECT * FROM table WHERE title='" $_GET['title'] . "'"); 
    Yes, that line has an SQL injection vulnerability, and it's an extreme example. Using any tainted data in a query represents an SQL injection vulnerability, so it's not always as obvious as $_GET.

    Quote Originally Posted by Ben
    Yes, use htmlentities on it first to clear it of any code.
    No, htmlentities() is for escaping data to be sent to the client, not a database. Use an escaping function native to your database such as mysql_real_escape_string(). You should also filter this data - escaping is not a substitute.

    Quote Originally Posted by bjcffnet
    But, anyway, wouldn't it just be easier to do this?
    I'm glad to see you using mysql_real_escape_string(), but it's not a good idea to store escaped data back in $_GET. The reason is theoretical in nature, but imagine what happens when you make a mistake and forget to escape something. If you use another array for escaped data, the worst case scenario is that you reference an undefined variable, and your error_reporting() can alert you to the problem. With this approach, the worst case scenario is that you use tainted data in your query, creating an SQL injection vulnerability.

    Again, it's theory, which I know is hard to appreciate, but history has proven that theoretically sound practices can save the day. Here is a slightly better approach:

    PHP Code:
    <?php

    $clean 
    = array();
    $mysql = array();

    if (
    ctype_alnum($_GET['username']))
    {
        
    $clean['username'] = $_GET['username'];
    }
    else
    {
        
    /* ... */
    }

    $mysql['username'] = mysql_real_escape_string($clean['username']);
    $sql "INSERT
            INTO   users (username)
            VALUES ('
    {$mysql['username']}')";

    /* ... */

    ?>
    Quote Originally Posted by Mike Borozdin
    I must admit that SQL injection with PHP & MySQL are hard because mysql_query() doesn't allow you to execute you more than one command per function runnning.
    It keeps an attacker from being able to construct an entirely new query, yes, but that certainly doesn't make it hard.

    This is a perfect example, because the format of the query allows an attacker to modify the nature of the WHERE clause. With very little work, an attacker can make the query match any records desired, including all records. Thus, a SELECT can match all records, an UPDATE can modify all records, and a DELETE can delete all records. Being able to manipulate the WHERE clause is very easy and very dangerous, and this is a common situation.
    Chris Shiflett
    http://shiflett.org/

  9. #9
    Scary's On The Wall
    Join Date
    Apr 2003
    Location
    PA
    Posts
    518
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by shiflett
    This is a perfect example, because the format of the query allows an attacker to modify the nature of the WHERE clause. With very little work, an attacker can make the query match any records desired, including all records. Thus, a SELECT can match all records, an UPDATE can modify all records, and a DELETE can delete all records. Being able to manipulate the WHERE clause is very easy and very dangerous, and this is a common situation.
    Could you by any chance give an example where addslashes() alone wouldn't be entirely injection-proof in PHPBoy's example?

  10. #10
    SitePoint Addict
    Join Date
    Aug 2004
    Location
    Chicago
    Posts
    296
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Addslashes only adds backslashes to single quote ('), double quote ("), backslash (\) and NUL (the NULL byte), while mysql_real_escape_query adds it to \x00, \n, \r, \, ', " and \x1a.

    I'm not exactly great with databases, but addslashes doesn't add a \ before \x00, \n, \r, \x1a. I'm not sure what that means, but I hope its good
    Why's (Poignant) Guide to Ruby
    learn ruby with foxes, wizards, and chunky bacon

  11. #11
    SitePoint Addict
    Join Date
    Jun 2005
    Posts
    294
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    So following the same question...I was reading this thread and I noticed a similarity to my code..
    PHP Code:
    $sql "SELECT * FROM $table_name WHERE username = '$_POST[username]' AND password =password('$_POST[password]')";

    $result mysql_query($sql) or die("Cannot query the database.<br>" mysql_error()); 
    WOuld that code be a candidate for injection?

  12. #12
    SitePoint Addict
    Join Date
    Oct 2004
    Location
    Italy
    Posts
    203
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Chris Shiflett,
    Thanks for the instructive post. I have a question, though. Wouldn't O'Reilly fail to qualify as clean in your code? If so, what's your proposed alternative to handle not only apostrophes but also underscores and '&'?
    Thanks

  13. #13
    SitePoint Addict
    Join Date
    Jun 2005
    Posts
    294
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    ^bump^

  14. #14
    SitePoint Addict
    Join Date
    Aug 2004
    Location
    Chicago
    Posts
    296
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Mav3n
    So following the same question...I was reading this thread and I noticed a similarity to my code..
    PHP Code:
    $sql "SELECT * FROM $table_name WHERE username = '$_POST[username]' AND password =password('$_POST[password]')";

    $result mysql_query($sql) or die("Cannot query the database.<br>" mysql_error()); 
    WOuld that code be a candidate for injection?
    PHP Code:
    $_POST['username'] = "' OR 'a' = 'a";
    $_POST['password'] = "' OR 'a' = 'a"
    So our query would be
    Code:
    SELECT * FROM $table_name WHERE username = '' OR 'a' = 'a' 
    AND password = password('' OR 'a' = 'a')
    So, with the password function, it wouldn't work.

    (If it matters, '' OR 'a' = 'a' comes out to something like *E6CC90B87B948C35E92B003C792C46C58C4AF40 . . .)
    Why's (Poignant) Guide to Ruby
    learn ruby with foxes, wizards, and chunky bacon

  15. #15
    SitePoint Addict
    Join Date
    Jun 2005
    Posts
    294
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I am not understanding your post buddy...Maybe I am just a moron! lol

  16. #16
    SitePoint Addict
    Join Date
    Aug 2004
    Location
    Chicago
    Posts
    296
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Just ignore my last post, and let me change my post a little . . .
    Let's say that $_POST['username'] is
    Code:
    ' OR 'a' = 'a
    and that $_POST['password'] is
    Code:
    somethingrandom') OR 'a' = 'a' OR 'a' = password('a
    That would make the original MySQL Query:
    Code:
    SELECT * FROM $table_name WHERE username = '$_POST[username]' AND password =password('$_POST[password]');
    Turn into
    Code:
    SELECT * FROM $table_name WHERE username = '' OR 'a' = 'a' AND password =password('somethingrandom') OR 'a' = 'a' OR 'a' = password('a');
    Which would make it return everything in $table_name

    Sorry if I'm still not being clear
    Why's (Poignant) Guide to Ruby
    learn ruby with foxes, wizards, and chunky bacon

  17. #17
    SitePoint Addict
    Join Date
    Jun 2005
    Posts
    294
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Maybe I am a complete stupid ***...but is that answering my question on whether or not my code was a candidate for sql injection?

  18. #18
    SitePoint Addict
    Join Date
    Aug 2004
    Location
    Chicago
    Posts
    296
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yes, and Yes it is a canidate for sql injection . . .

    Check out mysql_real_escape_string()
    Why's (Poignant) Guide to Ruby
    learn ruby with foxes, wizards, and chunky bacon

  19. #19
    SitePoint Addict
    Join Date
    Jun 2005
    Posts
    294
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I guess i might also include that at the top of my script I have...
    PHP Code:
    <?php
    session_start
    ();
    if ((!
    $_POST[username]) ||(!$_POST[password])){
      echo 
    "please enter username and password";
      exit;

  20. #20
    SitePoint Addict
    Join Date
    Jun 2005
    Posts
    294
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    So, qould you recommend me making two variablies...
    PHP Code:
    $username "$_POST['username']";
    $password "$_POST['passwird']"
    And then for my query.
    PHP Code:
    $query sprintf("SELECT * FROM users WHERE user='$username' AND password='password($password)'",
               
    mysql_real_escape_string($user),
               
    mysql_real_escape_string($password)); 
    Would that make it more secure?

  21. #21
    SitePoint Addict
    Join Date
    Aug 2004
    Location
    Chicago
    Posts
    296
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    In place of $username and $password, you would need to %s to tell PHP to replace it with the mysql_real_escape_string'd variables . . .

    So try something like this:

    PHP Code:
     $username "$_POST['username']";
    $password "$_POST['password']";

    $query sprintf("SELECT * FROM users WHERE user='%s' AND password=password('%s')",
               
    mysql_real_escape_string($user),
               
    mysql_real_escape_string($password)); 
    Why's (Poignant) Guide to Ruby
    learn ruby with foxes, wizards, and chunky bacon

  22. #22
    SitePoint Addict
    Join Date
    Jun 2005
    Posts
    294
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thank you for your help...I have been able to implement the mysql_real_escape_string..But now I am back at my old problem...I log-in using the correct username and password..and I get looped back to my login.html. That is being caused by either the admin.php or the login.php.

    I have a question...that might solve the solution...The way the users got placed on my database was via an adduser.php. Does that file need to have the mysql_real_escape_string in order for my log-in script to match the variables that are on the datbase?

    My adduser.php has the password() function...So what I am thinking is happening is that the hashes are not being recognized because I am implementing both the password() function and the mysql_real_escape_string function together.

  23. #23
    SitePoint Addict
    Join Date
    Jun 2005
    Posts
    294
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Here is my login.php code..
    PHP Code:
    <?php
    session_start
    ();
    //Variables..
    $username "$_POST[username]";
    $password "password($_POST[password])";
    if ((!
    $username) ||(!$password)){
      echo 
    "please enter username and password";
      exit;
    }
    //Set up Names of Database
    $db_name "dbname";
    $table_name "tablename";

    //Connect to the Database
    $connection mysql_connect("localhost""username""password")or die(mysql_err());
    $db mysql_select_db($db_name$connection)or die (mysql_error());

    //Insert Data into the Table
    $query sprintf("SELECT * FROM members WHERE username='%s' AND password='%s'",
               
    mysql_escape_string($username),
               
    mysql_escape_string($password));

    $result mysql_query($query) or die("Cannot query the database.<br>" mysql_error());
    //
    //Set The Cookie Session Settings
    $num mysql_num_rows($result);
    if (
    $num != 0){
      
    $cookie_name "auth";
      
    $cookie_value "ok";
      
    $cookie_expire "0";
      
    $cookie_domain "www.mydomain.com";
      
    setcookie($cookie_name$cookie_value$cookie_expire "/"$cookie_domain0);
      
    header "Location: index.php");
    }else{
      echo 
    "Wrong Username/Password";
    }
    //End
    /*That's All Folks!*/
    ?>
    Notice the last echo statement...Well that's what I get when I enter the CORRECT username and password!

  24. #24
    SitePoint Addict
    Join Date
    Aug 2004
    Location
    Chicago
    Posts
    296
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You aren't calling the password function in the MySQL query. So try replacing
    PHP Code:
    $query sprintf("SELECT * FROM members WHERE username='%s' AND password='%s'",
               
    mysql_escape_string($username),
               
    mysql_escape_string($password)); 
    with:
    PHP Code:
    $query sprintf("SELECT * FROM members WHERE username='%s' AND password=password('%s')",
               
    mysql_escape_string($username),
               
    mysql_escape_string($password)); 
    Why's (Poignant) Guide to Ruby
    learn ruby with foxes, wizards, and chunky bacon

  25. #25
    SitePoint Addict
    Join Date
    Jun 2005
    Posts
    294
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks..I added that..but I am still getting the
    PHP Code:
    echo "Wrong Username/Password"
    After I submit the username and password.

    Here is how the USERS get on my database
    PHP Code:
    <?php
    if ((!$_POST[gamertag]) || (!$_POST[email]) || (!$_POST[username]) || (!$_POST[password])) {
      
    header"Location: adduser.html");
    }

    //Set up Names of Database
    $db_name "dbname";
    $table_name "tablename";
    //
    //
    //Connect to the Database
    $connection mysql_connect("localhost""username""password")or die(mysql_err());
    $db mysql_select_db($db_name$connection)or die (mysql_error());

    //Insert Data into the Table
    $sql "INSERT INTO $table_name(id,gamertag, email, username, password) VALUES ('$_POST[id]','$_POST[gamertag]', '$_POST[email]', '$_POST[username]',password('$_POST[password]'))";

    $query mysql_query($sql) or die("Cannot query the database.<br>" mysql_error());
    ?>

    <HTML>
    <HEAD>
    <TITLE>Add a user</TITLE>
    </HEAD>
    <BODY>
    <p>GamerTag<br>
    <? echo "$_POST[gamertag]"?></p>

    <p>E-mail<br>
    <? echo "$_POST[email]"?></p>

    <p>Username<br>
    <? echo "$_POST[username]"?></p>

    <p>Password<br>
    <? echo "$_POST[password]";
    ?></p>
    <p><a href="adduser.html">Add Another</a></p>
    </BODY>
    </HTML>
    My concern is that I have the mysql_escape_string on login.php..But I don't have it on adduser.php..I think the hashes aren't being matched up.


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
  •