mysql_real_escape_string 不够好?

发布于 2024-10-21 19:22:19 字数 700 浏览 2 评论 0原文

因此,即使使用 mysql_real_escape_string 清理数据,也可以使用 %27 进行 SQL 注入

%27) SQL INJECTION HERE %2F*

该怎么办?

编辑示例:

$sql = sprintf("SELECT *, MATCH(post) AGAINST ('%s*' IN BOOLEAN MODE) AS score FROM Posts WHERE MATCH(post) AGAINST('%s*' IN BOOLEAN MODE)",
                mysql_real_escape_string($_GET['searchterm']),
                mysql_real_escape_string($_GET['searchterm']));

$results = $db->queryAsArray($sql);

如果您将 %27) SQL INJECTION HERE %2F* 传递到搜索词查询字符串,我会在页面上输出:

您的 SQL 语法有错误; 检查对应的手册 您的 MySQL 服务器版本 在 'BOOLEAN 附近使用正确的语法 MODE)' 在第 1 行

感谢大家在 db 类中发现问题。

So using %27 you can just SQL inject even though data is sanitized with mysql_real_escape_string

%27) SQL INJECTION HERE %2F*

What to do?

Edit with example:

$sql = sprintf("SELECT *, MATCH(post) AGAINST ('%s*' IN BOOLEAN MODE) AS score FROM Posts WHERE MATCH(post) AGAINST('%s*' IN BOOLEAN MODE)",
                mysql_real_escape_string($_GET['searchterm']),
                mysql_real_escape_string($_GET['searchterm']));

$results = $db->queryAsArray($sql);

If you pass in %27) SQL INJECTION HERE %2F* to the searchterm querystring, I get outputted on the page:

You have an error in your SQL syntax;
check the manual that corresponds to
your MySQL server version for the
right syntax to use near 'BOOLEAN
MODE)' at line 1

Thanks everyone for finding the problem in the db class..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

烏雲後面有陽光 2024-10-28 19:22:19

从方法名称 queryAsArray 推理,您似乎正在使用 这个DbBase类来自MySQL函数手册页的注释。如果是这样,则 query 方法会从转义引号中删除转义字符:

function query($sql, &$records = null){
    $sql = str_replace(array('\\"', "\\'"), array('"', "'"), $sql);
    // …
}

那么您的示例有效(我简化了它)就不是奇迹了:

$input = "', BAD SQL INJECTION --";

$sql = "SELECT '".mysql_real_escape_string($input)."'";
var_dump($sql);  // string(33) "SELECT '\', BAD SQL INJECTION --'"
//                      everything’s OK ↑

$sql = str_replace(array('\\"', "\\'"), array('"', "'"), $sql);
var_dump($sql);  // string(32) "SELECT '', BAD SQL INJECTION --'"
//                                Oops! ↑

Reasoning from the method name queryAsArray, it seems that you’re using this DbBase class from the comments of the MySQL functions manual page. If so, it’s the query method that removes the escape character from the escaped quotation marks:

function query($sql, &$records = null){
    $sql = str_replace(array('\\"', "\\'"), array('"', "'"), $sql);
    // …
}

Then it’s not a miracle that your example works (I simplified it):

$input = "', BAD SQL INJECTION --";

$sql = "SELECT '".mysql_real_escape_string($input)."'";
var_dump($sql);  // string(33) "SELECT '\', BAD SQL INJECTION --'"
//                      everything’s OK ↑

$sql = str_replace(array('\\"', "\\'"), array('"', "'"), $sql);
var_dump($sql);  // string(32) "SELECT '', BAD SQL INJECTION --'"
//                                Oops! ↑
晨光如昨 2024-10-28 19:22:19

我们手册中提到的注释已被标记为删除。一旦它传播到我们网络中的所有镜像,它将不再出现在官方文档中。

~ Daniel P. Brown
  Network Infrastructure Manager
  http://php.net/

The note mentioned in our manual has been marked for deletion. Once it propagates across all of the mirrors in our network, it will no longer appear attached to the official documentation.

~ Daniel P. Brown
  Network Infrastructure Manager
  http://php.net/
活雷疯 2024-10-28 19:22:19

最好根本不要构建这样的语句,而是使用 mysqli 或 PDO 来使用带有参数的查询。这将解决 MySQL 注入的问题,并且有一天(不幸的是,还没有)它也会执行得更好,因为查询是在没有参数的情况下缓存的,这意味着您在缓存中只有一个查询,而不是几十个不同的查询,因为单个输入值一直在变化。其他数据库很早就使用了这一点,但 MySQL 自最新版本以来只是设法不让参数化查询变慢。

%27 实际上会终止字符串,这看起来不太合理。这似乎更像是在字符串中嵌入引号的可能性,但我不确定。

可以肯定的是,我决定牺牲我的服务器来测试它。当我在输入字段和文本区域中输入 %27 并使用 mysql_real_escape_string 转义然后插入数据库时​​,我没有收到任何错误。文本 %27 刚刚插入。所以完全没问题。

It's best to not to build statements like this at all, and instead use queries with parameters using mysqli or PDO. This will deal with the problem of MySQL injection and one day (not yet, unfortunately) it will perform better too, because the queries are cached without parameters, meaning you only got one query in the cache instead of dozens of different queries because of a single input value changing all the time. Other databases make use of this since long, but MySQL just managed not to make parameterized queries slower since the latest version.

It doesn't look plausible that %27 will actually terminate the string. It seems more like a possibility to embed quotes inside a string, but I'm not sure.

To be sure, I decided to sacrificed my server and test this. When I enter %27 in an input field and textarea that are escaped using mysql_real_escape_string and are then inserted in the database, I get no errors. The text %27 is just inserted. So no problem at all.

寂寞美少年 2024-10-28 19:22:19

您错了。这里不可能进行注射。

通过遵循这三个简单的规则,

  1. 客户端的编码由 mysql_set_charset() 正确设置,
  2. 数据被转义 using mysql_real_escape_string()
  3. 并用引号引起来,

您可以确保不可能进行注入

You are wrong. No injection possible here.

By following these three simple rules

  1. Client's encoding properly set by mysql_set_charset()
  2. Data being escaped using mysql_real_escape_string()
  3. And enclosed in quotes

you can be sure that no injection possible

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文