PHP pdo 的默认字符集是什么 mysql
PHP What is the default charset for pdo mysql
我正在阅读此页面上的二阶 MySQL 注入 Are PDO prepared statements sufficient to prevent SQL injection?。
它带来了很多关于 charset
的问题,我不确定我的代码对 MySQL 注入是否安全
在我的代码中,我在进行查询时从不使用字符集,
我就是这样
$pdo = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME, DB_USER, DB_PASSWORD, [PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_PERSISTENT => false]);
$stmt = $pdo->prepare("SELECT * FROM keywords WHERE keyword_name = ? || keyword_name = ?");
$stmt->execute(["hello","world"]);
rows = $stmt->fetchAll();
// show the data on webpage
$pdo = null;
我发现有两种不同的方法可以 set
pdo
中的 charset
$pdo = new PDO("mysql:host=" . DB_HOST . ";charset=utf8;......);
和
$pdo->exec("set names utf8");
根据@ircmaxell 对此 link Are PDO prepared statements sufficient to prevent SQL injection? 的回答。第一种方法应该用于防止二阶 SQL 注入...
但是我的代码中有 never set
charset
(如第一个代码所示)所以我有几个问题
- 对于我没有设置任何字符集的第一个代码,默认字符集是什么,它安全吗?
- 是否与数据库的字符集有关,我的数据库字符集(Collation)是
ut8_general_ci
(在phpmyadmin->operations中发现)?
-
utf8
字符集对于二阶注入是安全的,即 $pdo = new PDO("mysql:host=" . DB_HOST . ";charset=utf8;......);
已经完成了针对所有类型 mysql 注入的工作?
选项character_set_client
MySQL 用于客户端发送的查询和数据的字符集。
MySQL5.5、5.6 和 5.7 中默认为 utf8,8.0 中默认为 utf8mb4。
它也可以在您的 my.cnf 选项文件中全局更改,或者通过 SET NAMES 语句在每个会话中更改。
最好在连接时明确设置该选项,这样您就不必假定其默认值。
回复您的评论:
恐怕您混淆了两种不同的 SQL 注入案例。使用那些特定的五个字符集时存在风险,但它与二阶SQL注入无关。
字符集风险是由某些多字节字符集引起的。通常插入反斜杠来转义文字引号字符。但在某些字符集中,反斜杠字节会合并到前面的字节中,形成多字节字符。这使得报价未转义。
二阶SQL注入完全不同。它可以出现在任何字符集上。这是攻击者通过合法方式(例如填写表格)向您的数据库添加数据的时候。插入数据的处理没有错误。但是它们插入的值包含旨在利用稍后 SQL 查询的语法。
它依赖于开发人员相信已经安全保存到他们的数据库中的数据在某种程度上 "safe" 可以在没有适当参数化的情况下使用。
一个二阶 SQL 注入的例子,它只是偶然而非恶意的,可能是一个人有姓氏 "O'Reilly," 并且该名字被代码读取并用于后续查询。
$name = $db->query("SELECT last_name FROM people WHERE id = 123")->fetchColumn();
$sql = "SELECT * FROM accounts WHERE account_owner_last_name = '$name'";
如果名称中包含文字撇号,则会弄乱该示例中的第二个查询。
我正在阅读此页面上的二阶 MySQL 注入 Are PDO prepared statements sufficient to prevent SQL injection?。
它带来了很多关于 charset
的问题,我不确定我的代码对 MySQL 注入是否安全
在我的代码中,我在进行查询时从不使用字符集,
我就是这样
$pdo = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME, DB_USER, DB_PASSWORD, [PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_PERSISTENT => false]);
$stmt = $pdo->prepare("SELECT * FROM keywords WHERE keyword_name = ? || keyword_name = ?");
$stmt->execute(["hello","world"]);
rows = $stmt->fetchAll();
// show the data on webpage
$pdo = null;
我发现有两种不同的方法可以 set
pdo
charset
$pdo = new PDO("mysql:host=" . DB_HOST . ";charset=utf8;......);
和
$pdo->exec("set names utf8");
根据@ircmaxell 对此 link Are PDO prepared statements sufficient to prevent SQL injection? 的回答。第一种方法应该用于防止二阶 SQL 注入...
但是我的代码中有 never set
charset
(如第一个代码所示)所以我有几个问题
- 对于我没有设置任何字符集的第一个代码,默认字符集是什么,它安全吗?
- 是否与数据库的字符集有关,我的数据库字符集(Collation)是
ut8_general_ci
(在phpmyadmin->operations中发现)? -
utf8
字符集对于二阶注入是安全的,即$pdo = new PDO("mysql:host=" . DB_HOST . ";charset=utf8;......);
已经完成了针对所有类型 mysql 注入的工作?
选项character_set_client
MySQL 用于客户端发送的查询和数据的字符集。
MySQL5.5、5.6 和 5.7 中默认为 utf8,8.0 中默认为 utf8mb4。
它也可以在您的 my.cnf 选项文件中全局更改,或者通过 SET NAMES 语句在每个会话中更改。
最好在连接时明确设置该选项,这样您就不必假定其默认值。
回复您的评论:
恐怕您混淆了两种不同的 SQL 注入案例。使用那些特定的五个字符集时存在风险,但它与二阶SQL注入无关。
字符集风险是由某些多字节字符集引起的。通常插入反斜杠来转义文字引号字符。但在某些字符集中,反斜杠字节会合并到前面的字节中,形成多字节字符。这使得报价未转义。
二阶SQL注入完全不同。它可以出现在任何字符集上。这是攻击者通过合法方式(例如填写表格)向您的数据库添加数据的时候。插入数据的处理没有错误。但是它们插入的值包含旨在利用稍后 SQL 查询的语法。
它依赖于开发人员相信已经安全保存到他们的数据库中的数据在某种程度上 "safe" 可以在没有适当参数化的情况下使用。
一个二阶 SQL 注入的例子,它只是偶然而非恶意的,可能是一个人有姓氏 "O'Reilly," 并且该名字被代码读取并用于后续查询。
$name = $db->query("SELECT last_name FROM people WHERE id = 123")->fetchColumn();
$sql = "SELECT * FROM accounts WHERE account_owner_last_name = '$name'";
如果名称中包含文字撇号,则会弄乱该示例中的第二个查询。