iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >使用 exec 函数时需要注意的一些安
  • 531
分享到

使用 exec 函数时需要注意的一些安

要注意函数时需 2023-01-31 08:01:05 531人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

众所周知,在 python 中可以使用 exec 函数来执行包含 Python 源代码的字符串: >>> code = ''' ...: a = "hello" ...: print(a) ...: '

众所周知,在 python 中可以使用 exec 函数来执行包含 Python 源代码的字符串:

>>> code = '''
   ...: a = "hello"
   ...: print(a)
   ...: '''
>>> exec(code)
hello
>>> a
'hello'

exec 函数的这个功能很是强大,慎用。如果一定要用的话,那么就需要注意一下下面这些安全相关的问题。

全局变量和内置函数

exec 执行的代码中,默认可以访问执行 exec 时的局部变量和全局变量, 同样也会修改全局变量。如果 exec 执行的代码是根据用户提交的数据生产的话,这种默认行为就是一个安全隐患。

如何更改这种默认行为呢?可以通过执行 exec 函数的时候再传两个参数的方式来 修改这种行为(详见 之前 关于 exec 的文章):

>>> g = {}
>>> l = {'b': 'world'}
>>> exec('hello = "hello" + b', g, l)
>>> l
{'b': 'world', 'hello': 'helloworld'}
>>> g
{'__builtins__': {...}}
>>> hello
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
...
NameError: name 'hello' is not defined

如果要限制使用内置函数的话,可以在 globals 参数中定义一下 __builtins__ 这个 key:

>>> g = {}
>>> l = {}
>>> exec('a = int("1")', g, l)
>>> l
{'a': 1}

>>> g = {'__builtins__': {}}
>>> exec('a = int("1")', g, l)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'int' is not defined
>>>

现在我们限制了访问和修改全局变量以及使用内置函数,难道这样就万事大吉了吗? 然而并非如此,还是可以通过其他的方式来获取内置函数甚至 os.system 函数。

另辟蹊径获取内置函数和 os.system

通过函数对象:

>>> def a(): pass
...
>>> a.__globals__['__builtins__']

>>> a.__globals__['__builtins__'].open
<built-in function open>

通过内置类型对象:

>>> for cls in {}.__class__.__base__.__subclasses__():
...     if cls.__name__ == 'WarningMessage':
...         b = cls.__init__.__globals__['__builtins__']
...         b['open']
...
<built-in function open>
>>>

获取 os.system:

>>> cls = [x for x in [].__class__.__base__.__subclasses__() if x.__name__ == '_wrap_close'][0]
>>> cls.__init__.__globals__['path'].os
<module 'os' from '/usr/local/var/pyenv/versions/3.5.1/lib/python3.5/os.py'>
>>>

对于这两种办法又如何应对呢? 一种办法就是禁止访问以 _ 开头的属性:

  • 如果可以控制 code 的生成,那么就在生成 code 的时候判断

  • 如果不能的话,可以通过 dis 模块分析生成的 code (dist 无法分析嵌套函数的代码)

  • 使用 tokenize 模块:

    In [68]: from io import BytesIO
    In [69]: code = '''
       ....: a = 'b'
       ....: a.__str__
       ....: def b():
       ....:     b.__get__
       ....: '''
    In [70]: t = tokenize(BytesIO(code.encode()).readline)
    In [71]: for x in t:
       ....:     print(x)
       ....:
    TokenInfo(type=59 (ENcoding), string='utf-8', start=(0, 0), end=(0, 0), line='')
    TokenInfo(type=58 (NL), string='\n', start=(1, 0), end=(1, 1), line='\n')
    TokenInfo(type=1 (NAME), string='a', start=(2, 0), end=(2, 1), line="a = 'b'\n")
    TokenInfo(type=53 (OP), string='=', start=(2, 2), end=(2, 3), line="a = 'b'\n")
    TokenInfo(type=3 (STRING), string="'b'", start=(2, 4), end=(2, 7), line="a = 'b'\n")
    TokenInfo(type=4 (NEWLINE), string='\n', start=(2, 7), end=(2, 8), line="a = 'b'\n")
    TokenInfo(type=1 (NAME), string='a', start=(3, 0), end=(3, 1), line='a.__str__\n')
    TokenInfo(type=53 (OP), string='.', start=(3, 1), end=(3, 2), line='a.__str__\n')
    TokenInfo(type=1 (NAME), string='__str__', start=(3, 2), end=(3, 9), line='a.__str__\n')
    TokenInfo(type=4 (NEWLINE), string='\n', start=(3, 9), end=(3, 10), line='a.__str__\n')
    TokenInfo(type=1 (NAME), string='def', start=(4, 0), end=(4, 3), line='def b():\n')
    TokenInfo(type=1 (NAME), string='b', start=(4, 4), end=(4, 5), line='def b():\n')
    TokenInfo(type=53 (OP), string='(', start=(4, 5), end=(4, 6), line='def b():\n')
    TokenInfo(type=53 (OP), string=')', start=(4, 6), end=(4, 7), line='def b():\n')
    TokenInfo(type=53 (OP), string=':', start=(4, 7), end=(4, 8), line='def b():\n')
    TokenInfo(type=4 (NEWLINE), string='\n', start=(4, 8), end=(4, 9), line='def b():\n')
    TokenInfo(type=5 (INDENT), string='    ', start=(5, 0), end=(5, 4), line='    b.__get__\n')
    TokenInfo(type=1 (NAME), string='b', start=(5, 4), end=(5, 5), line='    b.__get__\n')
    TokenInfo(type=53 (OP), string='.', start=(5, 5), end=(5, 6), line='    b.__get__\n')
    TokenInfo(type=1 (NAME), string='__get__', start=(5, 6), end=(5, 13), line='    b.__get__\n')
    TokenInfo(type=4 (NEWLINE), string='\n', start=(5, 13), end=(5, 14), line='    b.__get__\n')
    TokenInfo(type=6 (DEDENT), string='', start=(6, 0), end=(6, 0), line='')
    TokenInfo(type=0 (ENDMARKER), string='', start=(6, 0), end=(6, 0), line='')

从上面的输出我们可以知道当 type 是 OP 并且 string 等于 '.' 时,下一条记录就是
点之后的属性名称。所以我们的检查代码可以这样写:


    import io
    import tokenize


    def check_unsafe_attributes(string):
        g = tokenize.tokenize(io.BytesIO(string.encode('utf-8')).readline)
        pre_op = ''
        for toktype, tokval, _, _, _ in g:
            if toktype == tokenize.NAME and pre_op == '.' and tokval.startswith('_'):
                attr = tokval
                msg = "access to attribute '{0}' is unsafe.".fORMat(attr)
                raise AttributeError(msg)
            elif toktype == tokenize.OP:
                pre_op = tokval

我所知道的使用 exec 函数时需要注意的安全问题就是这些了。 如果你还知道其他需要注意的安全问题的话,欢迎留言告知。

--结束END--

本文标题: 使用 exec 函数时需要注意的一些安

本文链接: https://www.lsjlt.com/news/192510.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 使用 exec 函数时需要注意的一些安
    众所周知,在 python 中可以使用 exec 函数来执行包含 python 源代码的字符串: >>> code = ''' ...: a = "hello" ...: print(a) ...: '...
    99+
    2023-01-31
    要注意 函数 时需
  • 在MySQL中使用sleep函数时需要注意哪些事项
    在MySQL中使用sleep函数时需要注意哪些事项?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。前言MySQL中的系统函数sl...
    99+
    2024-04-02
  • 在python中使用zip函数时需要注意的事项
    在python中使用zip函数时需要注意的事项?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。python可以做什么Python是一种编程语言,内置了许多有效的工...
    99+
    2023-06-14
  • 在python中使用匿名函数时需要注意哪些问题
    在python中使用匿名函数时需要注意哪些问题?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。python可以做什么Python是一种编程语言,内置了许多有效的工...
    99+
    2023-06-14
  • 使用云存储数据时需要注意哪些安全事项
    使用云存储数据时需要注意的安全事项:1、需要做好数据分类,根据数据重要性进行划分;2、需要做好内容保护措施,防止黑客轻易入侵窃取数据;3、需要做好权限管理措施,限制不同用户的数据访问权限,减少人为操作错误的影响;4、需要利用平台工具监控记录...
    99+
    2024-04-02
  • 使用 C++ 内联函数需要注意哪些事项?
    c++++内联函数在编译时直接展开,避免函数调用开销。事项包括:1. 函数体小(建议10行以内);2. 避免循环和递归;3. 注意内联展开仅在同文件范围内。实战案例中,计算三角形面积的内...
    99+
    2024-04-16
    编程 c++内联函数 c++
  • 使用 STL 函数对象需要注意哪些陷阱?
    stl函数对象使用陷阱:不可修改函数对象的状态,否则可能导致后果或崩溃。函数对象应作为右值使用,左值使用会导致未定义行为。捕获局部变量时应确保捕获所有引用的变量,否则可能导致崩溃。 使...
    99+
    2024-04-25
    stl 陷阱
  • Centos7安装时需要注意哪些问题
    这篇文章主要介绍“Centos7安装时需要注意哪些问题”,在日常操作中,相信很多人在Centos7安装时需要注意哪些问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Centos7安装时需要注意哪些问题”的疑...
    99+
    2023-06-10
  • 使用ADO.NET时需要注意什么
    小编给大家分享一下使用ADO.NET时需要注意什么,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!使用ADO.NET时,出现了一个严重的问题,ADO.NET统一了数...
    99+
    2023-06-17
  • 安装rac时需要注意的问题有哪些
    这篇文章将为大家详细讲解有关安装rac时需要注意的问题有哪些,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。安装rac时需要注意的问题1.虚拟机添加共享磁盘,1)创建磁盘在...
    99+
    2024-04-02
  • C++指针作为函数的参数进行传递时需要注意的一些问题
    只有在被调函数中,对指针进行引用操作,才可以达到不需要返回值,就对指针指向的变量做出相应的变化。 下面分析这样两个例子; 要求:定义并初始化两个字符串变量,并执行输出操作;然后调用函...
    99+
    2022-11-15
    指针 函数参数
  • PHP 函数处理数据时,需要注意哪些常见错误?
    处理 php 数据时,常见错误包括:使用 unset() 而不是 empty() 和 isset();混淆 == 和 ===;忘记过滤用户输入和转义输出;错误处理数组。避免这些错误可提升...
    99+
    2024-05-04
    php 数据处理错误 lsp
  • 使用Go需要注意哪些坑
    本篇内容介绍了“使用Go需要注意哪些坑”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Go 需要注意的坑需要注意的坑Go 的优势在于方便的协程...
    99+
    2023-06-22
  • C++ 函数返回指针时需要注意什么?
    在 c++++ 中,函数返回指针时,需要注意以下事项:指针必须指向有效对象,否则会导致未定义行为。函数返回指针后,不要修改指针指向的对象,否则其他代码会受影响。调用者负责管理内存,在不再...
    99+
    2024-04-20
    c++ 指针
  • 在python中使用yield时需要注意哪些事项
    在python中使用yield时需要注意哪些事项?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Python的优点有哪些1、简单易用,与C/C++、Java、C# 等传统语言相比...
    99+
    2023-06-14
  • 在python中使用os.remove()时需要注意哪些问题
    在python中使用os.remove()时需要注意哪些问题?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。python可以做什么Python是一种编程语言,内置...
    99+
    2023-06-14
  • 在java中使用final时需要注意哪些事项
    在java中使用final时需要注意哪些事项?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Java的特点有哪些Java的特点有哪些1.Java语言作为静态面向对象编程语言的代表...
    99+
    2023-06-14
  • 使用Java构造器时需要注意哪些事项
    今天就跟大家聊聊有关使用Java构造器时需要注意哪些事项,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Java构造器使用方法及注意事项超类的构造器在子类的构造器运行之前运行,也就是说...
    99+
    2023-05-31
    java ava
  • 在python中使用lxml时需要注意哪些事项
    这篇文章将为大家详细讲解有关在python中使用lxml时需要注意哪些事项,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。python主要应用领域有哪些1、云计算,典型应用OpenStack。...
    99+
    2023-06-14
  • 在java中使用subList时需要注意哪些问题
    在java中使用subList时需要注意哪些问题?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。1. 使用Arrays.asList的注意事项1.1 可能会踩的坑先来看下Ar...
    99+
    2023-06-06
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作