|
|
|
|
|
|
IT Security and Insecurity Portal |
|
|
Protect varchar(255) |
|
Posted: Mon Jul 26, 2004 10:30 am |
|
|
shmk |
Active user |
|
|
Joined: Jul 22, 2004 |
Posts: 25 |
|
|
|
|
|
|
|
I write a piece of code that take from MySQL database a varchar(255) [e-mails, usernames, adresses...], how can protect from SQL Injection ?
I used strip_tags($variable)... is there a better command ? |
|
|
|
|
|
|
|
|
Posted: Tue Jul 27, 2004 10:11 pm |
|
|
madman |
Active user |
|
|
Joined: May 24, 2004 |
Posts: 46 |
|
|
|
|
|
|
|
Example:
Code: | $sql = "INSERT INTO table (strfield) VALUES ('" . quotemeta(addslashes($strfield)) ."')"; |
Or create a special function like this:
Code: | function qstr($text) {
if (strlen($text) == 0) return $text;
while (preg_match('/\\\'/', $text)) $text = str_replace("\\\'", "'", $text);
return quotemeta(addslashes($text));
}
$sql = "INSERT INTO table (strfield) VALUES ('" . qstr($strfield) ."')"; |
But this function is union-proof:
Code: | function nounion($text) {
if (strlen($text) == 0) return $text;
return preg_replace_callback('/(\'|u|n|i|o)/i', create_function('$match', 'return "&#".strval(ord($match)).";";'), $text);
}
$sql = "SELECT * FROM table WHERE strfield = ''" . nounion($strfield) ."'"; |
However, to avoid parser warning during SQL injection (and reveal your physical path), keep in touch with variables types. For any of string type, use the function above. For numeric types, always evaluate through appropriate functions (intval, floatval, etc or using typecasting) then passed directly to the sql query strings. E.g:
Code: | $int = intval($int);
$float = (float)$float;
$sql = "SELECT * FROM table WHERE int_val = '$int' AND float_val = '$float'"; |
|
|
_________________ ch88rs,
madman |
|
|
|
|
|
heh |
|
Posted: Tue Jul 27, 2004 10:18 pm |
|
|
icenix |
Advanced user |
|
|
Joined: May 13, 2004 |
Posts: 106 |
Location: Australia |
|
|
|
|
|
|
perfectly executed madman
lol sounds like you answered that well |
|
|
|
|
Posted: Sat Jul 31, 2004 9:14 am |
|
|
shmk |
Active user |
|
|
Joined: Jul 22, 2004 |
Posts: 25 |
|
|
|
|
|
|
|
Thanks 4 the Help
I have 2 last questions:
- I have to call "nounion($text)" for every varchar variable before INSERTing in db and after SELECTing from database, or only before INSERT ?
- Why in some PHPNuke patched modules (like encyclopedia admin) using only a "stripslashes(FixQuotes($text))" instead of a full preg_replace function ? Is a hole in security ?
Thx 4 Helping a Noob |
|
|
|
|
|
|
|
|
Posted: Sat Jul 31, 2004 8:33 pm |
|
|
madman |
Active user |
|
|
Joined: May 24, 2004 |
Posts: 46 |
|
|
|
|
|
|
|
shmk wrote: | - I have to call "nounion($text)" for every varchar variable before INSERTing in db and after SELECTing from database, or only before INSERT ? |
UNION only affect to SELECT, so you can filter any variables through nounion() function only at SELECT query strings.
shmk wrote: | - Why in some PHPNuke patched modules (like encyclopedia admin) using only a "stripslashes(FixQuotes($text))" instead of a full preg_replace function ? Is a hole in security ? |
Because of simple reason, stripslashes() is a build-in PHP function and FixQuotes() is availables with most PHP-Nuke version (defined in mainfile.php). The patch maker keep the compatibility with most possible version (and upgrades) without worrying about "function not defined" error.
shmk wrote: | Thx 4 Helping a Noob |
You're welcome. |
|
_________________ ch88rs,
madman |
|
|
|
|
|
|
|
Posted: Sun Aug 01, 2004 10:11 pm |
|
|
shmk |
Active user |
|
|
Joined: Jul 22, 2004 |
Posts: 25 |
|
|
|
|
|
|
|
Some other questions:
1. A piece of code like:
$vartot = $var1 + $var2;
need some quotes to protect it ?
2. An update like:
$sql = "UPDATE table SET var=var+1, var2=var2-1 WHERE ...";
need something for protection ?
3. To protect a variable that get only value 0/1 I can use intval() or is there a better command ?
Thx Again |
|
|
|
|
|
|
|
|
Posted: Sun Aug 01, 2004 10:58 pm |
|
|
madman |
Active user |
|
|
Joined: May 24, 2004 |
Posts: 46 |
|
|
|
|
|
|
|
shmk wrote: | 1. A piece of code like:
$vartot = $var1 + $var2;
need some quotes to protect it ? |
You may put a variable that hold numeric computation results using enclosed single-quotes inside query string. This applies to mySQL but another SQL might has different behavior. An example of integer computation:
Code: | $vartot = intval($var1) + intval($var2);
$vartot2 = intval($var3 + $var4);
$sql = "UPDATE table SET tot='$vartot', tot2='$vartot2' WHERE ..."; |
shmk wrote: | 2. An update like:
$sql = "UPDATE table SET var=var+1, var2=var2-1 WHERE ...";
need something for protection ? |
No you don't, as long as all statements are comes from internal SQL syntax and commands. Only "external" variables from PHP required to be "sanitized" or filtered into proper variable types. This example no need to filtered at all:
Code: | $sql = "UPDATE table SET var=var+1, var2=var2-1, var3=UNIX_TIMESTAMP(var4)+86400 WHERE ..."; |
shmk wrote: | 3. To protect a variable that get only value 0/1 I can use intval() or is there a better command ? |
Better if you evaluated the value before passed to SQL query string. This is an example code that evaluating input value, restrict to either 0 or 1, or fall to 0 (default) if does not meet the condition. I give you two safe codes for similar purpose, both are faster than if..then statement.
Code: | $value = (preg_match(/^[0-1]{1}$/', "$value")) ? intval($value) : 0;
$value2 = ($value2) ? 1 : 0;
$sql = "UPDATE table SET bool='$value', bool2='$value2' WHERE ..."; |
The first checking code ($value assignment) always expecting $value variable must be containing either 0 or 1 (one digit), otherwise 0 (default) will be used. The second code ($value2 assignment) can evaluate any types assigned to $value2 variable; numeric, string, array, etc. If $value2 is not-0 or not-null, or not-false or not-empty or not-"" or not-emptyarray, etc then $value2 will be assigned to 1 otherwise 0. Both are safe to be passed to SQL query because the values always either 0 or 1. |
|
_________________ ch88rs,
madman |
|
|
|
|
|
|
|
Posted: Mon Aug 02, 2004 9:19 am |
|
|
shmk |
Active user |
|
|
Joined: Jul 22, 2004 |
Posts: 25 |
|
|
|
|
|
|
|
MANY MANY thanks |
|
|
|
|
Posted: Mon Aug 02, 2004 4:23 pm |
|
|
shmk |
Active user |
|
|
Joined: Jul 22, 2004 |
Posts: 25 |
|
|
|
|
|
|
|
Always me... I hope that this time is my last question
I'm using a link like:
/modules.php?name=ModuleName&op=FunctionName&variable=username
To protect the username I used
$username = stripslashes(FixQuotes(substr($username, 0, 24)))
All this concatened code can protect my variable and module or is completly useless ? |
|
|
|
|
|
|
|
|
Posted: Mon Aug 02, 2004 8:39 pm |
|
|
madman |
Active user |
|
|
Joined: May 24, 2004 |
Posts: 46 |
|
|
|
|
|
|
|
shmk wrote: | Always me... I hope that this time is my last question |
I hope not.
I love to discuss about security. I don't care even this thread being get millions page views and thousands replies.
shmk wrote: | To protect the username I used
$username = stripslashes(FixQuotes(substr($username, 0, 24)))
All this concatened code can protect my variable and module or is completly useless ? |
To be honest, I never be sure to use FixQuotes() to filter string vars before passed to SQL query strings. The main functionality of this function is to replace a single-quote into two single-quotes (may work or not with some database) and two backslashes followed by a single-quote characters into a single-quote. This mean, your code above isn't safe to be passed into SQL query. Instead, use this:
Code: | $username = addslashes(FixQuotes($username)); |
Because we talking in the context of username string, we have to know how PHP-Nuke handles this string. From various version of PHP-Nuke (at least since 6.5), I found that accepted username as evaluated from Your_Account module always expecting only these following characters: alphanumerics (a-z), numeric (0-9), dashes (-), and underscores. Username's characters other than these rules will be rejected.
The problem is, because PHP-Nuke grown to become a popular CMS, then we have many add-ons or modules that overrides this basic security principal. People demanding for "strange" characters to their nick, such as "W@r@+3", "m/dm/n", "5h|^|x", or something similar. This makes things more complicated because not all these characters can be passed safely into database queries.
To accomodate this, we have to use more complex code. This is an example:
Code: | $username = quotemeta(addslashes(FixQuotes($username))); |
If we want to stick on default PHP-Nuke username behavior, we can filter username using this code:
Code: | $username = (preg_match('/^[a-z0-9_-]+$/i', $username)) ? $username : '';
if ($username == '') die('invalid username'); |
The last code is more secure but has disadvantages, such as your existing users that already use "strange" characters will never be accepted or loose some site's benefits. The following code still allow user to pass but their username are filtered already and may look different than original:
Code: | $username = preg_replace('[^a-z0-9_-]*/i', '', $username)); |
I hope this is useful. |
|
_________________ ch88rs,
madman |
|
|
|
|
|
|
|
Posted: Mon Aug 02, 2004 9:45 pm |
|
|
shmk |
Active user |
|
|
Joined: Jul 22, 2004 |
Posts: 25 |
|
|
|
|
|
|
|
I'll use this one becuase some users have special character on his names
$username = quotemeta(addslashes(FixQuotes($username)));
So substr() with this other function became useless ? |
|
|
|
|
Posted: Mon Aug 02, 2004 10:50 pm |
|
|
madman |
Active user |
|
|
Joined: May 24, 2004 |
Posts: 46 |
|
|
|
|
|
|
|
No, you still need substr.
My codes above was only considered as example ( oh, the truth is I'm too lazy for typing )
Here the working code:
Code: | $username = quotemeta(addslashes(FixQuotes(substr($username,0,25)))); |
|
|
_________________ ch88rs,
madman |
|
|
|
Posted: Tue Aug 03, 2004 9:27 am |
|
|
shmk |
Active user |
|
|
Joined: Jul 22, 2004 |
Posts: 25 |
|
|
|
|
|
|
|
after all this I have a REALLY stupid question (come in my mind after see some PHPNuke module)...
Variable taked from database but not used later for sql INSERT or SELECT (only "echo" on page), have to be sanitize ?
Omg I'm feel like a stupid, but thx again
PS: the quotemeta(addslashes($strfield)) is union-proof ?
Be "union-proof" is usefull only if I use WHERE statement or in every INSERT/SELECT ? |
|
|
|
|
|
|
|
|
Posted: Tue Aug 03, 2004 7:59 pm |
|
|
madman |
Active user |
|
|
Joined: May 24, 2004 |
Posts: 46 |
|
|
|
|
|
|
|
shmk wrote: | Variable taked from database but not used later for sql INSERT or SELECT (only "echo" on page), have to be sanitize ? |
No, unless you do care with "dangerous" html tagging on the text string. This example will sanitize scripting tags in a string retrieved from database:
Code: | $result = $db->sql_query("SELECT msg FROM table WHERE cond=true");
if ($result)
{
list($msg) = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
}
else
{
$msg = '';
}
if ($msg != '') $msg = preg_replace('/\<(\/?script)[^\>]*\>/si', '<\\1>', $msg); |
Echo command will always filtering escaped characters and displayed properly.
shmk wrote: | PS: the quotemeta(addslashes($strfield)) is union-proof ? |
No. You need to use nounion() function that I was given.
shmk wrote: | Be "union-proof" is usefull only if I use WHERE statement or in every INSERT/SELECT ? |
Use nounion() function only on SELECT query statements and on every external variables (any PHP variables with dollar sign) considered as string types. |
|
_________________ ch88rs,
madman |
|
|
|
|
|
|
|
Posted: Tue Aug 03, 2004 9:32 pm |
|
|
shmk |
Active user |
|
|
Joined: Jul 22, 2004 |
Posts: 25 |
|
|
|
|
|
|
|
Thx again... saturday i'll leave for a 2 weeks holiday so I don't disturbe you no more
Good Holiday |
|
|
|
|
www.waraxe.us Forum Index -> Php
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
All times are GMT
Page 1 of 2
Goto page 1, 2Next
|
|
|
Powered by phpBB © 2001-2008 phpBB Group
|
|
|
|
|