基于默认配置的 Dify 沙箱 RCE 利用链分析与加固探讨
本文记录了针对开源 LLM 应用平台 Dify 沙箱模块的一次安全测试过程。在研究其网络架构与源码时,发现由于默认配置中存在硬编码的通信凭证,在特定部署条件下(如端口暴露于公网),可能存在未经授权执行 2026-11-11 18:2:6 Author: xz.aliyun.com(查看原文) 阅读量:0 收藏

本文记录了针对开源 LLM 应用平台 Dify 沙箱模块的一次安全测试过程。在研究其网络架构与源码时,发现由于默认配置中存在硬编码的通信凭证,在特定部署条件下(如端口暴露于公网),可能存在未经授权执行代码的风险。

文章详细复现了从鉴权绕过到获取底层系统信息的完整链路。针对此问题,官方团队基于开发者体验(DX)的考量,认为该设计属于预设功能并无缺陷。本文不针对此定性做过多主观评价,仅从客观的技术视角还原漏洞细节,并从企业自托管运维的视角,给出了一套切实可行的纵深防御建议,以供安全同仁交流探讨。

摘要

dify该服务中存在硬编码的默认 API 密钥( ) dify-sandbox。能够访问 Dify 内部网络的攻击者可以middleware.Auth()通过X-Api-Key: dify请求头绕过该密钥,从而执行任意 Python 代码。本报告详细描述了完整的攻击链,从代码来源到实际验证,包括深度防御边界映射和业务级拒绝服务风险评估。

1. 问题起源:硬编码配置与路由分析

(对应附件: 2_Docker_Key_Config.png)

在 Dify 官方代码的 中,沙箱服务配置了 。这意味着只要运维人员未显式配置强密码,沙箱将默认回退使用 作为出厂密钥。docker/docker-compose.ymlAPI_KEY: ${CODE_EXECUTION_API_KEY:-dify}dify

(对应附件: 3_Router_Auth.png)

沙箱的入口路由定义在 中,将所有 路径挂载了 鉴权中间件。但攻击者只需携带 ,即可瞬间突破 的防御,直接进入内部处理流程。dify-sandbox/internal/controller/router.go/v1/sandbox/middleware.Auth()X-Api-Key: dify401

2. 攻击链:从解析到任意代码执行

(对应附件: 4_Run_Controller.png)

在 Go 语言控制层 的 中,HTTP 请求体里的 字段被 强制接收,并通过 原封不动传递给底层,无任何过滤或消毒。internal/controller/run.goRunSandboxControllerCodebinding:"required"service.RunPython3Code

(对应附件: 5_Prescript_Exec.png)

代码最终落入沙箱核心的 Python 执行器 中。该脚本通过文件描述符(管道)读取载荷,并在最后一行执行了极其危险的底层代码:。攻击者的任意 Python 载荷在此处被底层加载并触发。internal/core/runner/python/prescript.pyexec(compile(code, "<fds>", "exec"))

3. 实弹验证:从 RCE 到底层 C 库穿透

(对应附件: 6_RCE_Verified.png)

成功绕过鉴权后,发起 ,沙箱成功回显自定义字符串,证明已完全获得任意 Python 代码执行权。print("RCE_VERIFIED_BY_HHC")

(对应附件: 7_Exec_File_Path.png)

通过 变形成功获取沙箱内部临时文件的绝对路径,证明执行环境可控。exec

(对应附件: 8_Ctypes_Module_Found.png, 9_Sys_Modules_Full.png, 10_Builtins_List.png)

通过 Python 自省机制,成功探测到沙箱底层不仅加载了 模块,还保留了 , , 等核心内置函数。这为突破 Python 层防御提供了致命情报。ctypesevalexecopen

(对应附件: 11_Base64_Hidden_Backdoor.png)

攻击者使用 动态混淆载荷,沙箱完美解码并回显中文标记 。这证明攻击者完全可以通过动态编码绕过日志的静态流量审计,实现无文件持久化攻击。exec(base64.b64decode(...))"我是你的后门"

(对应附件: 12_Ctypes_Timestamp.png, 13_Ctypes_PID.png, 14_Sys_Executable_Path.png)

借助 调用底层 C 语言库 ,攻击者成功穿透 Python 层封锁,直接触碰到了 Linux 容器底层:ctypeslibc

  • 成功获取宿主机底层系统时间戳:。1786588842

  • 成功获取沙箱容器内的真实进程 PID:。51883

  • 成功获取沙箱内部 Python 二进制绝对路径:。
    这是本报告最具核心价值的底层指纹情报,证明了沙箱对攻击者来说已完全透明。/opt/python/bin/python3

(对应附件: 15_Path_Exist_Check.png)

通过纯 Python 验证文件是否存在(返回 ),侧面印证了代码执行逻辑的绝对通畅。False

4. 资源耗尽推演与业务级 DoS 风险

(对应附件: 16_Resource_Exhaustion_Test.png)

攻击者成功向沙箱发送大规模纯 Python 计算载荷(如列表推导式 ),沙箱返回 。尽管底层的 及时限制了单核 CPU 的占用,但这证明了攻击者完全可以在实战中通过多线程并发发送大量此类载荷,引发沙箱处理 AI 业务请求的严重延迟,直接威胁 Dify 核心业务的可用性。[i**2 for i in range(10**6)]successcgroup

5. 防御边界深度测绘

在 RCE 与底层情报获取成功后,本报告还记录了通过发送各类特定的恶意载荷进行的防御边界推演:

  • 文件系统封锁验证: 尝试读取 和 ,被精准拦截返回 。/proc/self/status/proc/self/cgroupoperation not permitted

  • 内网横向移动验证: 尝试从沙箱内部通过 探测 Dify 主 API 容器,连接被底层 规则拦截。requests.get("http://dify-api-1:5001/health")seccomp

  • DNS 外带验证: 尝试通过 发送 DNS 请求,同样被彻底封死。
    这些失败的测试精确绘制出了沙箱的 与 防御极限。socket.gethostbyname_exseccompcgroup

6. 危害评估与修复建议

尽管沙箱避免了攻击者逃逸到宿主机,但这绝不能掩盖漏洞在微服务架构下的致命性:

  1. 内网零信任防线彻底崩塌: 一把 的出厂钥匙,让所有内网隔离防御形同虚设。任何触达内网的攻击者都能瞬间获得一个完整的沙箱控制权。dify

  2. 核心底层情报严重泄露: 容器底层真实 、绝对路径及 C 库时间戳的获取,为攻击者提供了精确定位宿主机 Linux 内核版本的瞄准镜,为后续组合攻击提供了精确的情报支撑。PID

  3. 修复建议: 强烈建议官方移除 中 的默认回退配置,并强制要求用户在 中显式配置高强度随机字符串作为 。docker-compose.yml:-dify.envCODE_EXECUTION_API_KEY



7.得到的相关回复

8.给Dify使用者的建议

1.立即修改默认秘钥(底线防御)

切勿直接使用官方默认的docker-compose.yml上生产环境。

修改.env文件中的CODE_EXECUTION_API_KEY,使用 openssl rand -base -32 生成高强度随机字符串替换Dify。

2.坚决实施网络隔离(核心防线)

禁止将Sandbox端口(默认8194)和API端口(默认5001)直接暴露在公网

必须使用Nginx等反向代理,仅对外暴露Web访问所需的80/443端口。Sandbox应仅在内部Docker网络或内网通信。

3.收紧沙箱权限限制(防横向移动)

在.env中确保配置SANDBOX_ENABLE_NETWORK=false,防止攻击者利用沙箱发起内网探测(SSRF)或DNS数据外带。

严禁以 --privileged 特权模式运行容器,务必使用非root用户运行,防止底层容器被直接突破。

4.建立异常监控与拦截

在网关或WAF层增加规则,拦截包含exec、__subclasses__、base64.b64decode等危险特征的恶意请求。

监控Sandbox容器的CPU与内存使用率,防止被恶意利用执行死循环代码导致算力耗尽(DOS)。


文章来源: https://xz.aliyun.com/news/93260
如有侵权请联系:admin#unsafe.sh