什么是转义sql语句的正确方法?

时间:2012-08-08 11:39:06

标签: php character-encoding escaping mysqli exploit

我阅读了很多关于常见sql注入的事情,所以对如何修复它们感兴趣。在我刚刚使用之前 addslashes()(非常)认为它适合。然后我发现mysql(i)_real_escape_string()addslashes()更有用和更可靠。从那以后我使用mysqli_real_escape_string(),但最近我遇到了一些我还没有真正理解的东西。 我有一些关于将数据发送到mysql和字符集的问题。 因此,我再一次搜索,并且许多用户说SET NAMES UTF8是使一切正确的方式。 但后来我读到使用该查询会使mysqli_real_escape_string()无效。

所以我毕竟有点困惑。

转义sql语句的正确方法是什么?

使用SET NAMES UTF8有哪些可能的漏洞利用?

mysqli_set_charset()是否是在指定的字符集中进行连接通信的正确方法?

使用mysqli_sey_charset()是mysql的内部变量在这个过程中被改变了吗?

由于

4 个答案:

答案 0 :(得分:2)

您可以使用mysqli prepared statements来避免SQL注入 - 而无需担心字符集编码。

链接中的一个例子:

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$city = "Amersfoort";

/* create a prepared statement */
if ($stmt = $mysqli->prepare("SELECT District FROM City WHERE Name=?")) {

    /* bind parameters for markers */
    $stmt->bind_param("s", $city);

    /* execute query */
    $stmt->execute();

    /* bind result variables */
    $stmt->bind_result($district);

    /* fetch value */
    $stmt->fetch();

    printf("%s is in district %s\n", $city, $district);

    /* close statement */
    $stmt->close();
}

/* close connection */
$mysqli->close();
?>

答案 1 :(得分:0)

由于向后兼容性问题,仅支持传递手动构造的查询。现代应用程序绝不应该这样做,而是使用预处理语句。

话虽如此,如果您已经开始使用手动构造的查询,正确的方法是使用mysql_real_escape_string(),并将编码设置为UTF-8。

您可以在OWASP网站上找到更多详细信息:https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet

答案 2 :(得分:0)

只要您明确设置连接对象的字符集,就应该没问题:

mysql_set_charset('utf8', $db); // for mysql
$db->set_charset('utf8'); // for mysqli

字符集的相同问题适用于PDO预处理语句,因此建议使用PDO,但在这种情况下它不会使您安全。

mysqli_real_escape_string()与定义的字符集一起使用没有问题。请注意您使用UTF-8作为连接对象以及HTML页面,这样可以避免很多问题。

我发现有关此主题的最佳解释,来自PHP作者ircmacell,一次用于mysql_real_escape_string(),一次用于PDO

答案 3 :(得分:0)

只是纠正了问题和答案中的许多错误信息。

  1. 不是“语句”而是字符串文字。转义“SQL语句”是一种直接的注入方式。只有字符串必须被转义,而其他查询部分需要不同的,绝对不同的格式和转义对他们来说没有丝毫的好处。
  2. 所有逃避/编码混乱只与GBK等边缘编码有关。使用UTF-8,您甚至可以使用addslashes()
  3. 由于5.3 PDO可以设置客户端编码,只要它在DSN中设置即可。
  4.   

    转义sql语句的正确方法是什么?

    In PHP when submitting strings to the database should I take care of illegal characters using htmlspecialchars() or use a regular expression?

      

    使用SET NAMES UTF8有什么可能的漏洞?

      

    mysqli_set_charset()是否是在指定字符集中进行连接通信的正确方法?

    不确定。
    它必须与HTML页面上使用的实际字符集一起提供。

相关问题