寒钟书在编一个项目的时候,需要使用system命令来执行操作。system函数是什么呢?先上函数原型:
string system ( string$command [, int&$return_var ] )
同 C 版本的 system() 函数一样, 本函数执行 command 参数所指定的命令, 并且输出执行结果。
如果 PHP 运行在服务器模块中, system() 函数还会尝试在每行输出完毕之后, 自动刷新 web 服务器的输出缓存。
如果要获取一个命令未经任何处理的 原始输出, 请使用 passthru() 函数。
(以上摘自php官方文档)
好吧,这个system函数居然什么shell命令都能执行…那么安全性就是很大的一个问题啊~~
精简一下这个问题,我想要运行的命令是docker run -dt –rm centos $command,而这个command却是用户传入的数据,而且不可避免的会有特殊字符。居正大大有云:用户传入的数据都是不可信的。所以究竟应该怎么过滤呢?
Way 1:
$rum_command = “docker run -dt –rm centos $command”;
显然不行…
Way 2:
$rum_command = “docker run -dt –rm centos ‘$command’ “;
然而可以这样构造command:’;echo 1;’
成功绕过。
还是不行。
Way 3:
就在我冥思苦想之时,忽然发现一个神奇的php函数——escapeshellarg
string escapeshellarg ( string$arg )
escapeshellarg() 将给字符串增加一个单引号并且能引用或者转码任何已经存在的单引号,这样以确保能够直接将一个字符串传入 shell 函数,并且还是确保安全的。对于用户输入的部分参数就应该使用这个函数。shell 函数包含 exec(), system() 执行运算符 。
(这不就是为我准备的嘛,PHP 万岁!)
所以,实际上我们可以这样写:$rum_command = “docker run -dt –rm centos “.escapeshellarg($command).” “;
Well Done.
本文首发于淀粉月刊:https://dfkan.com
原作者:寒中书
发布时间:2018年6月29日
网友评论