安全地使用PHP exec函数

时间:2012-01-19 18:25:46

标签: php ffmpeg

我正在编写一个PHP脚本,用于通过exec()函数运行可执行文件(ffmpeg.exe)。问题是我已经读过使用exec()函数可能存在安全风险,应该尽可能避免。我一直在研究如何安全地运行exec()函数,我唯一能遇到的是使用escapeshellcmd或escapeshellarg过滤命令字符串。我想知道的是,在使用exec()函数时是否可以进一步提高安全性,或者是否存在exec()的安全替代方法。任何帮助将不胜感激。

这是我的代码;

define('FFMPEG_LIBRARY', 'c:\\ffmpeg7\\ffmpeg\\bin\\ffmpeg ');
$transcode_string = FFMPEG_LIBRARY." -i " . $srcFile . " -acodec libmp3lame -ab 64k -ar 22050 -ac 1 -vcodec libx264 -b:v 250k -r 30 -f flv -y " . $destFile;
$transcode_string = escapeshellcmd($transcode_string);
exec($transcode_string);

$ srcFile基本上是用于转码的视频,而$ destFile是我想要创建的输出文件。

2 个答案:

答案 0 :(得分:3)

exec本身不是问题,问题是当你把它放到exec()中时,你绝对不应该接受用户输入。你应该总是使用escapeshellarg()但是如果你确实需要接受用户输入,你应该首先进行自己的排毒和操作。

你的代码究竟是什么?没有看到在这件事上没有更多的话要说。

更新

如果$ srcFile是上传文件的名称,那么你应该改变它。@ preinheimer的评论包含一个好主意,你可以调用uniqid();并将$ srcFile重命名为,然后你知道你有一个字母数字文件名,无论他们上传了什么。将$ srcFile更改为新的uniqid()'d文件名,你就可以了。

关于$ dstFile,将其设置为其他唯一的,你可以调用uniqid();再次,或使用当前时间。

如果您同时执行这两项操作,那么您根本就不会接受用户输入,而且您的脚本将非常安全。

答案 1 :(得分:3)

  

使用exec()函数可能存在安全风险,应尽可能避免使用。

这有点概括 - 使用exec()构建安全解决方案是完全可能的。但这确实很难:执行外部程序有很多陷阱,特别是如果你将外部参数传递给它们。

正如你所说,第一步是使用escapeshellarg()来逃避一切,以防止注入其他可能有害的命令。

然后问题是输入错误值的损坏会在被调用的程序中造成什么。例如,

  • 对200000 x 200000像素的大视频运行ffmpeg操作可能会导致服务器挂断,因为该调用会尝试分配不可能的内存量。因此,您必须清理用户可以输入的大小值,如果它们太大或不是数字,则退出。

  • 恶意用户可以告诉ffmpeg使用配置文件并尝试从中创建视频,可能导致配置文件用作输出,因此您需要限制用户可以使用的文件路径范围指定。

依旧等等。

此外,您需要考虑通过少量请求来杀死服务器的可能性。如果我每秒向PHP脚本发送50个请求,然后又调用复杂的ffmpeg命令,该怎么办?服务器可能很容易在负担下解决,您可能希望防止这种情况发生。

所以:使用exec()时没有固有的安全问题,但是传递给它的每个传入参数都需要仔细查看。