Python Subprocess库在使用中可能存在的安全风险总结_python subprocess漏洞如何避免

处理方案:

那死锁问题如何避免呢?官方文档里推荐使用 Popen.communicate()。这个方法会把输出放在内存,而不是管道里,所以这时候上限就和内存大小有关了,一般不会有问题。而且如果要获得程序返回值,可以在调用 Popen.communicate() 之后取 Popen.returncode 的值。

3)死锁形式3

call、check_call、popen、check_output 这四个函数,参数shell=True,命令参数不能为list,若为list则引发死锁

处理方案:

参数shell=True时,命令参数为字符串形式

0×02. 关闭subprocess.Popen 子进程时存在子进程关闭失败而成为僵尸进程的风险

Python 标准库 subprocess.Popen 是 shellout 一个外部进程的首选,它在 Linux/Unix 平台下的实现方式是 fork 产生子进程然后 exec 载入外部可执行程序。

于是问题就来了,如果我们需要一个类似“夹具”的子进程(比如运行 Web 集成测试的时候跑起来的那个被测试 Server), 那么就需要在退出上下文的时候清理现场,也就是结束被跑起来的子进程。

最简单粗暴的做法可以是这样:

 @contextlib.contextmanager
def process_fixture(shell_args):
 proc = subprocess.Popen(shell_args)
 try:
    yield
 finally:
    # 无论是否发生异常,现场都是需要清理的
     proc.terminate()
     proc.wait()
     
if __name__ == '__main__':
    with process_fixture(['python', 'SimpleHTTPServer', '8080']) as proc:
    print('pid %d' % proc.pid)
    print(urllib.urlopen('http://localhost:8080').read())

那个 proc.wait() 是不可以偷懒省掉的,否则如果子进程被中止了而父进程继续运行, 子进程就会一直占用 pid 而成为僵尸,直到父进程也中止了才被托孤给 init 清理掉。

这个简单粗暴版对简单的情况可能有效,但是被运行的程序可能没那么听话。被运行程序可能会再fork 一些子进程来工作,自己则只当监工 —— 这是不少 Web Server 的做法。 对这种被运行程序如果简单地 terminate ,也即对其 pid 发 SIGTERM , 那就相当于谋杀了监工进程,真正的工作进程也就因此被托孤给 init ,变成畸形的守护进程…… 嗯没错,这就是我一开始遇到的问题,CI Server上明明已经中止了 Web S

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值