0

0

如何使用Python发现不安全的eval()使用?

蓮花仙者

蓮花仙者

发布时间:2025-07-24 09:27:02

|

792人浏览过

|

来源于php中文网

原创

python中的eval()被视为不安全函数的核心原因在于其能够执行任意代码,导致严重的安全风险,尤其当输入来源不可信时。①攻击者可构造恶意输入,执行如文件操作、数据泄露等危险行为;②即使尝试通过限制globals和locals参数构建“沙箱”,也难以真正安全;③推荐使用ast.literal_eval()、json.loads()等替代方案;④通过ast静态分析可有效识别eval()调用并评估其风险等级;⑤运行时应严格验证输入、限制权限并避免eval()的使用。

如何使用Python发现不安全的eval()使用?

在Python项目中识别并处理不安全的eval()使用,核心在于理解其带来的巨大安全风险,并结合静态代码分析与必要的运行时考量。最直接有效的方法是利用Python内置的ast模块进行抽象语法树分析,辅以代码审查和对替代方案的深入理解。

如何使用Python发现不安全的eval()使用?

解决方案

要发现不安全的eval()使用,我们可以编写一个脚本来遍历项目的Python文件,解析它们的抽象语法树(AST),并查找所有对eval函数的调用。一旦找到,就需要进一步分析eval的参数来源。如果参数来源于外部不可信输入(如用户提交的数据、网络请求内容、文件读取等),或者是一个动态构建的字符串,那么这几乎可以肯定是一个安全漏洞。

一个基本的AST扫描器可以这样构建:

立即学习Python免费学习笔记(深入)”;

如何使用Python发现不安全的eval()使用?
import ast
import os

class EvalFinder(ast.NodeVisitor):
    def __init__(self):
        self.eval_calls = []

    def visit_Call(self, node):
        # 检查是否是函数调用
        if isinstance(node.func, ast.Name) and node.func.id == 'eval':
            # 找到一个eval()调用
            # 进一步分析node.args[0]可以判断参数类型
            # 例如,如果是ast.Str,可能是字面量字符串
            # 如果是ast.Name,则参数是一个变量,需要进一步追踪其来源
            self.eval_calls.append({
                'line': node.lineno,
                'col': node.col_offset,
                'args': [ast.dump(arg) for arg in node.args] # 简单展示参数结构
            })
        self.generic_visit(node) # 继续遍历子节点

def find_eval_in_file(filepath):
    with open(filepath, 'r', encoding='utf-8') as f:
        content = f.read()
    try:
        tree = ast.parse(content, filename=filepath)
        finder = EvalFinder()
        finder.visit(tree)
        return finder.eval_calls
    except SyntaxError as e:
        print(f"Error parsing {filepath}: {e}")
        return []

def scan_project_for_eval(project_root):
    all_eval_uses = {}
    for root, _, files in os.walk(project_root):
        for file in files:
            if file.endswith('.py'):
                filepath = os.path.join(root, file)
                eval_uses = find_eval_in_file(filepath)
                if eval_uses:
                    all_eval_uses[filepath] = eval_uses
    return all_eval_uses

# 示例用法:
# project_path = './my_python_project'
# insecure_evals = scan_project_for_eval(project_path)
# for file, calls in insecure_evals.items():
#     print(f"File: {file}")
#     for call in calls:
#         print(f"  Line {call['line']}, Col {call['col']}: eval({call['args']})")

这个AST扫描器能定位到eval的调用点。更复杂的分析会涉及到数据流追踪,例如一个变量被eval调用,但这个变量的值是在程序运行过程中从用户输入、网络请求等外部来源获取的。这超出了纯粹静态分析的范畴,通常需要更专业的静态分析工具或人工代码审查。

Python中的eval()为何被视为不安全函数?

eval()函数在Python中被认为是极其危险的,其核心原因在于它能够执行任意的Python代码。当你把一个字符串传递给eval(),Python解释器会尝试将这个字符串当作一个完整的Python表达式来求值并执行。这意味着,如果攻击者能够控制传递给eval()的字符串内容,他们就可以在你的应用程序运行环境中执行任何他们想执行的代码。

如何使用Python发现不安全的eval()使用?

这听起来可能有点抽象,但想象一下:一个Web应用接收用户提交的查询字符串,然后直接用eval()来处理。如果用户输入的是__import__('os').system('rm -rf /'),那么你的服务器文件系统可能就遭殃了。这可不是开玩笑,而是实实在在的威胁。它不仅仅限于文件操作,还可以是数据泄露(比如读取环境变量、数据库凭证)、权限提升、甚至是在你的服务器上安装恶意软件。

很多人会误以为eval()提供了一个“沙箱”环境,或者通过限制globalslocals参数就能安全使用。但实际情况是,构建一个真正安全的Python沙箱是极其困难的,几乎不可能完美。即使限制了内置函数和全局变量,攻击者也常常能找到绕过的方法,例如通过对象的属性、方法链等来访问受限资源。所以,默认的立场应该是:除非你对输入有绝对的控制且能确保其安全性,否则永远不要使用eval()

网奇IOS智能在线订单系统
网奇IOS智能在线订单系统

产品简介: 网奇IOS智能订单系统,是网奇公司研发的一款智能在线订单编辑以及管理系统。本系统适合使用在;在线报名、酒店预定、信息反馈、在线订单和在线投诉等等诸多应用上。本系统所有选项字段完全通过后台控制,在线报名系统可以变为在线预定系统,同时可以变为任何其它的系统,里面的栏目字段,可以任意添加、删除、 修改。本系统为网奇公司全国独家首创,顺应网络需求,安装十分便利,上传即可使用。产品特色:

下载

静态分析与AST:检测eval()的利器

静态分析,尤其基于抽象语法树(AST)的分析,是发现代码中潜在eval()滥用的最可靠方法之一。不像正则表达式,AST分析能够真正理解代码的结构和语义,避免误报和漏报。Python的ast模块正是为此而生。

当我们用ast.parse()将Python源代码转换为AST时,我们得到的是一个树形结构,每个节点代表了代码中的一个元素,比如一个函数调用、一个变量赋值、一个循环等等。对于eval()的检测,我们关注的是ast.Call节点,它表示一个函数调用。通过遍历这棵树,我们可以很容易地识别出所有名为eval的函数调用。

但仅仅找到eval还不够。一个字面量字符串,比如eval("1 + 1"),虽然使用了eval,但其风险是可控的,因为代码内容是固定的。真正危险的是当eval的参数是变量,或者是一个从外部输入动态构建的字符串时。虽然AST本身无法追踪变量在运行时的具体值,但它可以识别出参数的类型。如果eval的参数不是一个简单的字面量字符串(ast.Str),而是一个变量(ast.Name)、一个函数调用(ast.Call)、一个二进制操作(ast.BinOp)等,那么这就需要引起高度警惕了。

例如,在上面的EvalFinder中,我们捕获了eval的调用及其参数的AST表示。这提供了一个起点,让你能够手动审查这些调用,或者在此基础上构建更复杂的数据流分析,尝试追踪变量的来源。对于大型项目,这样的AST扫描器能快速提供一个“危险清单”,大大提高代码审计的效率。当然,它也有局限性,比如无法处理通过getattr__builtins__等方式动态构造的eval调用,以及无法在编译时确定变量的实际值。

运行时监控与防御策略:不仅仅是发现

发现代码中的eval()使用只是第一步,更重要的是如何处理它们,以及在无法避免时如何进行运行时防御。理想情况下,如果发现不安全的eval(),应该立即将其替换掉。

替换eval()的常见安全替代方案:

  • json.loads()yaml.safe_load() 如果你只是想解析JSON或YAML格式的数据,这些是安全且专用的方法。它们不会执行任意代码。
  • ast.literal_eval() 如果你需要安全地评估只包含Python字面量(字符串、数字、元组、列表、字典、布尔值和None)的表达式,ast.literal_eval()是完美的选择。它会拒绝任何非字面量的表达式,从而避免代码执行。
  • 模板引擎: 对于生成动态HTML或文本内容,使用Jinja2、Django Templates等成熟的模板引擎。它们通常有严格的安全控制,避免任意代码执行。
  • 自定义解析器: 如果数据格式非常特殊,可以编写一个专门的解析器,而不是依赖eval()。这虽然工作量大,但安全性最高。

如果eval()真的不可避免(极少数情况):

  • 严格限制globalslocals eval()函数接受globalslocals参数,可以用来限制可用的全局和局部命名空间。例如,eval(code_str, {"__builtins__": {}}, {})可以创建一个非常受限的环境。但请注意,这并非万无一失的沙箱,经验丰富的攻击者仍可能找到绕过方法。
  • 输入验证与净化: 这是最关键但也是最困难的一点。你必须对所有传递给eval()的输入进行极其严格的验证和净化,确保它只包含预期的数据或表达式,绝不包含任何可执行代码的片段。这通常意味着白名单验证,而不是黑名单(因为你永远无法穷尽所有恶意输入)。
  • 最小权限原则: 运行应用程序的账户应该拥有最小的权限,即使eval()被利用,也能将损害降到最低。

最终,最好的防御策略是避免使用eval()。在绝大多数情况下,都有更安全、更健壮的替代方案。代码审查和开发团队的安全意识培训也至关重要,它们能从源头上减少eval()这种高风险函数的引入。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Python Web 框架 Django 深度开发
Python Web 框架 Django 深度开发

本专题系统讲解 Python Django 框架的核心功能与进阶开发技巧,包括 Django 项目结构、数据库模型与迁移、视图与模板渲染、表单与认证管理、RESTful API 开发、Django 中间件与缓存优化、部署与性能调优。通过实战案例,帮助学习者掌握 使用 Django 快速构建功能全面的 Web 应用与全栈开发能力。

163

2026.02.04

json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

455

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

546

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

334

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

82

2025.09.10

js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

530

2023.06.20

正则表达式不包含
正则表达式不包含

正则表达式,又称规则表达式,,是一种文本模式,包括普通字符和特殊字符,是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式的文本。php中文网给大家带来了有关正则表达式的相关教程以及文章,希望对大家能有所帮助。

258

2023.07.05

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

766

2023.07.05

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

3

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.5万人学习

Django 教程
Django 教程

共28课时 | 4.9万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号