2012-08-08 104 views
1

我读了很多关于常见SQL注入的东西,所以对如何解决它们感兴趣。在我刚刚使用 addslashes()之前,我认为它很合适。然后我发现mysql(i)_real_escape_string()addslashes()更有用和可信。从那时起我使用mysqli_real_escape_string(),但最近我陷入了一些我还没有真正理解的东西。 我有一些关于发送数据到MySQL和字符集的问题。 因此,我再次搜索,许多用户表示SET NAMES UTF8是让所有事情顺利进行的方法。 但后来我读到,使用该查询使得mysqli_real_escape_string()无法正常工作。转义sql语句的正确方法是什么?

所以毕竟我有点困惑。

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

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

mysqli_set_charset()使连接在指定字符集中通信的正确方法是什么?

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

感谢

+0

请编辑您的文章,并在'mysqli_real_escape_string()'处理之前和之后包含SQL示例。 – 2012-08-08 11:42:25

回答

0

只是为了纠正问题和答案中的大量错误信息。

  1. 不是“声明”,而是字符串文字。转义“SQL语句”是一种直接注入方式。只有字符串必须转义,而其他查询部分需要截然不同的格式和转义,对他们来说不会有丝毫好处。
  2. 所有转义/编码混乱只连接到一些边际编码,如GBK。使用UTF-8,您甚至可以使用addslashes()
  3. 由于5.3只要设置了DSN,PDO就可以设置客户端编码。

转义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()的正确途径,以指定的charset的连接进行通信?

当然。
必须使用HTML页面上使用的实际字符集。

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(); 
?> 
+0

不能使用此方法。我也想知道事情是如何工作的。 – Kei 2012-08-09 14:57:31

+0

@kei为什么你不能使用这种方法? – Fluffeh 2012-08-09 14:59:59

+0

正如我所说我想了解事情如何工作,所以我的问题是确切的。 然后,在这个项目中我们决定使用标准方法,所以我不能只是说“嘿,让我们用这种方式做所有事情吧”。 – Kei 2012-08-09 15:11:56

0

传递手动构造查询仅由于向后兼容性问题的支持。现代应用程序绝不应该这样做,而是使用预处理语句。尽管如此,如果您使用手动构建的查询已经死了,正确的方法是使用mysql_real_escape_string()并将编码设置为UTF-8。

你可以找到在OWASP网站的详细信息:https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet

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

相关问题