Python新型字符串格式漏洞分析
前言
本文对Python引入的一种格式化字符串的新型语法的安全漏洞进行了深入的分析,并提供了相应的安全解决方案。
当我们对不可信的用户输入使用str.format的时候,将会带来安全隐患——对于这个问题,其实我早就知道了,但是直到今天我才真正意识到它的严重性。因为攻击者可以利用它来绕过Jinja2沙盒,这会造成严重的信息泄露问题。同时,我在本文最后部分为str.format提供了一个新的安全版本。
需要提醒的是,这是一个相当严重的安全隐患,这里之所以撰文介绍,是因为大多数人很可能不知道它是多么容易被利用。
核心问题
从Python 2.6开始,Python受.NET启发而引入了一种格式化字符串的新型语法。当然,除了Python之外,Rust及其他一些编程语言也支持这种语法。借助于.format()方法,该语法可以应用到字节和unicode字符串(在Python 3中,只能用于unicode字符串)上面,此外,它还能映射为更加具有可定制性的string.Formatter API。
该语法的一个特点是,人们可以通过它确定出字符串格式的位置和关键字参数,并且随时可以显式对数据项重新排序。此外,它甚至可以访问对象的属性和数据项——这是导致这里的安全问题的根本原因。
总的来说,人们可以利用它来进行以下事情:
- >>> 'class of {0} is {0.__class__}'.format(42)
- "class of 42 is <class 'int'>"
实质上,任何能够控制格式字符串的人都有可能访问对象的各种内部属性。
问题出在哪里?
第一个问题是,如何控制格式字符串。可以从下列地方下手:
1.字符串文件中不可信的翻译器。我们很可能通过它们得手,因为许多被翻译成多种语言的应用程序都会用到这种新式Python字符串格式化方法,但是并非所有人都会对输入的所有字符串进行全面的审查。
2.用户暴露的配置。 由于一些系统用户可以对某些行为进行配置,而这些配置有可能以格式字符串的形式被暴露出来。需要特别提示的是,我就见过某些用户可以通过Web应用程序来配置通知邮件、日志消息格式或其他基本模板。
危险等级
如果只是向该格式字符串传递C解释器对象的话,倒是不会有太大的危险,因为这样的话,你最多会暴露一些整数类之类的东西。
然而,一旦Python对象被传递给这种格式字符串的话,那就麻烦了。这是因为,能够从Python函数暴露的东西的数量是相当惊人的。 下面是假想的Web应用程序的情形,这种情况下能够泄露密钥:
- CONFIG = {
- 'SECRET_KEY': 'super secret key'
- }
- class Event(object):
- def __init__(self, id, level, message):
- self.id = id
- self.level = level
- self.message = message
- def format_event(format_string, event):
- return format_string.format(eventevent=event)
如果用户可以在这里注入format_string,那么他们就能发现下面这样的秘密字符串:
- {event.__init__.__globals__[CONFIG][SECRET_KEY]}
将格式化作沙箱化处理
那么,如果需要让其他人提供格式化字符串,那该怎么办呢? 其实,可以利用某些未公开的内部机制来改变字符串格式化行为。
- from string import Formatter
- from collections import Mapping
- class MagicFormatMapping(Mapping):
- """This class implements a dummy wrapper to fix a bug in the Python
- standard library for string formatting.
- See http://bugs.python.org/issue13598 for information about why
- this is necessary.
- """
- def __init__(self, args, kwargs):
- self._args = args
- self._kwargs = kwargs
- self._last_index = 0
- def __getitem__(self, key):
- if key == '':
- idx = self._last_index
- self._last_index += 1
- try:
- return self._args[idx]
- except LookupError:
- pass
- key = str(idx)
- return self._kwargs[key]
- def __iter__(self):
- return iter(self._kwargs)
- def __len__(self):
- return len(self._kwargs)
- # This is a necessary API but it's undocumented and moved around
- # between Python releases
- try:
- from _string import formatter_field_name_split
- except ImportError:
- formatter_field_name_split = lambda \
- x: x._formatter_field_name_split()
- class SafeFormatter(Formatter):
- def get_field(self, field_name, args, kwargs):
- first, rest = formatter_field_name_split(field_name)
- obj = self.get_value(first, args, kwargs)
- for is_attr, i in rest:
- if is_attr:
- obj = safe_getattr(obj, i)
- else:
- objobj = obj[i]
- return obj, first
- def safe_getattr(obj, attr):
- # Expand the logic here. For instance on 2.x you will also need
- # to disallow func_globals, on 3.x you will also need to hide
- # things like cr_frame and others. So ideally have a list of
- # objects that are entirely unsafe to access.
- if attr[:1] == '_':
- raise AttributeError(attr)
- return getattr(obj, attr)
- def safe_format(_string, *args, **kwargs):
- formatter = SafeFormatter()
- kwargs = MagicFormatMapping(args, kwargs)
- return formatter.vformat(_string, args, kwargs)
现在,我们就可以使用safe_format方法来替代str.format了:
- >>> '{0.__class__}'.format(42)
- "<type 'int'>"
- >>> safe_format('{0.__class__}', 42)
- Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- AttributeError: __class__
小结
在本文中,我们对Python引入的一种格式化字符串的新型语法的安全漏洞进行了深入的分析,并提供了相应的安全解决方案,希望对读者能够有所帮助。
作者:shan66
来源:51CTO
Python新型字符串格式漏洞分析相关推荐
- python格式化字符串漏洞_Python新型字符串格式漏洞分析及解决方案
最近一个python字符串格式化的漏洞引起了我的注意,今天就来说一下Python引入的一种格式化字符串的新型语法的安全漏洞进行了深入的分析,并提供了相应的安全解决方案. 当我们对不可信的用户输入使用s ...
- python 下字符串格式时间比较
python 下有多个有关时间的模块,分别是time.datetime.calendar,今天重点讨论下time写法. 其中time模块,主要有以下方法: ltime=time.time() 获取当前 ...
- python 打开dat格式_p4vasp分析态密度输出pdos数据后用Python分列
注:本文来源于"晚亭听铃"发表在CSDN网站上的原创博文,点击阅读原文关注他!在分析态密度(DOS)时,常常用p4vasp这个软件来读取vasprun.xml,进而获得需要的各元素 ...
- python打印字符串格式_Python字符串三种格式化输出
字符串格式化输出是python非常重要的基础语法,今天就把三种格式化输出做一个简单的总结,希望对大家有帮助. 格式化输出:内容按照一定格式要求进行输出. 1.使用占位符%输出 python2.6版本之 ...
- python字符宽度_使用vars或\uyu dict的Python固定宽度字符串格式__
我正在做一个Python项目,我希望使用一些快捷方式来帮助格式化字符串中的类数据.更具体地说,我希望能够使用类似于'{a}{b}{c}'.format(**vars(self), [strlen, s ...
- php字符串转换表达式,php处理字符串格式的计算表达式
有时候我们对每一种产品都有一个提成公式,而这个计算提成的公式是以字符串格式存在表中的 当我们用这个计算公式时,他并不像我们写的:$a=2+3*5;这样简单的能计算出结果,而它是个字符串 所以,我们就必 ...
- fastjson转换时有大括号或者冒号或者有中括号_[Python Basic] 字符串处理以及类型转换 1...
String Manipulation & Typecasting (1) 1. 文本复制以及连接 1.1 Multiply sign 使用 multiply sigh/乘号* 来复制文本片段 ...
- Python格式化字符串字面值 | 被官方文档称之为『漂亮』的输出格式
Python格式化字符串字面值 | 被官方文档称之为『漂亮』的输出格式 本文参考输入输出 - Python 3.7.10 文档.首先声明咱的实验环境. ❯ python --version Pytho ...
- python pickle反序列化漏洞_Numpy反序列化命令执行漏洞分析(CVE-2019-6446) –vr_system...
1. 介绍 NumPy 是 Python 机器学习库中之一,主要对于多为数组执行计算.NumPy提供大量的函数和操作,能够帮助 程序员 便利进行数值计算.在NumPy 1.16.0版本之前存在反序列化 ...
最新文章
- 共识机制:区块链技术的根基
- RH442-10 内存回收之二
- 《让系统发生重大宕机事故的15个方法》
- 经常使用的时间同步server地址
- WebBrowser介绍——Javascript与C++互操作
- Django配置开发环境和生产环境以及配置Jinja2模板引擎
- 二叉树最大宽度与leetcode662的二叉树最大宽度
- PHFRefreshControl
- vue v-for 不能自能渲染问题
- 信用卡到底逾期多少天才会上征信系统?
- Shell编程:awk使用总结
- synchronized锁机制 之 代码块锁
- Pass4side EMC E20-817认证考试题库
- 数学建模的论文格式以及visio画图
- 如何通过Homography矩阵制作虚拟图像
- 大龄程序员的8种出路
- Quartz是什么?
- 西瓜错时上市销售,提高经济效益的背后是技术支持!
- Python处理2个表格。从源表格中筛选符合条件的数据,写入到dst表格中
- 华为p40 pro鸿蒙系统体验,华为P40Pro升级鸿蒙系统体验_华为P40Pro升级鸿蒙系统感受...
热门文章
- 在WebAPI中自动创建Controller
- Python天气预报数据获取脚本
- Unity3D教程:自定义mesh做指向信息面板效果
- Springboot08-项目单元测试(接口测试)
- 云南“爆款”景区相继停业整顿 旅游大省为环保让路
- 【Machine learning】余弦相似度
- JavaScript学习笔记(八)--- 函数表达式
- MLS 移动最小二乘
- 这段时间Dot Text 老出错,实在没办法解决了,特来求助。[InvalidOperationException: 内部连接致命错误。]...
- tradingview Vue