What is a proper way to filter parameters passed in functions? The goal is to make the function secure, especially when working with a database.
Example:
function user_profile($user_id)
{
//get user's profile data
$query = "SELECT * FROM `users` WHERE `user_id` = $user_id";
}
$user_id
is a URI se开发者_运维技巧gment.
Other general examples are welcomed.
To escape strings, use the same method you'd use outside the function:
$user_id= mysql_real_escape_string($user_id);
If you're expecting the value to be, for example, an integer and would like to return error from the function if it isn't, you can do something like:
if (!is_int($user_id)) {
return FALSE;
}
else // do you query
Or if you expect it to match some specific pattern, do so with preg_match()
:
// For example, $user_id should be 4 letters and 4 numbers
if (!preg_match("/^[A-Z]{4}[0-9]{4}$/", $user_id)) {
return FALSE;
}
else // do you query
There's a couple of ways. The OLD way is to use mysql_real_escape_string()
. However, many people nowadays complain bitterly about this, and say the proper way is to use prepared statements.
Create a filter class to handle all your filtering. Before you pass the variable into the function as a parameter, pass it through the filter class first. Or run the parameter through the filter class in the first line of your function.
So essentially, you're creating an abstract layer that 'filters'.
So the kind of filtering you're wanting to do in your scenario is to filter against sql injection/code injections.
So create a wrapper with this filter class around the mysql_real_escape_string()
function.
The idea is to create an extensible filter class that can be used anywhere else in your application that is conceptually high level enough to handle all future needs.
final class Filter
{
static public function sqlInjections($some_parameter)
{
// my code to prevent injections by filtering $some_parameter
return mysql_real_escape_string($some_paramters);
}
static public function badWords()
{
// code in the future that can be added to filter bad words
}
}
call it like so $filtered_parameter = Filter::sqlInjections($some_paramter);
If your user_id
field is a string in your database, then, you'll use mysql_real_escape_string()
, or mysqli_real_escape_string()
, or PDO::quote()
-- depending on the API you're working with :
$query = "SELECT * FROM `users` WHERE `user_id` = '"
. mysql_real_escape_string($user_id) . "'";
or
$query = "SELECT * FROM `users` WHERE `user_id` = '"
. mysqli_real_escape_string($user_id) . "'";
or, with PDO -- provided that $db
is a PDO
object :
$query = "SELECT * FROM `users` WHERE `user_id` = '"
. $db->quote($user_id) . "'";
But, if it's an integer, you should make sure that the value passed to it is indeed an integer -- which is generally done using intval()
:
$query = "SELECT * FROM `users` WHERE `user_id` = "
. intval($user_id);
Edit: I just realized you said it's an URL segment -- so, not an integer. I don't delete this idea, though: it might help someone else who would read this answer.
Another solution would be to not build a query containing that value -- and use prepared statements.
See :
- For mysqli :
mysqli::prepare()
- And with PDO :
PDO::prepare()
Use mysql_real_escape_string()
$query = "SELECT * FROM users WHERE user_id = '" . mysql_real_escape_string($user_id) . "'";
You can do two or Three complementary ways to prevent SQL injection:
The escape functions commented above.
Query the other way around:
function user_profile($user_id) { //get user's profile data $query = "SELECT * FROM
users
WHERE {$user_id} =user_id
"; }User prepare and execute functions/methods if your database engine allow it http://php.net/manual/en/pdo.prepare.php http://www.php.net/manual/en/pdostatement.execute.php
精彩评论