前言

本文对Python引入的一种格式化字符串的新型语法的安全漏洞进行了深入的分析,并提供了相应的安全解决方案。

当我们对不可信的用户输入使用str.format的时候,将会带来安全隐患——对于这个问题,其实我早就知道了,但是直到今天我才真正意识到它的严重性。因为攻击者可以利用它来绕过Jinja2沙盒,这会造成严重的信息泄露问题。同时,我在本文最后部分为str.format提供了一个新的安全版本。

需要提醒的是,这是一个相当严重的安全隐患,这里之所以撰文介绍,是因为大多数人很可能不知道它是多么容易被利用。

核心问题

从Python 2.6开始,Python受.NET启发而引入了一种格式化字符串的新型语法。当然,除了Python之外,Rust及其他一些编程语言也支持这种语法。借助于.format()方法,该语法可以应用到字节和unicode字符串(在Python 3中,只能用于unicode字符串)上面,此外,它还能映射为更加具有可定制性的string.Formatter API。

该语法的一个特点是,人们可以通过它确定出字符串格式的位置和关键字参数,并且随时可以显式对数据项重新排序。此外,它甚至可以访问对象的属性和数据项——这是导致这里的安全问题的根本原因。

总的来说,人们可以利用它来进行以下事情:

  1. >>> 'class of {0} is {0.__class__}'.format(42)
  2. "class of 42 is <class 'int'>"

实质上,任何能够控制格式字符串的人都有可能访问对象的各种内部属性。

问题出在哪里?

第一个问题是,如何控制格式字符串。可以从下列地方下手:

1.字符串文件中不可信的翻译器。我们很可能通过它们得手,因为许多被翻译成多种语言的应用程序都会用到这种新式Python字符串格式化方法,但是并非所有人都会对输入的所有字符串进行全面的审查。

2.用户暴露的配置。 由于一些系统用户可以对某些行为进行配置,而这些配置有可能以格式字符串的形式被暴露出来。需要特别提示的是,我就见过某些用户可以通过Web应用程序来配置通知邮件、日志消息格式或其他基本模板。

危险等级

如果只是向该格式字符串传递C解释器对象的话,倒是不会有太大的危险,因为这样的话,你最多会暴露一些整数类之类的东西。

然而,一旦Python对象被传递给这种格式字符串的话,那就麻烦了。这是因为,能够从Python函数暴露的东西的数量是相当惊人的。 下面是假想的Web应用程序的情形,这种情况下能够泄露密钥:

  1. CONFIG = {
  2. 'SECRET_KEY': 'super secret key'
  3. }
  4. class Event(object):
  5. def __init__(self, id, level, message):
  6. self.id = id
  7. self.level = level
  8. self.message = message
  9. def format_event(format_string, event):
  10. return format_string.format(eventevent=event)

如果用户可以在这里注入format_string,那么他们就能发现下面这样的秘密字符串:

  1. {event.__init__.__globals__[CONFIG][SECRET_KEY]}

将格式化作沙箱化处理

那么,如果需要让其他人提供格式化字符串,那该怎么办呢? 其实,可以利用某些未公开的内部机制来改变字符串格式化行为。

  1. from string import Formatter
  2. from collections import Mapping
  3. class MagicFormatMapping(Mapping):
  4. """This class implements a dummy wrapper to fix a bug in the Python
  5. standard library for string formatting.
  6. See http://bugs.python.org/issue13598 for information about why
  7. this is necessary.
  8. """
  9. def __init__(self, args, kwargs):
  10. self._args = args
  11. self._kwargs = kwargs
  12. self._last_index = 0
  13. def __getitem__(self, key):
  14. if key == '':
  15. idx = self._last_index
  16. self._last_index += 1
  17. try:
  18. return self._args[idx]
  19. except LookupError:
  20. pass
  21. key = str(idx)
  22. return self._kwargs[key]
  23. def __iter__(self):
  24. return iter(self._kwargs)
  25. def __len__(self):
  26. return len(self._kwargs)
  27. # This is a necessary API but it's undocumented and moved around
  28. # between Python releases
  29. try:
  30. from _string import formatter_field_name_split
  31. except ImportError:
  32. formatter_field_name_split = lambda \
  33. x: x._formatter_field_name_split()
  34. class SafeFormatter(Formatter):
  35. def get_field(self, field_name, args, kwargs):
  36. first, rest = formatter_field_name_split(field_name)
  37. obj = self.get_value(first, args, kwargs)
  38. for is_attr, i in rest:
  39. if is_attr:
  40. obj = safe_getattr(obj, i)
  41. else:
  42. objobj = obj[i]
  43. return obj, first
  44. def safe_getattr(obj, attr):
  45. # Expand the logic here.  For instance on 2.x you will also need
  46. # to disallow func_globals, on 3.x you will also need to hide
  47. # things like cr_frame and others.  So ideally have a list of
  48. # objects that are entirely unsafe to access.
  49. if attr[:1] == '_':
  50. raise AttributeError(attr)
  51. return getattr(obj, attr)
  52. def safe_format(_string, *args, **kwargs):
  53. formatter = SafeFormatter()
  54. kwargs = MagicFormatMapping(args, kwargs)
  55. return formatter.vformat(_string, args, kwargs)

现在,我们就可以使用safe_format方法来替代str.format了:

  1. >>> '{0.__class__}'.format(42)
  2. "<type 'int'>"
  3. >>> safe_format('{0.__class__}', 42)
  4. Traceback (most recent call last):
  5. File "<stdin>", line 1, in <module>
  6. AttributeError: __class__

小结

在本文中,我们对Python引入的一种格式化字符串的新型语法的安全漏洞进行了深入的分析,并提供了相应的安全解决方案,希望对读者能够有所帮助。

作者:shan66

来源:51CTO

Python新型字符串格式漏洞分析相关推荐

  1. python格式化字符串漏洞_Python新型字符串格式漏洞分析及解决方案

    最近一个python字符串格式化的漏洞引起了我的注意,今天就来说一下Python引入的一种格式化字符串的新型语法的安全漏洞进行了深入的分析,并提供了相应的安全解决方案. 当我们对不可信的用户输入使用s ...

  2. python 下字符串格式时间比较

    python 下有多个有关时间的模块,分别是time.datetime.calendar,今天重点讨论下time写法. 其中time模块,主要有以下方法: ltime=time.time() 获取当前 ...

  3. python 打开dat格式_p4vasp分析态密度输出pdos数据后用Python分列

    注:本文来源于"晚亭听铃"发表在CSDN网站上的原创博文,点击阅读原文关注他!在分析态密度(DOS)时,常常用p4vasp这个软件来读取vasprun.xml,进而获得需要的各元素 ...

  4. python打印字符串格式_Python字符串三种格式化输出

    字符串格式化输出是python非常重要的基础语法,今天就把三种格式化输出做一个简单的总结,希望对大家有帮助. 格式化输出:内容按照一定格式要求进行输出. 1.使用占位符%输出 python2.6版本之 ...

  5. python字符宽度_使用vars或\uyu dict的Python固定宽度字符串格式__

    我正在做一个Python项目,我希望使用一些快捷方式来帮助格式化字符串中的类数据.更具体地说,我希望能够使用类似于'{a}{b}{c}'.format(**vars(self), [strlen, s ...

  6. php字符串转换表达式,php处理字符串格式的计算表达式

    有时候我们对每一种产品都有一个提成公式,而这个计算提成的公式是以字符串格式存在表中的 当我们用这个计算公式时,他并不像我们写的:$a=2+3*5;这样简单的能计算出结果,而它是个字符串 所以,我们就必 ...

  7. fastjson转换时有大括号或者冒号或者有中括号_[Python Basic] 字符串处理以及类型转换 1...

    String Manipulation & Typecasting (1) 1. 文本复制以及连接 1.1 Multiply sign 使用 multiply sigh/乘号* 来复制文本片段 ...

  8. Python格式化字符串字面值 | 被官方文档称之为『漂亮』的输出格式

    Python格式化字符串字面值 | 被官方文档称之为『漂亮』的输出格式 本文参考输入输出 - Python 3.7.10 文档.首先声明咱的实验环境. ❯ python --version Pytho ...

  9. python pickle反序列化漏洞_Numpy反序列化命令执行漏洞分析(CVE-2019-6446) –vr_system...

    1. 介绍 NumPy 是 Python 机器学习库中之一,主要对于多为数组执行计算.NumPy提供大量的函数和操作,能够帮助 程序员 便利进行数值计算.在NumPy 1.16.0版本之前存在反序列化 ...

最新文章

  1. 共识机制:区块链技术的根基
  2. RH442-10 内存回收之二
  3. 《让系统发生重大宕机事故的15个方法》
  4. 经常使用的时间同步server地址
  5. WebBrowser介绍——Javascript与C++互操作
  6. Django配置开发环境和生产环境以及配置Jinja2模板引擎
  7. 二叉树最大宽度与leetcode662的二叉树最大宽度
  8. PHFRefreshControl
  9. vue v-for 不能自能渲染问题
  10. 信用卡到底逾期多少天才会上征信系统?
  11. Shell编程:awk使用总结
  12. synchronized锁机制 之 代码块锁
  13. Pass4side EMC E20-817认证考试题库
  14. 数学建模的论文格式以及visio画图
  15. 如何通过Homography矩阵制作虚拟图像
  16. 大龄程序员的8种出路
  17. Quartz是什么?
  18. 西瓜错时上市销售,提高经济效益的背后是技术支持!
  19. Python处理2个表格。从源表格中筛选符合条件的数据,写入到dst表格中
  20. 华为p40 pro鸿蒙系统体验,华为P40Pro升级鸿蒙系统体验_华为P40Pro升级鸿蒙系统感受...

热门文章

  1. 在WebAPI中自动创建Controller
  2. Python天气预报数据获取脚本
  3. Unity3D教程:自定义mesh做指向信息面板效果
  4. Springboot08-项目单元测试(接口测试)
  5. 云南“爆款”景区相继停业整顿 旅游大省为环保让路
  6. 【Machine learning】余弦相似度
  7. JavaScript学习笔记(八)--- 函数表达式
  8. MLS 移动最小二乘
  9. 这段时间Dot Text 老出错,实在没办法解决了,特来求助。[InvalidOperationException: 内部连接致命错误。]...
  10. tradingview Vue