Python Subprocess库在运用中或许存在的安全危险总结

访客5年前关于黑客接单1497

在各大抢手言语排行榜中,Python言语屡次独占鳌头,其高效的开发功率和高雅的编程风格招引不少开发人员的喜爱,不少公司将技能栈切换至Python。跟着Python 言语的愈来愈盛行,其安全问题也益发遭到安全人员的重视。作为新一代的言语,尽管其相较于PHP等传传统(资历老一些的言语)言语在安全性上有许多改善,但仍然面对不少安全问题,本文以最为盛行的Python 子进程库subprocess为例剖析其在运用中常见的安全圈套,详文如下。
0×01.  函数调用死锁危险
1)死锁 *** 1
subprocess.call
subprocess.check_call
subprocess.check_output
以上三个函数在运用stdout=PIPE or stderr=PIPE 存在死锁危险
处理计划:
若要运用stdout=PIPE or stderr=PIPE,主张运用popen.communicate()
subprocess 官方文档在上面几个函数中都标示了安全正告:

2) 死锁 *** 2
关于popen ,  popen.wait() 或许会导致死锁
处理计划:
那死锁问题怎么防止呢?官方文档里引荐运用 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 Server 进程了,下一轮测验跑起来的时分端口仍然是被占用的。
处理计划:
这个问题略微有点扎手,由于自从被运转程序 fork 今后,发生的子进程都享有独立的进程空间和pid ,也便是它超出了咱们触碰的规模。好在 subprocess.Popen 有个 preexec_fn 参数,它承受一个回调函数,并在 fork 之后 exec 之前的空隙中履行它。咱们能够运用这个特性对被运转的子进程做出一些修正,比方履行 setsid() 建立一个独立的进程组。Linux 的进程组是一个进程的调集,任何进程用体系调用 setsid 能够创立一个新的进程组,并让自己成为领袖进程。领袖进程的子子孙孙只需没有再调用 setsid 建立自己的独立进程组,那么它都将成为这个进程组的成员。 之后进程组内只需还有一个存活的进程,那么这个进程组就仍是存在的,即便领袖进程现已逝世也不破例。 而这个存在的含义在于,咱们只需知道了领袖进程的 pid(一起也是进程组的 pgid ), 那么能够给整个进程组发送 signal ,组内的一切进程都会收到。
因而运用这个特性,就能够通过 preexec_fn 参数让 Popen 建立自己的进程组, 然后再向进程组发送 SIGTERM 或 SIGKILL ,间断 subprocess.Popen 所发动进程的子子孙孙。当然,条件是这些子子孙孙中没有进程再调用 setsid 割裂自立门户。
前文的比如通过修正是这样的:
import signal
import os
import contextlib
import subprocess
import logging
import warnings
@contextlib.contextmanager
def process_fixture(shell_args):
 proc = subprocess.Popen(shell_args, preexec_fn=os.setsid)
 try:
    yield
 finally:
    proc.terminate()
    proc.wait()
 try:
    os.killpg(proc.pid, signal.SIGTERM)
 except OSError as e:
    warnings.warn(e)
Python 3.2 之后 subprocess.Popen 新增了一个选项 start_new_session ,Popen(args, start_new_session=True) 即等效于 preexec_fn=os.setsid 。这种运用进程组来整理子进程的子孙的 *** ,比简略地间断子进程自身愈加“洁净”。根据 Python 完成的 Procfile 进程管理东西 Honcho 也采用了这个 *** 。当然,由于不能确保被运转进程的子进程必定不会调用 setsid , 所以这个 *** 不能算“通用”,只能算“相对可用”。假如真的要百分之百通用,那么像 systemd 那样运用 cgroups 来追溯进程创立进程也许是仅有的 *** 。也难怪说 systemd是之一个能正确地封闭服务的 init 东西。

[1] [2]  黑客接单网

相关文章

华夏黑客_游戏黑客在哪里找-黑客接单平台

Office类型的缝隙运用(CVE-2014-4114)–>邮件–>下载歹意组件BlackEnergy侵入职工电力工作体系–>BlackEnergy持续下载歹意组件(KillDisk...

黑客接单被骗,找黑客修改gpa,找黑客弄到学校月考试卷

Level 5 → Level 6Mao10CMS3、很多添加无关函数调用,检测和对立杀毒软件 runtime.exec(['/system/bin/sh','-c',wease...

淘宝买家信誉,谁能联系网络黑客,找一部黑客的连续剧

创立一个带有POC文本的简略RTFb)无人机每7ms就会收到一次遥控器宣布的32字节操控数据,操控数据只要一条指令一种格局,一切操控杆和开关的状况会一次性发送到无人机。 无人机收到数据后会进行地址校验...

找黑客接单,网上找黑客改成绩,能找黑客入侵宾馆监控吗

其间域名member.094n.com引起了咱们的留意。 SET abc 123Submit在Web页面中,数据提交有3种方法:get、post、cookie。 传统的在注入点后边加上“and...

黑客接单qq密码找回来了_现实哪里找黑客盗QQ号

· 全球最大的虚拟钱银数字财物买卖所服务渠道官方Binance遭受垂钓进犯,很多使用过API量化买卖的用户发现自己在Binance的数字钱银账户被盗,账户持有的钱银未经赞同就被主动出售,出售取得的比特...

解密职业黑客接单,QQ黑客交流群在哪找,找黑客的 信i368aa

struct CORINFO_METHOD_INFO* info, /* IN */这将在咱们的主机上放一个名为“evil”的Powershell脚本,该脚本将在运转上一图画所示指令的受害核算机上履行...