7

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

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

  1. $_POST 与 mysql_real_escape_string

    $password = mysql_real_escape_string($_POST["pwd"]));

  2. JRequest::getVar 与 mysql_real_escape_string

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

  3. JRequest::getVar

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

  4. 输入法

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

  5. 带有 mysql_real_escape_string 的 JInput

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

或者是其他东西 ?

编辑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 的 Framework 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'));

4

2 回答 2

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

因此,最好的做法是始终尽可能靠近需要的地方进行逃生。对于传入数据,这是在检索之后立即进行的,对于即将发送/打印之前的传出数据。

于 2013-05-07T13:03:10.873 回答
2

I think the question hides a few misconceptions so I'll elaborate a proper answer.

First of all, mysql_real_escape_string() is a function from the legacy mysql extension. As such:

  • It's no longer maintained
  • It'll trigger E_DEPRECATED warnings in PHP/5.5
  • It'll no longer be available in future PHP releases

And I'm not talking about the function, I'm talking about the entire extension.

Additionally, you cannot use it if you are not using the deprecated legacy mysql extension. If you use PDO, MySQLi, ADODB or anything else, it's useless and it won't work. Needless to say, it won't work either if you are using SQLite, Oracle, SQL Server or PostgreSQL. All DB extensions have (or should have) an alternative tool.

Now, the Joomla framework provides its own database classes. You appear to be using version 2.5 and the escape function is JDatabase::quote(). That's how the feature works in Joomla. I don't really understand why you think it might be unreliable but, if you think so, you'd better drop the complete JDatabase and use something else. What you cannot do is to mix stuff from different extensions that aren't designed to work together.

Edit: I've grabbed Joomla 2.5 and had a look at the source code. The quote() function is a wrapper for escape(), which belongs to an abstract class, JDatabase, that implements an interface, JDatabaseInterface. There are three implementations:

  • 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;
    }
    

So, is quote() the same as mysql_real_escape_string()? Obviously not. Does it do the same? Yes.

于 2013-05-07T11:29:28.830 回答