I am working within an existing PHP program that has an established way that it dynamically loads certain PHP files for rendering HTML, by doing something basically this:
try {
$includeFilePath = realpath($mySubPath);
include $includeFilePath;
} catch (Exception $e) {
//imagine code that handles error
}
Assume that both file to be included and the file containing the above method are read-only and it's not permissible to alter these actual files on disk. However the above method may be overridden by extending the class it is part of. Meanwhile the file that's being included cannot be overridden gracefully because it does not contain classes, just a mix of PHP and HTML instructions (old school "phtml").
Now what I want to do instead is:
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
}
... where the modifyCode($str) method is defined elsewhere, and basically what it would do is (a) check the existing file against a pre-known hash checksum value to ensure it has not been modified, and (b) inject known safe code into it in order to add additional functionality to the application (it's "known safe" because we also would use a similar hash verification system on it and validate it).
Now my question is, assuming that security risks are not a concern here, is there any functional reason why eval would be problematic?
Note: no files we'd be including have closing html tags, only opening ones. I chose to use substr($str,5) to trim the opening tag as opposed to adding opening and closing tags as I've seen done elsewhere; that ought to work, right?
Explanation:
Since I anticipate a lot of you might wonder, "Why would you want to do that?", the reason is fairly complicated, but I'll try to explain it. The alternative to doing the above would be to include an entirely different file: one that already contains the custom code I want to use on top of the code from the base file. However the custom code I want to use is all additional code not present in the original base file, so we would end up with a fair amount of duplicated code instead of a more elegant solution where only the new code is "injected" into the base code prior to execution. Even still, using a new file that contains both the old and new code would technically work fine for now.
The problem is, though, in the future it's entirely possible that when we upgrade the base program, there will be changes to the original file (the one that's been effectively overridden by using my custom version of it). If that happens, our override would continue to rely on the previous version's code for that file, since the part of it that carried over from the original base system would no longer match up with the new version's normal default code for that file.
So, to address that problem, I want to go with the method of injecting the code using my custom modifyCode($str) method. That method can tell if there's been any updates to the original file (whether due to a hacker or due to system update) and it would be able to then warn the admin to check out why this code has changed, and issue an approval before executing the modified version of the code by updating the checksum with the hash of the new version of the file to be overridden. That way we can safely update the system and know it will fall back on the default behavior of the new version of the system rather than continue to run old code (which risks breaking the system) or adding mods intended for old versions of the code to new versions of the code that they haven't yet been tested on.
I hope that makes sense.