为什么makefile中的eval邪恶

时间:2016-08-30 13:46:05

标签: makefile eval

我有几个人告诉我,eval在makefile中是邪恶的。我最初接受了他们的话,但现在我开始质疑它了。采取以下makefile:

%.o:
    $(eval targ=$*)
    echo making $targ

%.p:
    echo making $*

我了解如果您之后执行了make "a;blah;".o,那么它会运行blah(可能是rm -rf \,或更糟)。但是,如果您运行make "a;blah;".p,则在没有eval的情况下会得到相同的结果。此外,如果您有权运行make,您还可以直接运行blah,并且根本不需要运行make。所以现在我想知道,eval在makefile中是否真的增加了安全风险,如果是,应该避免什么?

1 个答案:

答案 0 :(得分:1)

为什么eval邪恶?

因为它赋予了你实际上并不想赋予这种力量的事物的语言能力。

通常它被用作"穷人的元编程"构造一些代码然后运行它。通常它看起来像eval("do stuff with " + thing) - 并且事物只在运行时才知道,因为它是从外部提供的。

但是,如果您不确定thing属于您在该特定情况下需要的一小部分语言(例如,是一个有效名称的字符串表示),您的代码将授予对你不打算的东西的权限。例如,如果thing"apples; steal all oranges",那么橙子就会被盗。

如果 确保thing属于您实际需要的某种语言子集,则会出现2个问题:

  • 您正在重新实现非DRY的语言功能(解析源),并且通常是滥用语言的标志。
  • 如果你诉诸于此意味着更简单的手段并不适合你的用例有点复杂,这会使你的输入更难以验证。

因此,使用eval打破安全性并采取足够的预防措施以确保其安全是非常容易的,这就是为什么如果您看到eval您应该怀疑的原因可能的安全漏洞。这只是一种启发式方法,而不是一种法律。

eval是一个非常强大的工具 - 与整个语言一样强大 - 并且用它来拍摄你的腿太容易了。

为什么eval的这种特殊用途不好?

想象一个需要制作一些依赖于文件的步骤的任务。任务可以使用各种文件完成。 (例如,用户为将要启动并集成到现有网络基础架构中的计算机提供Virtualbox映像) 想象一下,懒惰的管理员自动执行这项任务 - 所有命令都写在一个makefile中,因为它比sh脚本更合适(一些步骤依赖于其他步骤,有时候不需要重新完成)。 管理员确保所有命令都正确且正确,并且已授予sudoers使用该特定makefile运行make的权限。现在,如果makefile包含与您类似的字符串,那么使用正确制作的Virtualbox图像名称,您可以使用pwn系统,或类似的东西。

当然,我不得不伸长远来使这个特例成为一个问题,但无论如何它都是一个潜在的问题。

Makefile通常提供简单的合同:你命名目标和一些非常具体的东西 - 用makefile编写 - 完成。使用eval你使用它的方式提供了一个不同的合同:与上面相同的东西,但你也可以用一些复杂的方式提供命令,它们也会被执行。

您可以尝试通过确保$*不会造成任何问题来修补合同。如果你想尽可能保持目标名称的灵活性,那么用语言来描述这意味着什么可能是一个有趣的练习。

否则,您应该了解扩展合同,如果扩展会导致问题,请不要使用此类解决方案。如果您打算让尽可能多的人重复使用您的解决方案,那么您应该尽可能减少合同问题。