CodeIgniter如何对输入进行清理处理?

11

我正在构建一个Codeigniter应用程序,并尽力防止SQL注入。我使用Active Record方法来构造所有查询。我知道Active Record自动对输入进行了消毒,但我想知道它到底消毒了多少?它只是转义所有引号,还是做得更多?如何防止混淆的SQL注入或其他更高级的注入方式?

基本上,我正在寻找有关CI如何净化数据的详细解释。有人知道吗?


4
您考虑过查看CI的代码吗? - Beat
1
PDO 有人用过吗?http://www.php.net/pdo - Bailey Parker
1
CI(至少我所知道的版本)会主动“清理”输入(这意味着:修改!),而且是在任何控制器动作之前,在初始化请求时进行。有人还记得我们曾经多么讨厌magic_quotes_gpc吗? - Rudie
"Sanitizing" 数据完全取决于上下文。@Rudie: 这是一个配置设置,可以在所有 $_REQUEST 数据上全局运行 CI 的 xss_clean() 函数,但它会破坏原始数据。除非你是一个需要在学习如何 正确 处理转义、验证和处理输出时为实时应用提供安全保护的新手,否则我不建议使用它。 - Wesley Murch
虽然它远不及魔术引号那么糟糕,但请确保设置$config['global_xss_filtering'] = FALSE; - Wesley Murch
3个回答

9

MySQL驱动程序中的实现方式(完全一样):

  • 尝试使用mysql_real_escape_string()(99%的情况下都是这样)
  • 回退到mysql_escape_string()
  • 回退到addslashes()
  • 通过str_replace()手动转义LIKE条件中的%_

https://github.com/EllisLab/CodeIgniter/blob/develop/system/database/drivers/mysql/mysql_driver.php#L294

/**
* Escape String
*
* @access public
* @param string
* @param bool whether or not the string will be used in a LIKE condition
* @return string
*/
function escape_str($str, $like = FALSE)
{
    if (is_array($str))
    {
        foreach ($str as $key => $val)
        {
            $str[$key] = $this->escape_str($val, $like);
        }

        return $str;
    }

    if (function_exists('mysql_real_escape_string') AND is_resource($this->conn_id))
    {
        $str = mysql_real_escape_string($str, $this->conn_id);
    }
    elseif (function_exists('mysql_escape_string'))
    {
        $str = mysql_escape_string($str);
    }
    else
    {
        $str = addslashes($str);
    }

    // escape LIKE condition wildcards
    if ($like === TRUE)
    {
        $str = str_replace(array('%', '_'), array('\\%', '\\_'), $str);
    }

    return $str;
}

请注意,这只是转义字符,以便MySQL查询不会出错或做出意外的操作,并且仅在数据库查询的上下文中使用,以确保基于您传递给它的内容正确的语法。
并没有一种神奇的方法可以使所有数据都适用于任何上下文(如HTML、CSV或XML输出),而且即使你在考虑它:xss_clean()也不是一种万能解决方案,也不能百分之百地防范风险,有时它实际上是非常不合适的。Active Record类会自动进行查询转义,但对于其他所有情况,您应该根据所给定的上下文手动转义/清理数据,并将其应用于您的输出,而不是输入。

我不太确定您所说的“清理输出而不是输入”的意思。我认为我明白了如果我想要防止XSS攻击,但是如果我正在使用活动记录类构建mysql查询呢?那会是什么样子? - Erreth
无论您向AR类中添加什么内容,它最终都像mysql_real_escape_string一样安全,并具有转义表和数据库名称的额外安全性。 您不需要为了安全而对其进行净化,只需要进行有效性检查(整数值,最大长度,格式等)。 请参见http://stackoverflow.com/questions/4171115/is-mysql-real-escape-string-enough-to-anti-sql-injection/4171134#4171134,http://stackoverflow.com/questions/5288953-is-mysql-real-escape-string-broken - Wesley Murch

3
Active Record只对数据进行转义,不会对其他内容进行处理。通过转义可以防止SQL注入。然后在表单中使用验证类的验证功能。这样就能解决你的问题了。以下是CodeIgniter安全相关项的链接:

CodeIgniter用户指南——安全


我明白了。我有点使用表单验证类,但我想我应该在每个表单上都使用它。那么我一定要进行更积极的净化和验证。谢谢! - Erreth

1

您可以使用last_query()方法随时查看最新的查询。

$this->db->last_query()

您将看到查询的确切样子,以便验证是否已正确进行了清理。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接