我正在一个现有的PHP程序中工作,该程序具有一种既定的方式,它动态加载某些PHP文件以呈现HTML,通过基本上这样做:
try {
$includeFilePath = realpath($mySubPath);
include $includeFilePath;
} catch (Exception $e) {
//imagine code that handles error
}
假设要包含的文件和包含上述方法的文件都是只读的,并且不允许更改磁盘上的这些实际文件。但是,可以通过扩展它所属的类来覆盖上述方法。同时,包含的文件不能被优雅地覆盖,因为它不包含类,只是PHP和HTML指令的混合(旧学校" phtml")。
现在我要做的是:
try {
$includeFilePath = realpath($mySubPath);
$codeToModify = substr(file_get_contents($includeFilePath),5);
$codeToEval = $this->modifyCode($codeToModify);
eval($codeToExecute);
} catch (Exception $e) {
//imagine code that handles error
}
... modifyCode($ str)方法在别处定义,基本上它会做的是(a)根据预先知道的哈希校验和值检查现有文件以确保它尚未修改,并且(b)将已知的安全代码注入其中,以便为应用程序添加其他功能(它已经安全"因为我们也会使用类似的哈希验证系统它和验证它)。
现在我的问题是,假设这里不担心安全风险,是否有任何功能性原因导致eval存在问题?
注意:我们所包含的文件都没有关闭html标签,只有开放标签。我选择使用 substr($ str,5)来修剪开始标记,而不是添加开始和结束标记,因为我已经在别处看到过;应该工作,对吗?
说明:
因为我预计很多你可能会想,"你为什么要这样做?",原因相当复杂,但我会尝试解释它。执行上述操作的替代方法是包含一个完全不同的文件:一个已经包含我想在基本文件的代码之上使用的自定义代码的文件。但是,我想要使用的自定义代码是原始基本文件中不存在的所有其他代码,因此我们最终会得到相当数量的重复代码,而不是更优雅的解决方案,其中只有新代码被注入" 34;在执行之前进入基本代码。即使如此,使用包含旧代码和新代码的新文件在技术上也可以正常工作 for now 。
但问题是,将来我们升级基本程序时,原始文件(通过使用我的自定义有效覆盖的文件)将会发生变化,这是完全可能的。版本)。如果发生这种情况,我们的覆盖将继续依赖于该文件的以前版本的代码,因为从原始基本系统转移的部分将不再与该文件的新版本正常默认代码。
因此,为了解决这个问题,我想使用我的自定义 modifyCode($ str)方法注入代码的方法。该方法可以判断原始文件是否有任何更新(无论是由于黑客还是由于系统更新),然后它可以警告管理员检查此代码更改的原因,以及问题通过使用要覆盖的新版本文件的哈希更新校验和,在执行代码的修改版本之前获得批准。这样我们就可以安全地更新系统,并知道它将依赖于新版本系统的默认行为,而不是继续运行旧代码(这可能会破坏系统)或者为旧版本的代码添加mods他们尚未经过测试的新版代码。
我希望这是有道理的。
答案 0 :(得分:2)
没有。调用堆栈将被更改(错误消息,魔术常量__FILE__
)。可以破坏相对包含在包含的代码中。两个新变量$codeToModify
,$codeToEval
将出现在恶化的代码范围中。 Evaled代码不会被缓存。在evaled代码中解析错误不会中断整个脚本。可以使用Suhosin禁用Eval。