php初学者安全输入

时间:2010-07-14 15:48:24

标签: php

  

可能重复:
  mysql_fetch_array() expects parameter 1 to be resource, boolean given in select

我需要一些帮助。

我有这个问题:

$order = isset($_GET['order']) ? mysql_real_escape_string($_GET['order']) : 'title';
$query = mysql_query("SELECT * FROM entry ORDER BY $order ASC");

您可以按标题,日期或作者订购。

但是,如果某人给了$ order,那就是:

Warning: mysql_fetch_assoc() expects parameter 1 to be resource, boolean given in C:\wamp\www\entries.php on line 20

如何摆脱此错误消息?

由于

9 个答案:

答案 0 :(得分:6)

在order by子句中不能包含colu\'nname之类的内容 - 这意味着mysql_real_escape_string不是解决方案。

相反,您应该检查$order实际上是否包含表中某列的名称 - 如果不是,则不运行查询。


例如,您可以使用以下内容:

if (!in_array($_GET['order'], array('column1', 'title', 'id', 'other_column'))) {
    // deal with the problem
    // and don't run the query
    // because $_GET['order'] is not one of the allowed values
}

答案 1 :(得分:2)

您不应将列标识符视为与字符串文字相同。在您的示例中,您最终可能会使用SQL:

SELECT * FROM entry ORDER BY O\'Hare ASC

这会导致任何SQL解析器出现语法错误。

我有一些提示:

  1. 将SQL放入变量中,不要尝试在mysql_query()的调用中构建它。如果使用变量,现在可以检查SQL字符串,这样可以更容易地捕获上面的错误。

    $sql = "SELECT * FROM entry ORDER BY $order ASC";
    // here you can log $sql, or output to Firebug, etc.
    $query = mysql_query($sql);
    
  2. 检查返回值是否表示错误。您需要检查错误状态,因为它们可能由于多种原因而发生。

    $query = mysql_query($sql);
    if ($query === false) {
      die(mysql_error());
    }
    
  3. 对{em>字符串使用mysql_real_escape_string() - 而不是列名,表名,SQL关键字等。我使用的是一个映射{{1}的关联数组输入有效的列名,所以我知道它是安全的。这也允许您在app参数中使用与列名称不同的值。

    $_GET

答案 2 :(得分:1)

不要向用户提供任何订单选项,但事实并非如此。如果您使用的是文本输入,请将其替换为选择。只要列存在,就不应该出错。

您可以在交换机案例中对每个选项进行硬编码:

switch($_GET['order']){
    case 'date' : 
         $order = 'date';
         break;
    case 'author' : 
         $order = 'author';
         break;
    default
         $order = 'title';
}

这也会阻止SQL注入。

答案 3 :(得分:0)

它预计$ order中的列名称,如果它不是一个,它将失败。尝试回显$ query。

答案 4 :(得分:0)

您应该从可能接受的值列表中检查$ _GET ['order']的值。

在尝试获取行之前,您还应检查是否($ query)以确定查询是否有效。

答案 5 :(得分:0)

$checker = array('title', 'date', 'author')

$order = isset($_GET['order']) ? mysql_real_escape_string($_GET['order']) : 'title';

if (in_array($_GET['order'], $checker) {
  $query = mysql_query("SELECT * FROM entry ORDER BY $order ASC");
}

答案 6 :(得分:0)

如果不符合您的预期,您应检查有效值并向用户显示错误。

一个简单的例子,

$valid_values = array("title", "date", "author");

if (in_array($_GET['order'], $valid_values))
{
    // Your db stuff
}
else
{
    echo "The order value you gave wasn't valid. Please try another.";
}

答案 7 :(得分:0)

您还需要确保$_GET["order"]包含有效列 您的问题来自于获取无效的列名,您放入查询。 mysql_query()函数在出错时返回false,并且您的错误消息告诉您将其传递给mysql_fetch_assoc来电。

尝试类似

的内容
$columns = array("id", "name", "title");
if (false === ($key = array_search($_GET["column"], $columns))) {
  $column = "title";
} else {
  $column = $columns[$key];
}
$query = "SELECT * FROM entry ORDER BY {$column};";

我没有使用mysql_real_escape_string,因为此方法还会检查输入是否在有效选项列表中。

答案 8 :(得分:0)

在运行查询之前检查$ order是否为列名

$order = isset($_GET['order']) ? mysql_real_escape_string($_GET['order']) : 'title';
//Run a check here, before the query
$query = mysql_query("SELECT * FROM entry ORDER BY $order ASC");

mysql_real_escape_string也看起来处于不正确的位置。只是一个抬头