I have been using sprintf() and mysql_real_escape_string() with a custom function called quote_smart as a way to prevent bad people from injecting malicious code into my SQL query strings. Everything went smoothly when I first started to switch all my web apps over to this syetem. Then I came to a search script that used MySQL's LIKE with wildcards.
Example:
SELECT * FROM catalog WHERE title LIKE '%$search%';
The problem with this is that sprintf() uses % as place holders for variables to be added.
Just in case you came to this article looking for a solution to prevent injection, I will show a basic example of using sprintf() with mysql_real_escape_string() and quote_smart:
$name = trim($_POST['name']);
$position = trim($_POST['position']);
$active="0";
if (isset($_POST['active'])) {
if ($_POST['active'] == "1") {
$active="1";
}
}
$query = sprintf("INSERT INTO table1 (name, position, active) VALUES (%s, %u, %u)",
quote_smart($name),
quote_smart($position),
quote_smart($active));
%s means the variable to be inserted is a string, %b would be binary, %u would be an decimal interger, etc etc. More information can be found in the
PHP Manual entry.
This is the quote_smart function I’ve been using (found all over the web):
function quote_smart($value) {
//stripslashes
if (get_magic_quotes_gpc()) {
$value = stripslashes($value);
}
//if it's not an number then put it in quotes.
if (!is_numeric($value)) {
$value = "'" . mysql_real_escape_string($value) . "'";
}
return $value;
}
That works pretty well. But what if you wanted to prevent people from injecting bad code into a search query? Both PHP’s sprintf() and MySQL’s LIKE use the percent sign (%). That stumped me the first time I came across this. I put my logic cap on and eventually figured out that I just have to put the percent signs for the LIKE wildcards inside the quote_smart argument!
$search = trim($_GET['search']);
$where = sprintf(" WHERE name LIKE %s",
quote_smart("%$search%"));
$query = "SELECT * FROM table1$where ORDER BY name;";
Like always, I was thinking the solution was going to be harder than it was. Hopefully this information will help other PHP Developers who were just as tired as I was when i first came across this.
More Information:
sprintf() - PHP Manual
mysql_real_escape_string() - PHP Manual
quote_smart example - One of many