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

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

在各大抢手言语排行榜中,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]  黑客接单网

相关文章

网上有黑客接单吗,黄岩黑客网吧联系方式,找黑客帮忙设置几个电话拦截多少钱

Rot13 decode:union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,* from adminBu...

微信好友定位_黑客用imei找手机-北京在哪找黑客

更多详细信息:D盾拦掉了一句话对传入的动态脚本的履行,但是咱们能够以奇葩的姿态来绕过 Netcraft.com Information gathered"歹意软件一般会被注入在core_conf...

百度竞价歹意点击实战心得

 这将是一篇很有含义的文章,能够让你对百度凤巢体系有更深一步知道。 仔细看下去,收成必将不少。 百度推广凤巢体系同一ip屡次点击会算为一次费用吗? 百度推广同行歹意点击体系会过滤掉吗? 咱们将从以下几...

网络安全小组组长,网络刷单被骗怎么找黑客,网赌账户冻结找黑客能出款吗

-b按指定的巨细单位切割字典文件成若干个指定的巨细的字典,防止一个字典文件过大,如:MITM,全称为Man In The Middle,即中间人。 地址解析协议是建立在网络中各个主机相互信赖的基础上的...

mac右键怎么按_怎样在找黑客盗号-找黑客加徽信i368aa

「mac右键怎么按_怎样在找黑客盗号-找黑客加徽信i368aa」然后拿了一些信息,比方数据库暗码:Referrer : http://50.116.13.242/index.php“麦芽地”传达源虽告...

从客户端中检测到有潜在风险的Request.Form值的处理方法

 一些用户在运用ASP.NET作为网站开发言语时,会呈现这样一个问题。用户提交表单宣布内容时,页面提示:应用程序中的服务器过错,从客户端(某某代码)中检测到有潜在风险的Request.Form值。 原...