PHP 什么是 pdo mysql 的默认字符集



我正在此页面上阅读有关二阶MySQL注入的信息 PDO准备的语句是否足以防止SQL注入?

它带来了许多关于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;

我发现有两种不同的方法可以在 pdo 中setcharset

$pdo = new PDO("mysql:host=" . DB_HOST . ";charset=utf8;......);

$pdo->exec("set names utf8");

根据此链接上的@ircmaxell答案 PDO准备的语句是否足以防止SQL注入? 第一种方法应该用来防止二阶SQL注入...

但是我已经在我的代码中never setcharset(如第一个代码所示(,所以我有几个问题

  1. 对于我没有设置任何字符集的第一个代码,默认字符集会是什么,它是否安全?
  2. 它是否与数据库的字符集有关,因为我的数据库字符集(排序规则(ut8_general_ci(在phpmyadmin->操作中发现(?
  3. utf8字符集对于二阶注入是否安全,即$pdo = new PDO("mysql:host=" . DB_HOST . ";charset=utf8;......);对所有类型的 MySQL 注入都完成了工作?

选项character_set_client是MySQL用于客户端发送的查询和数据字符集的选项。

默认为 MySQL 5.5、5.6 和 5.7 中的 utf8,以及 8.0 中的 utf8mb4。

也可以在 my.cnf 选项文件中全局更改它,也可以通过 SET NAMES 语句按会话更改它。

最好在连接时显式设置该选项,这样就不必假定其默认值。


重新发表您的评论:

恐怕你混淆了两种不同的SQL注入情况。使用这五个特定的字符集时存在风险,但它与二阶 SQL 注入无关。

字符集风险是由于某些多字节字符集造成的。通常插入反斜杠以转义文字引号字符。但在某些字符集中,反斜杠字节会合并到前面的字节中,形成一个多字节字符。这句话没有逃脱。

二阶SQL注入是完全不同的。它可以发生在任何字符集上。这是攻击者通过合法方式(例如填写表单(将数据添加到您的数据库时。插入数据的处理没有错误。但是它们插入的值包含旨在利用某些后续 SQL 查询的语法。

它依赖于开发人员相信已经安全保存到其数据库中的数据在没有适当参数化的情况下以某种方式"安全"使用。

二阶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'";

如果名称包含文字撇号,则会弄乱该示例中的第二个查询。

最新更新