在Joomla中防止SQL注入的最佳方法

时间:2013-05-07 10:32:48

标签: php mysql joomla

我从POST方法获取变量,并使用Joomla 2.5在MySQL上查询它们。

最安全的方法是什么?目前我正在使用带有mysql_real_escape_string的JRequest :: getVar。这是对的吗?

  1. $ _ POST with mysql_real_escape_string

    $ password = mysql_real_escape_string($ _ POST [“pwd”]));

  2. JRequest :: getVar with mysql_real_escape_string

    $ password = mysql_real_escape_string(JRequest :: getVar('pwd','','post'));

  3. JRequest :: getVar

    $ password = JRequest :: getVar('pwd','','post');

  4. JInput

    $ password = $ jinput-> get('pwd','','STRING');

  5. 使用mysql_real_escape_string进行JInput

    $ password = mysql_real_escape_string($ jinput-> get('pwd','','STRING'));

  6. 还是其他什么?

    编辑1:

    我找到了另一个使用mysql_real_escape_string http://docs.joomla.org/API15:JDatabaseMySQL/getEscaped

    转义字符的方法

    这是我的查询代码。

    $db = JFactory::getDbo();
    $query = $db->getQuery(true);
    $query->select(array('username', 'password', 'state','name'));
    $query->from('#__dbusers');
    $query->where('username = \''.$loginUsername.'\' AND password = \''.$loginPassword.'\' AND state > -1');
    $db->setQuery($query);
    $results = $db->loadObjectList();
    

    编辑2:MySQL的框架11.1 escape()方法

    public function escape($text, $extra = false)
    {
        $result = mysql_real_escape_string($text, $this->getConnection());
    
        if ($extra)
        {
            $result = addcslashes($result, '%_');
        }
    
        return $result;
    }
    

    因为escape()使用mysql_real_escape_string()使用如下所示是否安全?

    $ loginUsername = mysql_real_escape_string(JRequest :: getVar('user','','post','STRING'));

2 个答案:

答案 0 :(得分:12)

在Joomla!中,你从不直接访问任何超级全局。此外,您应始终区分传入和传出的数据。因此,要从请求中获取传入值,请使用

$password = $jinput->get('pwd', '', 'STRING');

JInput是正确的选择; JRequest已弃用,将来会被移除。) 现在你有一个干净的价值。它准备用PHP处理。

接下来要使用SQL查询中的值(传出),你必须正确地转义它。

$query->where("username = " . $db->quote($loginUsername) . " AND password = " . $db->quote($loginPassword) . " AND state > -1");

$db->escape()不同,$db->quote()添加了底层数据库引擎所需的引号。

为什么不一步处理这个?

好吧,你可能在某些时候想要另一种类型的输出,例如。在一个视图中(即使密码不是这个例子的最佳选择,我使用它来保持一致性):

echo $this->escape($password); // applies html_specialchars in HTML views

因此,最好始终尽可能地避开所需的地方。对于传入数据,这是在检索之后立即发送/打印之前的传出数据。

答案 1 :(得分:2)

我认为这个问题隐藏了一些误解,所以我会详细说明。

首先,mysql_real_escape_string()是遗留mysql扩展中的一个函数。就这样:

  • 不再维护
  • 它会在PHP / 5.5中触发E_DEPRECATED警告
  • 未来的PHP版本将不再提供

我不是在谈论这个功能,我在谈论整个扩展。

此外,如果您未使用已弃用的旧版mysql扩展,则无法使用它。如果你使用PDO,MySQLi,ADODB或其他任何东西,它就没用了,它也不会起作用。毋庸置疑,如果您使用的是SQLite,Oracle,SQL Server或PostgreSQL,它也无法工作。所有数据库扩展都有(或应该有)替代工具。

现在,Joomla框架提供了自己的数据库类。您似乎正在使用version 2.5,转义函数为JDatabase::quote()。这就是Joomla中该功能的工作原理。我真的不明白为什么你认为它可能不可靠但是,如果你这么认为,你最好放弃完整的JDatabase并使用别的东西。你不能做的是混合来自不同设计的一起工作的东西。

修改:我抓住了Joomla 2.5并查看了源代码。 quote()函数是escape()的包装器,它属于抽象类JDatabase,它实现了一个接口JDatabaseInterface。有三种实现方式:

  • JDatabaseMySQL

    /**
     * Method to escape a string for usage in an SQL statement.
     *
     * @param   string   $text   The string to be escaped.
     * @param   boolean  $extra  Optional parameter to provide extra escaping.
     *
     * @return  string  The escaped string.
     *
     * @since   11.1
     */
    public function escape($text, $extra = false)
    {
        $result = mysql_real_escape_string($text, $this->getConnection());
    
        if ($extra)
        {
            $result = addcslashes($result, '%_');
        }
    
        return $result;
    }
    
  • JDatabaseMySQLi

    /**
     * Method to escape a string for usage in an SQL statement.
     *
     * @param   string   $text   The string to be escaped.
     * @param   boolean  $extra  Optional parameter to provide extra escaping.
     *
     * @return  string  The escaped string.
     *
     * @since   11.1
     */
    public function escape($text, $extra = false)
    {
        $result = mysqli_real_escape_string($this->getConnection(), $text);
    
        if ($extra)
        {
            $result = addcslashes($result, '%_');
        }
    
        return $result;
    }
    
  • JDatabaseSQLSrv

    /**
     * Method to escape a string for usage in an SQL statement.
     *
     * The escaping for MSSQL isn't handled in the driver though that would be nice.  Because of this we need
     * to handle the escaping ourselves.
     *
     * @param   string   $text   The string to be escaped.
     * @param   boolean  $extra  Optional parameter to provide extra escaping.
     *
     * @return  string  The escaped string.
     *
     * @since   11.1
     */
    public function escape($text, $extra = false)
    {
        $result = addslashes($text);
        $result = str_replace("\'", "''", $result);
        $result = str_replace('\"', '"', $result);
        $result = str_replace('\\\/', '/', $result);
        $result = str_replace('\\\\', '\\', $result);
    
    
        if ($extra)
        {
            // We need the below str_replace since the search in sql server doesn't recognize _ character.
            $result = str_replace('_', '[_]', $result);
        }
    
        return $result;
    }
    

那么,quote()mysql_real_escape_string()相同吗?显然不是。它是否也这样做?是。

相关问题