TalkPHP
 
 
Account Login
Latest Articles
» The basic usage of PHPTAL, a XML/XHTML template library for PHP
» Vulnerable methods and the areas they are commonly trusted in.
» Simple way to protect a form from bot
» The Basics On: How Session Stealing Works
» How to keep your forms from double posting data
IRC Channel
IRC Speech Bubble Join the friendly bunch on IRC...
(#TalkPHP on Freenode)

...Also available via a web interface.

See this thread for information on the TalkPHP Free Hugs Initiative™. Subject to availability.
Associates
Associates
CSS Tutorials
Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old 06-25-2008, 02:01 PM   #1 (permalink)
The Acquainted
 
drewbee's Avatar
 
Join Date: May 2008
Posts: 175
Thanks: 9
drewbee is on a distinguished road
Default SQL Injection

Hey everyone, I am looking for some ideas or opinions on how well my secure my scripting is.

Should a query come from GET, POST, or any other means...

I always do this in the queries.

PHP Code:
$_GET['group_id'] = isset($_GET['group_id']) ? (int)$_GET['group_id'] : 0;
$_POST['username'] = isset($_POST['username']) ? $_POST['username'] : '';
 
SELECT        account_idusernameaccount_group
FROM          users
WHERE        belongs_to_group 
'" . $_GET['group_id'] . "' AND
                  
username '" . mysql_real_escape_string($_POST['username']) . "' 
I know the query doesn't really make sense... it doesn't need too. Display purposes only.

As well, the username value would have validation from the form (overflow, and proper regex validation against the username).

I let the query fail should a user enter a string through proper handling though as it (atleast to my understanding) will be looking for '0' if anything but an integer is entered.

so, since no rows were found...

PHP Code:
if (mysql_num_rows($query) > 0)
{
    
// bla hbal hbalh do stuff
}
else
{
     
$this->throwError('Invalid account information supplied');


Also, my form class (everytime form input is sent in, all values are automatically trim'ed and strip_slashed for redisplay (if form error) / processing (if passed form validation).

Thoughts? Ideas? Suggestions to better protect myself? I am just getting ready to start another project and want to get even tighter security implemented if possible.
__________________
There are No Stupid Questions. But there a LOT of Inquisitive Idiots.
Send a message via AIM to drewbee
drewbee is offline  
Reply With Quote
Old 06-25-2008, 05:54 PM   #2 (permalink)
The Acquainted
 
drewbee's Avatar
 
Join Date: May 2008
Posts: 175
Thanks: 9
drewbee is on a distinguished road
Default

To clean things up even a bit more, I am now going to use sprintf to write queries. Is this really necessary? I see them doing this in the manual, and have never done it myself.

PHP Code:
// No need for casting as %d in sprintf will take care ofit.
$_GET['group_id'] = isset($_GET['group_id']) ? $_GET['group_id'] : 0;
$_POST['username'] = isset($_POST['username']) ? $_POST['username'] : '';
 
$query sprintf("SELECT   *  
                  FROM     users 
                  WHERE    user_name='%s' AND 
                           user_group='%d'"
,
         
mysql_real_escape_string($_POST['user_name']),
         
$_GET['user_group']
                 ); 
__________________
There are No Stupid Questions. But there a LOT of Inquisitive Idiots.
Send a message via AIM to drewbee
drewbee is offline  
Reply With Quote
Old 06-25-2008, 06:17 PM   #3 (permalink)
The Contributor
 
ryanmr's Avatar
 
Join Date: Jun 2008
Location: Twin Cities, Minnesota, USA
Posts: 44
Thanks: 3
ryanmr is on a distinguished road
Default

I'm not sure if sprintf covers this but I normally use is_numeric for ids and some regex for usernames.
In anycase, you can look at this cheat sheet: 0x000000 # The Hacker Webzine - SQL Injection Cheat Sheet, it shows you a lot of different ideas.
ryanmr is offline  
Reply With Quote
Old 06-25-2008, 07:44 PM   #4 (permalink)
La Vida es Sueño
Advanced Programmer Top Contributor 
 
Wildhoney's Avatar
 
Join Date: Sep 2007
Location: Oldham
Posts: 2,280
Thanks: 90
Wildhoney is on a distinguished road
Default

In the past, before I switched over to Zend Framework, I ran all my PHP variables, to be used in a MySQL statement, through the following function. I'm not sure if it's actually 100% secure, but it seemed to be. I think Salathe, a while ago, pointed out some problems regarding different file-types, such as boolean values, but I don't believe anybody actually discovered any such major flaws.

It'll serve as a good base nonetheless, for if you wish to add onto it, or switch some things around, or merely use it as a reference.

php Code:
function mysql_parse_value($value, $strip_tags=true, $allowable_tags=null)
{
    if (is_array($value))
    {
        return
    }
   
    if (get_magic_quotes_gpc())
    {
        $value = stripslashes($value);
    }
         
    if ($strip_tags)
    {
        $value = strip_tags($value, $allowable_tags);
    }
       
    if (!is_numeric($value))
    {
     $value = "'" . mysql_real_escape_string($value) . "'";
    }

    return $value;
}

I did use it in conjunction with sprintf, as you mentioned. This function places in any quotes for you, and so you shouldn't actually put in any quotes into sprintf's first argument.

To give an example:

php Code:
$szMyVar1 = 'TalkPHP.com';
$szMyVar2 = 'TalkRSI.com';

$szSQL = sprintf
(
    "SELECT * FROM myTable WHERE myColumn = %s OR myColumn = %s",
    mysql_parse_value($szMyVar1), mysql_parse_value($szMyVar2)
);
__________________
The man who comes back through the Door in the Wall will never be quite the same as the man who went out.
Send a message via AIM to Wildhoney Send a message via MSN to Wildhoney Send a message via Yahoo to Wildhoney
Wildhoney is offline  
Reply With Quote
Old 06-25-2008, 07:46 PM   #5 (permalink)
The Acquainted
 
Join Date: Oct 2007
Posts: 170
Thanks: 18
maZtah is an unknown quantity at this point
Default

Just a little note: with mysql you don't have to put quotes around integers. So user_group = %d will do the job, no need to put quotes around it!

Futhermore, it looks quite safe to me.


Edit:
Wildhoney won the race to mention about the quotes. ;)
maZtah is offline  
Reply With Quote
Old 06-25-2008, 08:20 PM   #6 (permalink)
The Acquainted
 
drewbee's Avatar
 
Join Date: May 2008
Posts: 175
Thanks: 9
drewbee is on a distinguished road
Default

Yeah, I know you don't have to put quotes around integer values. For some reason, I always have. Not sure why. Just one of those things I started doing and formed a habit around it. Is there any actual benefit to not using quotes around numeric values?
__________________
There are No Stupid Questions. But there a LOT of Inquisitive Idiots.
Send a message via AIM to drewbee
drewbee is offline  
Reply With Quote
Old 06-26-2008, 08:59 AM   #7 (permalink)
The Acquainted
 
Join Date: Oct 2007
Posts: 170
Thanks: 18
maZtah is an unknown quantity at this point
Default

Quote:
Originally Posted by drewbee View Post
Yeah, I know you don't have to put quotes around integer values. For some reason, I always have. Not sure why. Just one of those things I started doing and formed a habit around it. Is there any actual benefit to not using quotes around numeric values?
For me it's just about "correct" coding, a string is a string, and a integer is an integer. I have no idea if there's any benefit if you're putting quotes around it or not. Though, logically it's more correct (to me).
maZtah is offline  
Reply With Quote
Old 06-25-2008, 10:06 PM   #8 (permalink)
La Vida es Sueño
Advanced Programmer Top Contributor 
 
Wildhoney's Avatar
 
Join Date: Sep 2007
Location: Oldham
Posts: 2,280
Thanks: 90
Wildhoney is on a distinguished road
Default

None as far as I can see. I thought maybe MySQL wouldn't be able to perform mathematical equations on numbers which guise themselves as strings, but it appears I am wrong, as both of these work correctly:

sql Code:
UPDATE myTable SET myCount = myCount + "2"
SELECT "1" + "10"
__________________
The man who comes back through the Door in the Wall will never be quite the same as the man who went out.
Send a message via AIM to Wildhoney Send a message via MSN to Wildhoney Send a message via Yahoo to Wildhoney
Wildhoney is offline  
Reply With Quote
Old 06-26-2008, 03:33 AM   #9 (permalink)
The Frequenter
Zend Certified 
 
Join Date: Sep 2007
Location: Denmark
Posts: 352
Thanks: 8
Kalle is on a distinguished road
Default

I don't even bother to make all the *_real_escape_string() functions, I've designed an input filtering class that does it all for me and I just call it like:

PHP Code:
$tuxxedo->input->doSqlSafe('p', Array('input1''input2''...')); 
The 'p' tells my class it has to clean post, it can also combine with more like 'pg' (POST + GET or simply r for REQUEST (POST / GET / COOKIE)) and then it modifies the global scope variables so I don't need to care about them when calling the query after.

Using something like this made my coding much easier ;)
__________________
Send a message via MSN to Kalle Send a message via Skype™ to Kalle
Kalle is offline  
Reply With Quote
Old 06-26-2008, 01:32 PM   #10 (permalink)
The Acquainted
 
drewbee's Avatar
 
Join Date: May 2008
Posts: 175
Thanks: 9
drewbee is on a distinguished road
Default

Yeah, I have a database abstraction class too. I just happened to use mysql_real_escape_string in the example for better understanding;

usually, my queries look like:

$this->db->query(sprintf("SELECT blah blah blah x = '%s'", $this->db->safe($_POST['var'])));

I love it because if all is well with the query, it just returns and is ready for processing but if an error happens (crucial) if I have debug turned on it will output what i passed in as the query, error message etc. In production, it sends an email to me so I can catch SQL Injection attempts and the like.

Plus should I ever change databases i simply need to change the code in the query()method. Gotta love it:)
__________________
There are No Stupid Questions. But there a LOT of Inquisitive Idiots.
Send a message via AIM to drewbee
drewbee is offline  
Reply With Quote
Old 07-03-2008, 01:18 PM   #11 (permalink)
The Visitor
 
Join Date: Nov 2007
Posts: 3
Thanks: 1
blakew is on a distinguished road
Default

I have been using my own escape functions on $_GET and $_POST before running them in queries but I am migrating over to the Zend Framework. Is this still necessary or does the Zend Framework take care of that for me?
blakew is offline  
Reply With Quote
Old 07-03-2008, 02:20 PM   #12 (permalink)
Jim
The Addict
 
Jim's Avatar
 
Join Date: Nov 2007
Location: the Netherlands
Posts: 281
Thanks: 2
Jim is on a distinguished road
Default

@ Blakew: How about running a test-query via the Zend Framework? That way you'll have your awnser in a few minutes :)

(I don't know)
__________________
Nunchaku! Who doesn't like martial arts? =)
Send a message via MSN to Jim Send a message via Skype™ to Jim
Jim is offline  
Reply With Quote
Reply



Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


All times are GMT. The time now is 10:46 AM.

 
     

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.1.0
Inactive Reminders By Icora Web Design