使用eval这样安全吗?

时间:2013-01-23 16:32:26

标签: php security eval

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

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

在我的php脚本中,它有一个html表单,输入名为" id"在其中,我做了以下技巧:

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

不关心关于sql-injections,因为我使用预准备语句并且$q->Num执行is_int检查。 但以这种方式使用eval是否安全?

据我了解,这里实际评估的是" $ {_ POST [' id']}"并且它会侵蚀用户输入的某个字符串值。只有当我第二次评估这个字符串时,这才会变得危险。虽然我只是在用户的输入只是字符串时才使用字符串,并且不能通过编译器将其解释为php代码,并且不能进行php注入。

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

3 个答案:

答案 0 :(得分:2)

eval语句 - 虽然我试图找到一种不使用eval的方法 - 但是不容易注入PHP,因为$sql包含在双引号"中;人们不能用PHP中的预备变量来结束这种引用。


  

由于我正在使用预备语句

,因此我不会对sql注入感到遗憾

不是吗? ;) 你是!

为什么要使用'。'将$ id添加到查询中运算符(字符串操作)?如果你真正使用预备语句带来的好处,我会期望像bindParam()

注意如何预处理语句防止SQL注入:SQL查询语法与参数分开。所以服务器会

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

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

    你在做什么会打败预备陈述的原则

答案 1 :(得分: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脚本来执行您想要的任何操作。您可能会说“应用程序仅限内部”,或“我已锁定权限”或其他任何内容 - 但在一天结束时无法保证。

答案 2 :(得分:-1)

让我们考虑以下代码:

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

危险点是:

  • 如果文件query.sql已根据您的预期进行修改,则可以使用它来执行程序中的任意代码。

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

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

这里似乎没有直接的SQL注入攻击,但对于eval()而言,这实际上是您最不担心的。

我个人曾在代码存在的项目中工作,这些项​​目的工作方式与您所描述的完全一致。系统中存在一些非常讨厌的错误,直接导致这些错误,并且在没有批量重写的情况下很难纠正。我强烈建议退回这个想法并使用合理的模板机制,而不是其他人在评论中所建议的。