【问题标题】:PHP What is the default charset for pdo mysqlPHP pdo mysql 的默认字符集是什么
【发布时间】:2019-02-07 06:09:54
【问题描述】:

我在这个页面Are PDO prepared statements sufficient to prevent SQL injection? 上阅读了关于二阶 MySQL 注入的信息。

它带来了很多关于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 在此链接Are PDO prepared statements sufficient to prevent SQL injection? 上的回答。第一种方法应该用来防止二阶SQL注入...

但我的代码中有never set charset(如第一个代码所示),所以我有几个问题

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

【问题讨论】:

    标签: php mysql pdo utf-8 sql-injection


    【解决方案1】:

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

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

    【讨论】:

    • 谢谢,在链接stackoverflow.com/questions/134099/… 上显示there are 5 such encodings supported in MySQL 5.6 by default: big5, cp932, gb2312, gbk and sjis. We'll select gbk here.,如果默认字符集是uf8 或utf8mb4,那么它应该已经可以安全地防止二阶MySQL 注入了,
    猜你喜欢
    • 1970-01-01
    • 2016-09-18
    • 2011-01-04
    • 2011-09-17
    • 2011-05-04
    • 2010-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多