【问题标题】:Is this a bug in Codeigniter active record?这是 Codeigniter 活动记录中的错误吗?
【发布时间】:2013-12-30 11:30:43
【问题描述】:

如果我使用 codeigniter 活动记录从 db 表中获取数据,如下所示:

$where = array("first_name" => "John", "age <" => 30, "status" => "active");
$this->db->where($where);
$query = $this->db->get("my_table");

die(var_dump($this->db->last_query())); // displays the query string

此代码将生成以下查询字符串:

SELECT * FROM (`my_table`) WHERE `first_name` = 'John' AND `age` < 30 AND `status` = 'active'

现在,如果我将字符串分配给 $where 而不是数组,如下所示:

$where = "first_name = 'John' AND age < 30 AND status = 'active'";

然后会产生如下查询字符串:

SELECT * FROM (`my_table`) WHERE `first_name` = 'John' AND age < 30 AND status = 'active'

请注意,当将字符串分配给$where 时,codeigniter 仅在第一个字段的名称周围添加了backticks (``),在我们的例子中是first_name。另一方面,当我们将数组分配给$where时,codeigniter 在所有字段名称周围添加了反引号

我的问题:这是 codeigniter 中的错误还是正常?如果我使用以下代码来防止 codeigniter 在字段名称周围添加反引号:

$this->db->where($where, null, false);

这将产生以下查询字符串:

SELECT * FROM (`my_table`) WHERE first_name = 'John' AND age < 30 AND status = 'active'

以这种方式编写where 部分是否有任何风险或缺点?

【问题讨论】:

    标签: php codeigniter activerecord


    【解决方案1】:

    问:这是 codeigniter 的 bug 还是正常现象?

    • 是的,这是一个错误,但并不严重。

    问:写 $this->db->where($where, null, false) 有什么风险或弊端吗?

    此代码本身没有风险。如果您在 WHERE 子句中进行硬编码,那么可能永远不会有问题。唯一会出现问题的情况是当您捕获用户输入时,例如表单或 URL,而这将是您必须手动清理的内容

    清理 where 子句非常重要。

    错误示例:易受 SQL 注入攻击

    $fname  = $_POST['fname']; 
    $age    = $_POST['age'];
    $status = $_POST['status'];
    
    $where  = sprintf("first_name = '%s' AND age < %d AND status = '%s'",$fname,$age,$status);
    $this->db->where($where, null, false);
    

    更好的例子:不那么脆弱

    $fname  = (string) mysql_real_escape_string($_POST['fname']);
    $age    = (int) $_POST['age'];
    $status = (string) mysql_real_escape_string($_POST['status']);
    
    $where  = sprintf("first_name = '%s' AND age < %d AND status = '%s'",$fname,$age,$status);
    $this->db->where($where, null, false);
    

    到目前为止你所做的一切都没有错,它只会给你带来更多的负担来清理你的 where 子句,因为使用 $this->db->where($where, null, false) 将删除内置卫生。

    简而言之:如果您的 where 子句将提供用户输入,则使用此方法会使您最初更容易受到 SQL 注入的攻击。但是没有什么是您不能通过一些卫生功能快速收紧的。

    我知道这个答案很完美,但希望它有所帮助。

    【讨论】:

      【解决方案2】:
      $this->db->where($where, null, false);
      

      这是一种危险的方式,因为 CodeIgniter 不会尝试使用反引号来保护您的字段或表名。

      对于缺少反引号,这似乎是错误,因为一些堆栈溢出用户在使用 group_concat 选项生成时也提到了查询中的问题。这是一个例子。

      Weird backticks behaviour in Active Record in Code Igniter 2.0.3

      【讨论】:

        【解决方案3】:

        不,至少在这种情况下,这不应该是一个问题。反引号允许字段名称中的替代字符。由于年龄和状态都不包含任何可能导致问题的字符,因此反引号是不必要的。此外,反引号的使用因所使用的 SQL 服务器而异。

        请参阅此问题以供参考:Using backticks around field names

        【讨论】:

          【解决方案4】:

          在 codeigniter 活动记录中,您必须用单引号定义列名(如果您的字符串是双引号)。清楚地看到这个特征。请参阅系统文件夹中的where 代码。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-06-13
            • 1970-01-01
            • 2014-02-22
            • 2011-01-13
            • 2014-08-15
            • 1970-01-01
            相关资源
            最近更新 更多