php-在python中使用subprocess.run()运行脚本,阻止所有文件读/写尝试

2021-01-08 21点热度 0人点赞 0条评论
我有一台Web服务器在Raspbian Stretch上运行Apache2。这将是一个编程竞赛网站,用户可以通过HTML表单发送代码,通过一个POST请求将源代码发送到PHP。然后运行php(使用执行()
)包含参数(如提交的代码路径)的python脚本。然后脚本执行代码(使用子进程.run()
)并将其与预期输出进行比较。所有这些都很好用。

但是,我想确保没有人会发送恶意代码来覆盖index.php等文件,或者读取预期的输出。我想知道是否有任何方法可以阻止 subprocess.run() 执行的申请阅读、创建和写入除 stdinstdoutstderr 以外的文件。

我尝试过使用Docker,但没有成功,因为当我使用PHP的exec()构建和运行Dockerfile时,它达到了第2/4步,然后就停止了。我的dockerfile应该将脚本、代码和预期的输出复制到一个映像、CD到新位置并执行代码,但这并不重要,因为我想避免docker,因为它不能正常工作。

我正在考虑使用Chrot监狱,但我仍然在寻找其他不那么复杂的方法。

这是我使用的PHP代码。它调用python 3代码验证器(变量从HTML表单和SQL查询中检索,这些变量不相关):

$cmd = "python3 verify.py $uploadedFile $questionID $uploadedFileExtension $questionTimeLimit 2>&1";

这是执行提交代码的python 3代码:

def runCmd(args, vStdin, timelimit = 10):
    p = subprocess.run(args, stdout = subprocess.PIPE, stderr = subprocess.PIPE, input = vStdin, encoding = 'utf-8', timeout=timelimit)
    vStdout = p.stdout
    vStderr = p.stderr
    if vStdout.endswith('\n'):
        vStdout = vStdout[:-1]
    if vStderr.endswith('\n'):
        vStderr = vStderr[:-1]
    return vStdout, vStderr

...

# Assuming it is a .py file
# Its path is given by PHP's exec.
runCmd(['python3', sys.argv[1], 'simulatedinput.in', int(sys.argv[4]))

两个程序的组合工作得很好。它使用模拟输入运行代码,将abraham与预期的输出进行比较,并将状态字符串返回给PHP代码。但是,如果发送的代码包含恶意代码,例如

open('/var/www/html/contest/index.php', 'w').write('oops!')

index.php文件将被覆盖。

我只需要一种执行用户发送的代码的方法,这种方法拒绝了它读或写文件的尝试( stdinstdoutstderr 除外)。

有什么想法吗?

查看隐藏内容需要支付:¥1
查看

未经允许不得转载!php-在python中使用subprocess.run()运行脚本,阻止所有文件读/写尝试

本文地址:https://ans.52learn.online/2133

ANS52LEARN

DO BEST