这个PHP / MySQL语句是否容易受到SQL注入攻击?

时间:2009-07-18 01:21:22

标签: php mysql sql-injection

应该是一个简单的问题,我只是不熟悉PHP语法,我想知道以下代码是否安全,不受SQL注入攻击?:

private function _getAllIngredients($animal = null, $type = null) {
    $ingredients = null;
    if($animal != null && $type != null) {
        $query = 'SELECT id, name, brief_description, description, 
                         food_type, ingredient_type, image, price,
                         created_on, updated_on
                    FROM ingredient
                   WHERE food_type = \'' . $animal . '\'
                     AND ingredient_type =\'' . $type . '\';';
        $rows = $this->query($query);

        if(count($rows) > 0) {
等等等等

我已经google了一下,似乎注射安全代码看起来与WHERE food_type = \''看起来不同。 $动物。 '\'语法在这里使用。

抱歉,我不知道这里使用的是哪个版本的PHP或MySQL,或者是否正在使用任何第三方库,任何有专业知识的人都可以提供任何输入吗?

更新

\ _在语句中服务的目的是什么?:

WHERE food_type = \'' . $animal . '\'  

在我的谷歌搜索中,我遇到了许多对mysql_real_escape_string的引用...这是一个防止SQL注入和其他恶意的功能吗?

班级声明是:

class DCIngredient extends SSDataController

那么可以想象mysql_real_escape_string包含在那里吗? 我应该要求查看SSDataController的实现吗?

7 个答案:

答案 0 :(得分:1)

$animal可以是一个包含'; drop table blah; --的字符串,所以是的,这对于SQL注入是可行的。

您应该考虑使用预先绑定参数的预准备语句,以便不会发生注入:

http://us3.php.net/pdo.prepared-statements

答案 1 :(得分:1)

此代码易受SQL注入攻击。

“\”仅转义引号字符,否则PHP认为引号将结束您的(sql-)字符串。

同样,当您将整个SQL字符串传递给 SSDataControler 类时,如果已注入准备好的字符串,则无法再避免攻击。

所以类SSDataControler在设计上被破坏(易受攻击)。

尝试更安全的东西:

$db_connection = new mysqli("host", "user", "pass", "db");
$statement = $db_connection->prepare("SELECT id, name, brief_description, description, 
                     food_type, ingredient_type, image, price,
                     created_on, updated_on
                FROM ingredient
               WHERE food_type = ?
                 AND ingredient_type = ?;';");
$statement->bind_param("s", $animal);
$statement->bind_param("s", $type);
$statement->execute();

通过使用 bind 方法,您可以指定参数的类型(s表示字符串,i表示整数等),您永远不会再考虑sql注入

答案 2 :(得分:1)

你最好还是使用mysql_real_escape_string来摆脱任何可以执行drop table或执行任何其他任意代码的东西。

在SQL语句中放置值的位置无关紧要,在任何时候它都可以有';'在它中,它立即结束声明并开始一个新的声明,这意味着黑客几乎可以做任何他想做的事情。

为了安全起见,只需将值包装在mysql_real_escape_string($ variable)中。所以:

WHERE Something='".mysql_real_escape_string($variable)."'

答案 3 :(得分:0)

它很脆弱。如果我通过:'\'; DROP TABLE成分;选择 \'' 作为$ type,poof,goodbye成分表。

答案 4 :(得分:0)

如果它是私人功能,那种。如果您担心有权访问源代码注入SQL的人,可以通过更简单的方法来实现其目标。我建议在使用前将参数传递给mysql_real_escape_string(),以保证安全。像这样:

private function _getAllIngredients($animal = null, $type = null) {
        $animal = mysql_real_escape_string($animal);
        $type   = mysql_real_escape_string($type);
        ...
        }

为了更加安全,您甚至可以使用htmlentities()标志将其传递给ENT_QUOTES - 这也有助于防范XSS类型的内容,除非您要放置这些数据库条目的内容进入<script>标签。

但你能做的最安全的事情就是编写自己的消毒功能,它可以充分利用各种技术,并且可以让你轻松抵御将来可能出现的新威胁。

答案 5 :(得分:0)

Re:UPDATE

\''用于将变量括在引号中,因此当它进入SQL时,空格不会破坏任何内容。 IE:Where Something = Cold Turkey会以错误结束,其中Something ='Cold Turkey'不会。

此外,类扩展不会影响MySQL语句的组合方式。

答案 6 :(得分:-2)

如果用户或任何第三方无论如何都要将$ animal的值注入你的系统(他们可能会这样做),那么是的,它可以用于sql注入。

解决这个问题的方法是做

private function _getAllIngredients($animal = null, $type = null) {
    $ingredients = null;
    if($animal != null && $type != null) {
        $query = 'SELECT id, name, brief_description, description, 
                         food_type, ingredient_type, image, price,
                         created_on, updated_on
                    FROM ingredient
        $rows = $this->query($query);
        if(count($rows) > 0) {
        if($rows['animal'] == $animal && $rows['ingredient_type'] == $type) {

注意:我从sql中删除了WHERE语句,并将if语句添加到循环