V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
xiaoz
V2EX  ›  问与答

请教一个 PHP 安全问题

  •  
  •   xiaoz · 2018-11-11 21:27:34 +08:00 · 1918 次点击
    这是一个创建于 2205 天前的主题,其中的信息可能已经有所发展或是发生改变。

    某些项目不得已需要使用system()函数调用系统命令,在 PHP 5.4 之前可以开启安全模式(safe_mode=On)并设置只能运行指定目录下的命令。

    但是 5.4 之后已经废弃安全模式,那么 PHP 7 有什么办法让system()函数只能运行指定命令。比如骇客上传了一个恶意的 PHP 文件,执行system("cat /etc/passwd"),有什么办法让这个命令无法运行?

    14 条回复    2018-11-12 08:08:08 +08:00
    jybox
        1
    jybox  
       2018-11-11 21:43:10 +08:00   ❤️ 1
    在 PHP-FPM 里设置单独的用户来运行 PHP,为各类文件设置正确的所有者和权限。
    2pang
        2
    2pang  
       2018-11-11 21:47:07 +08:00 via iPhone   ❤️ 1
    不用 root 用户来运行 php ls 的回答是对的
    xiaoz
        3
    xiaoz  
    OP
       2018-11-11 21:53:54 +08:00
    @jybox @2pang 目前已经是单独的用户来运行 PHP,但是 Linux 下很多命令都是具有执行权限的。就拿 cat 命令来说,cat 的权限如下:-rwxr-xr-x,那么就代码任何用户来执行 cat 命令都具有权限。
    ysc3839
        4
    ysc3839  
       2018-11-11 21:55:40 +08:00   ❤️ 1
    如果项目是只有一个 index.php 作为入口的话,把 HTTP 服务器配置成只有 index.php 才交给 PHP 处理,同时设置好文件权限,禁止写入新文件,这样可以避免上传文件然后执行。
    代码中不使用 eval 之类的执行代码的函数,可以避免直接执行代码。
    t6attack
        5
    t6attack  
       2018-11-11 21:56:19 +08:00   ❤️ 1
    nobody 的权限最低。但 cat /etc/passwd 这个命令连 nobody 都是可以执行的。
    如果无法读取 /etc/passwd,linux 系统将无法运转。不获取名册,如何知道自己是谁?
    xiaoz
        6
    xiaoz  
    OP
       2018-11-11 22:00:17 +08:00
    @t6attack 是的呀,Linux 几乎很多命令任何用户都有 x (执行权限)
    zwl2012
        7
    zwl2012  
       2018-11-11 22:39:25 +08:00 via iPhone   ❤️ 1
    命令传入 system 前过滤一遍呗,设置可执行白名单即可
    dapang1221
        8
    dapang1221  
       2018-11-11 22:41:57 +08:00   ❤️ 1
    不知道会调用多少命令,少的话可以封装一下,不暴露给外面
    xiaoz
        9
    xiaoz  
    OP
       2018-11-11 22:42:47 +08:00
    @zwl2012 正常开发肯定会过滤,但是如果程序存在上传漏洞这个过滤不了吧。“设置可执行白名单”能详细描述一下吗?
    xiaoz
        10
    xiaoz  
    OP
       2018-11-11 22:44:52 +08:00
    @dapang1221 需要执行的命令不多,就几个。您的意思是 PHP 封装还是其它方式封装呢?我的理解是 PHP 封装可能意义不大,因为已经开放 system 函数,骇客可利用上传漏洞使用该函数。如果是其它方式封装能提供一个思路吗,谢谢。
    zwl2012
        11
    zwl2012  
       2018-11-11 23:30:31 +08:00 via iPhone
    你要这样谨慎的话,那只能把需要 system 执行的命令封装成服务远程调用,彻底隔离 php 环境
    artoostark
        12
    artoostark  
       2018-11-11 23:32:00 +08:00   ❤️ 1
    用 Docker 试试?
    KasuganoSoras
        13
    KasuganoSoras  
       2018-11-12 03:56:00 +08:00 via Android
    $cmd = "ls /data"; //命令
    if(preg_match("/^[A-Za-z0-9\-\_\.\/ ]+$/", $cmd)) {
    $exp = explode(' ', $cmd); //用空格分割命令
    if($exp[0] == 'ls' && $exp[1] == '/data' && count($exp) == 2) { //判断命令以及参数是否合法
    system($cmd); //执行
    }
    }

    这样相对安全一些吧,但是要想真正的安全,还是找其他方法替代或者封装比较好。
    mcfog
        14
    mcfog  
       2018-11-12 08:08:08 +08:00 via Android   ❤️ 1
    不不,为啥要基于对方可以任意执行脚本的前提下考虑?难道不应该先封堵任意执行脚本的漏洞么?

    就比如说你说的 cat passwd,何苦 system 呢直接 file_get_contents 不是一样的么
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3584 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 10:54 · PVG 18:54 · LAX 02:54 · JFK 05:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.