1.使用eval获取用户输入的内容

通常来讲,当我们不知道用户会输入那种类型的时候会使用eval()来对输入的数据进行一个类型识别、自动转换【我之前都是这么干的】

例如:

varDemo = eval(input('请输入数据:'))
# 进行一些操作

如果当用户输入的是int或者str、float等数据,会自动将输入的数据转为对应的数据【当然输入字符串是不行的,因为input获取的就是字符串,当你使用eval获取的是字符串类型的时候就有问题了,可以看下面的解释(更好的做法是使用 input() 函数直接获取用户输入)】

Python-使用eval的一些知识点-安全问题_数据

Python-使用eval的一些知识点-安全问题_字符串_02

使用 eval 函数来解析用户输入的代码存在安全风险,因为它会执行输入的任何Python代码。


2.eval函数的基本知识

eval 函数在 Python 中用于计算传入的字符串表达式的值

这意味着它可以执行任何有效的 Python 表达式,包括但不限于数学运算、变量赋值、函数调用等

正因为如此,如果使用 eval 来处理不信任的输入,就可能引发安全问题。

eval 函数用于计算字符串中的有效 Python 表达式,并返回表达式的值。如果字符串不是一个有效的 Python 表达式,eval 将抛出异常。【这里对标上面的字符串问题】


3.eval的相关使用例子和其潜在风险

以下是几个相关的例子,讲解 eval 的使用及其潜在风险:

1.简单的数学运算

user_input = "2 + 3 * 4"
result = eval(user_input)  # 结果为 14

Python-使用eval的一些知识点-安全问题_数据_03

2.变量赋值

user_input = "x = 10"
eval(user_input)
print(x)  # 输出 10,表明变量 x 已经在当前命名空间中创建并赋值

Python-使用eval的一些知识点-安全问题_字符串_04

Python-使用eval的一些知识点-安全问题_数据_05

Python-使用eval的一些知识点-安全问题_Python_06

user_input = "x = 10"
exec(user_input)  # 使用 exec() 来执行字符串中的代码
print(x)  # 这将输出 10,因为 x 现在是在当前命名空间中定义的1

3.函数调用

user_input = "print('Hello, World!')"
eval(user_input)  # 将打印 "Hello, World!"

Python-使用eval的一些知识点-安全问题_Python_07

4.访问系统环境变量

user_input = "import os; os.system('dir')"  # Windows系统下
eval(user_input)  # 执行 dir 命令,列出当前目录的文件

上面这段代码有个问题,就是直接导入os模块的话报错,说语法错误。

eval() 并不适用于执行多条语句或者包含导入(import)语句的代码。如果你尝试使用 eval() 来执行像 import os; os.system('dir') 这样的代码,它将无法正常工作,因为它期望的是单个表达式。

如果当你的代码文件刚好需要导入os模块,那么就悲催了...

import os
user_input = "os.system('dir')"  # Windows系统下
eval(user_input)  # 执行 dir 命令,列出当前目录的文件

Python-使用eval的一些知识点-安全问题_Python_08

5.修改全局变量

global_var = 0
user_input = "global_var = 100"
eval(user_input)  # 将 global_var 修改为 100
print(global_var)  # 输出 100


6.执行系统命令(非常危险):

user_input = "import os; os.system('rm -rf /')"
eval(user_input)  # 这将尝试删除 Unix 系统上的所有文件


7.访问和修改对象属性

class MyClass:
    def __init__(self):
        self.value = 1
my_object = MyClass()
user_input = "my_object.value = 5"
eval(user_input)  # 将 my_object.value 修改为 5
print(my_object.value)  # 输出 5


8.执行复杂的操作

user_input = "(lambda x, y: x + y)(10, 20)"
result = eval(user_input)  # 结果为 30


在上述的8个示例中,如果 user_input (即用户输入的数据内容)来自不可信的源,比如网络输入或用户控制的文件,那么使用 eval 将非常危险,因为它允许执行任意代码。这可能导致恶意用户利用代码写入eyi代码来破坏系统、窃取数据或执行其他恶意操作

因此,除非绝对必要,并且你可以完全信任输入的来源,否则不建议使用 eval。在大多数情况下,更安全的替代方法是使用 ast.literal_eval(只评估Python字面量表达式),或者更好的做法是使用适当的错误处理来解析和验证用户输入(也就是try...except...)。


扩展

报错语法:

SyntaxError: invalid syntax语法错误:无效语法