3

假设我有一个名为的文件query.sql,其中包含以下内容:

SELECT * FROM `users` WHERE `id`!=".$q->Num($_POST['id'])."

在我的 php-script 中,它有一个带有名为“id”的输入的 html 表单,我做了以下技巧:

$sql=file_get_contents('query.sql');
$query= eval("return \"$sql\";");
//here follows something like $mysqli->query($query); and so on..

不担心sql 注入,因为我使用的是准备好的语句并$q->Num执行is_int检查。但是以这种方式使用 eval 是否安全?

据我了解,这里实际评估的是“${_POST['id']}”,它评估为用户输入的某个字符串值。只有当我第二次评估这个字符串时,这才会变得危险。虽然我仅在用户的输入只是字符串时才评估字符串,并且不能被编译器解释为 php 代码,并且不可能进行 php 注入。

更新 感谢您提出不同的方法并强调需要使用准备好的语句。但这根本不是我的问题。我的问题都是关于 php-injections 的。这样使用 eval 不好吗?如果是,为什么?

4

4 回答 4

2

无需使用eval- 放入令牌,然后替换它:

// file query.sql
SELECT * FROM `users` WHERE `id`!="{id}";

//php
$sql = file_get_contents('query.sql');
$query = str_replace("{id}", $_POST['id'], $sql);

更新 不,这不安全。有人可以编辑你的query.sql脚本来做任何你想做的事情。您可能会说“该应用程序仅供内部使用”或“我已锁定权限”或其他任何内容 - 但归根结底,没有任何保证。

于 2013-01-23T16:41:10.713 回答
2

eval 语句 - 虽然我会尝试找到一种不使用 eval 的方法 - 对于 PHP 注入来说不容易受到攻击,因为$sql它包含在双引号中";不能用 PHP 中准备好的变量来结束这个引用。


我不关心 sql-injections 因为我使用的是准备好的语句

你不是吗?;) 你是!

为什么要使用“。”将 $id 添加到查询中。运算符(字符串操作)?如果你真的使用准备好的陈述的好处,我会期待像bindParam()

请注意准备好的语句如何防止 SQL 注入:SQL 查询语法与参数分开。所以服务器会

  1. 解析 SQL 查询
  2. 应用参数

由于在应用参数之前已经解析了查询,因此查询语法不能被参数操纵。

如果您准备使用“。”创建的 MySQL 查询。和外部输入,您可能容易受到 SQL 注入的攻击

你正在做的事情违背了准备好的陈述的原则

于 2013-01-23T16:39:40.940 回答
1

此答案的参考。

https://stackoverflow.com/a/951868/627868

eval() 的主要问题是:

潜在的不安全输入。传递不受信任的参数是一种失败的方式。确保参数(或其中的一部分)被完全信任通常不是一项简单的任务。

狡猾。使用 eval() 使代码更聪明,因此更难遵循。引用 Brian Kernighan 的话:“首先,调试的难度是编写代码的两倍。因此,如果你尽可能巧妙地编写代码,那么根据定义,你就不够聪明,无法调试它”

于 2013-01-23T16:37:05.610 回答
-1

让我们考虑以下代码:

$sql=file_get_contents('query.sql');
$query= eval("return \"$sql\";");

此时的危险点是:

  • 如果文件按照query.sql您的预期进行了修改,那么它可以用于执行程序中的任意代码。

  • 文件名显示为硬编码;如果不是这种情况,那么恶意用户可能会找到一种方法来加载意外文件(甚至可能来自远程站点的文件),从而再次导致任意代码执行。

  • 为此使用文件(而不是直接在程序中对 SQL 代码进行硬编码)的唯一原因是因为您想将其用作配置文件。这里的问题是这个文件中的语法对于 SQL 和 PHP 都是无效的。由于它在 中运行的方式eval(),它还要求语法完全正确。使用错误的报价或错过一个,它会爆炸。这可能会导致脆弱的代码,当配置稍微不正确时,它会严重失败而不是优雅地失败。

这里似乎没有直接的 SQL 注入攻击,但对于eval().

我曾亲自参与过代码存在的项目,这些代码的工作方式几乎与您描述的方式完全相同。直接导致系统中出现了一些非常讨厌的错误,如果不进行大规模重写,就很难纠正这些错误。我强烈建议您放弃这个想法,并按照评论中其他人的建议使用合理的模板机制。

于 2013-01-23T17:33:45.037 回答