0

应该是一个简单的问题,我只是不熟悉 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) {

等等等等等等

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

抱歉,我不知道这里使用的是什么版本的 PHP 或 MySQL,或者是否正在使用任何 3rd 方库,任何有专业知识的人都可以提供任何意见吗?

更新

\ 在语句中的作用是什么?:

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

在我的谷歌搜索中,我遇到了很多关于mysql_real_escape_string......这是防止 SQL 注入和其他讨厌的功能的功能吗?

类声明是:

class DCIngredient extends SSDataController

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

4

7 回答 7

1

$animal可以是一个字符串,其中包含'; drop table blah; --所以是的,这对 SQL 注入很容易。

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

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

于 2009-07-18T01:24:07.040 回答
1

的,此代码易受 SQL 注入攻击。

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

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

因此,SSDDataControler 类在设计上被破坏(易受攻击)。

尝试像这样更安全的东西:

$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 注入

于 2009-07-18T01:24:47.757 回答
1

无论如何,您也可以使用 mysql_real_escape_string 来摆脱任何可以执行删除表或执行任何其他任意代码的操作。

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

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

WHERE Something='".mysql_real_escape_string($variable)."'
于 2009-07-18T01:27:06.740 回答
0

它很脆弱。如果我通过了:'\'; DROP TABLE 成分;SELECT \'' as $type,噗,再见成分表。

于 2009-07-18T01:25:17.880 回答
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>标签中。

但是您可以做的最安全的事情是编写自己的清理函数,这将充分利用各种技术,还可以让您轻松防御未来可能出现的新威胁。

于 2009-07-18T01:29:53.447 回答
0

回复:更新

\'' 用于将变量括在引号中,这样当它通过 SQL 时,空格不会破坏任何内容。IE:Something=Cold Turkey 会以错误结尾,而 Something='Cold Turkey' 不会。

此外,类扩展不会影响您如何组合 MySQL 语句。

于 2009-07-18T01:33:53.863 回答
-2

如果用户或任何第 3 方无论如何都将 $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 语句添加到循环中

于 2009-07-18T01:28:19.703 回答