目录
核心问题
问题出在哪里?
危险等级
将格式化作沙箱化处理
总结:
首页 后端开发 Python教程 解析Python新型字符串格式漏洞及解决方案

解析Python新型字符串格式漏洞及解决方案

Aug 16, 2017 pm 01:47 PM
python 字符串 漏洞

最近一个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 "
登录后复制

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

问题出在哪里?

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

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(event=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()
{C} 
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:
                obj = 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)
""
>>> safe_format('{0.__class__}', 42)
Traceback (most recent call last):
  File "", line 1, in
AttributeError: __class__
登录后复制

总结:

程序开发中有这么一句话:任何时候不要相信用户的输入!现在看来这句话说得非常有道理。所以各位同学要谨记!

以上是解析Python新型字符串格式漏洞及解决方案的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它们
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

PHP和Python:代码示例和比较 PHP和Python:代码示例和比较 Apr 15, 2025 am 12:07 AM

PHP和Python各有优劣,选择取决于项目需求和个人偏好。1.PHP适合快速开发和维护大型Web应用。2.Python在数据科学和机器学习领域占据主导地位。

CentOS上如何进行PyTorch模型训练 CentOS上如何进行PyTorch模型训练 Apr 14, 2025 pm 03:03 PM

在CentOS系统上高效训练PyTorch模型,需要分步骤进行,本文将提供详细指南。一、环境准备:Python及依赖项安装:CentOS系统通常预装Python,但版本可能较旧。建议使用yum或dnf安装Python3并升级pip:sudoyumupdatepython3(或sudodnfupdatepython3),pip3install--upgradepip。CUDA与cuDNN(GPU加速):如果使用NVIDIAGPU,需安装CUDATool

CentOS上PyTorch的GPU支持情况如何 CentOS上PyTorch的GPU支持情况如何 Apr 14, 2025 pm 06:48 PM

在CentOS系统上启用PyTorchGPU加速,需要安装CUDA、cuDNN以及PyTorch的GPU版本。以下步骤将引导您完成这一过程:CUDA和cuDNN安装确定CUDA版本兼容性:使用nvidia-smi命令查看您的NVIDIA显卡支持的CUDA版本。例如,您的MX450显卡可能支持CUDA11.1或更高版本。下载并安装CUDAToolkit:访问NVIDIACUDAToolkit官网,根据您显卡支持的最高CUDA版本下载并安装相应的版本。安装cuDNN库:前

docker原理详解 docker原理详解 Apr 14, 2025 pm 11:57 PM

Docker利用Linux内核特性,提供高效、隔离的应用运行环境。其工作原理如下:1. 镜像作为只读模板,包含运行应用所需的一切;2. 联合文件系统(UnionFS)层叠多个文件系统,只存储差异部分,节省空间并加快速度;3. 守护进程管理镜像和容器,客户端用于交互;4. Namespaces和cgroups实现容器隔离和资源限制;5. 多种网络模式支持容器互联。理解这些核心概念,才能更好地利用Docker。

Python vs. JavaScript:社区,图书馆和资源 Python vs. JavaScript:社区,图书馆和资源 Apr 15, 2025 am 12:16 AM

Python和JavaScript在社区、库和资源方面的对比各有优劣。1)Python社区友好,适合初学者,但前端开发资源不如JavaScript丰富。2)Python在数据科学和机器学习库方面强大,JavaScript则在前端开发库和框架上更胜一筹。3)两者的学习资源都丰富,但Python适合从官方文档开始,JavaScript则以MDNWebDocs为佳。选择应基于项目需求和个人兴趣。

CentOS下PyTorch版本怎么选 CentOS下PyTorch版本怎么选 Apr 14, 2025 pm 02:51 PM

在CentOS下选择PyTorch版本时,需要考虑以下几个关键因素:1.CUDA版本兼容性GPU支持:如果你有NVIDIAGPU并且希望利用GPU加速,需要选择支持相应CUDA版本的PyTorch。可以通过运行nvidia-smi命令查看你的显卡支持的CUDA版本。CPU版本:如果没有GPU或不想使用GPU,可以选择CPU版本的PyTorch。2.Python版本PyTorch

centos如何安装nginx centos如何安装nginx Apr 14, 2025 pm 08:06 PM

CentOS 安装 Nginx 需要遵循以下步骤:安装依赖包,如开发工具、pcre-devel 和 openssl-devel。下载 Nginx 源码包,解压后编译安装,并指定安装路径为 /usr/local/nginx。创建 Nginx 用户和用户组,并设置权限。修改配置文件 nginx.conf,配置监听端口和域名/IP 地址。启动 Nginx 服务。需要注意常见的错误,如依赖问题、端口冲突和配置文件错误。性能优化需要根据具体情况调整,如开启缓存和调整 worker 进程数量。

CentOS上PyTorch的分布式训练如何操作 CentOS上PyTorch的分布式训练如何操作 Apr 14, 2025 pm 06:36 PM

在CentOS系统上进行PyTorch分布式训练,需要按照以下步骤操作:PyTorch安装:前提是CentOS系统已安装Python和pip。根据您的CUDA版本,从PyTorch官网获取合适的安装命令。对于仅需CPU的训练,可以使用以下命令:pipinstalltorchtorchvisiontorchaudio如需GPU支持,请确保已安装对应版本的CUDA和cuDNN,并使用相应的PyTorch版本进行安装。分布式环境配置:分布式训练通常需要多台机器或单机多GPU。所

See all articles