langflow: AI产品AST代码解析执行产生的RCE
字数 1184 2025-08-29 22:41:38
Langflow AI产品AST代码解析执行RCE漏洞分析
漏洞概述
Langflow是一款AI产品,在其AST(抽象语法树)代码解析执行过程中存在远程代码执行(RCE)漏洞。该漏洞源于对decorator(装饰器)和参数注入的不当处理,使得攻击者能够通过精心构造的输入执行任意代码。
漏洞背景
AST解析执行的风险
AST(Abstract Syntax Tree)是源代码抽象语法结构的树状表示。当AI产品需要对代码进行分析、转换或执行时,通常会先将代码解析为AST,然后对AST进行操作。
问题出现在:
- Langflow在处理用户提供的代码时,未充分验证和清理AST节点
- 允许执行动态生成的AST结构
- 对装饰器和参数注入缺乏安全限制
装饰器的安全隐患
装饰器是Python中一种强大的语法特性,可以修改函数或类的行为。然而,不当的装饰器使用可能导致:
@eval('__import__("os").system("rm -rf /")')
def malicious_function():
pass
漏洞分析
漏洞产生点
-
AST解析阶段:
- 未对用户输入的代码进行充分过滤
- 允许执行包含危险节点的AST(如
eval、exec、__import__等)
-
装饰器处理:
- 装饰器参数未经验证直接执行
- 装饰器本身可以包含动态代码
-
参数注入:
- 通过参数传递恶意构造的字符串
- 这些字符串最终被解析为可执行代码
攻击向量
-
直接代码注入:
# 通过装饰器注入 @malicious_decorator(param='; import os; os.system("calc")') def target_function(): pass -
AST节点注入:
# 构造恶意AST节点 import ast malicious_node = ast.Call( func=ast.Name(id='eval', ctx=ast.Load()), args=[ast.Str(s='__import__("os").system("whoami")')], keywords=[] ) -
动态导入利用:
# 通过__import__动态加载危险模块 @dynamic_import(module='os', function='system', args=['rm -rf /']) def dummy(): pass
漏洞利用
基本利用步骤
- 识别Langflow中接受代码或AST输入的接口
- 构造包含恶意装饰器或参数的代码片段
- 通过API或UI提交恶意输入
- 触发AST解析和执行流程
高级利用技术
-
AST节点替换:
- 修改现有AST中的无害节点为恶意节点
- 利用AST的
NodeTransformer类进行自动化替换
-
装饰器链攻击:
@decorator1 @eval('__import__("subprocess").getoutput("id")') @decorator2 def victim_function(): pass -
元类滥用:
class MaliciousMeta(type): def __new__(cls, name, bases, namespace): import os os.system('malicious_command') return super().__new__(cls, name, bases, namespace) class VictimClass(metaclass=MaliciousMeta): pass
防御措施
代码层面防护
-
AST节点过滤:
SAFE_NODES = {ast.Expr, ast.Assign, ast.Name, ...} def validate_ast(node): if type(node) not in SAFE_NODES: raise SecurityError(f"Unsafe node type: {type(node)}") for field, child in ast.iter_fields(node): validate_ast(child) -
装饰器限制:
- 禁用动态装饰器
- 只允许预定义的安全装饰器
-
沙箱执行:
from RestrictedPython import compile_restricted try: bytecode = compile_restricted(source, '<inline>', 'exec') except SyntaxError as e: raise SecurityError(f"Unsafe syntax: {e}")
架构层面防护
-
最小权限原则:
- 使用低权限用户执行AI代码
- 限制文件系统、网络访问
-
输入验证:
- 白名单验证所有输入参数
- 禁止特殊字符和关键字
-
审计日志:
- 记录所有代码执行请求
- 监控异常执行模式
CodeQL检测规则
基本检测思路
- 识别AST解析执行点
- 查找未经验证的用户输入流向这些执行点
- 检测危险AST节点和装饰器使用
示例规则
import python
from DataFlow::PathGraph Node, DataFlow::PathNode source, DataFlow::PathNode sink
where
// 定义危险接收器 - AST执行点
exists(DataFlow::CallNode call |
call.getTarget().hasName(["eval", "exec", "ast.literal_eval"]) and
sink.asExpr() = call.getAnArgument()
) or
exists(DataFlow::CallNode call |
call.getTarget().hasQualifiedName("ast", "parse") and
sink.asExpr() = call.getAnArgument()
)
and
// 定义用户可控的源
source.asParameter() = any(UserControlledInput input).getParameter()
and
// 数据流路径
DataFlow::localPath(source, sink)
select sink, "Potential RCE via AST parsing from user input"
总结
Langflow的RCE漏洞揭示了AI产品在处理代码解析和执行时的常见安全隐患。通过深入理解AST操作、装饰器机制和参数注入,安全研究人员可以更好地识别和防御此类漏洞。开发者应当:
- 严格验证所有用户提供的代码和参数
- 限制AST解析和执行的权限
- 实施沙箱环境执行不可信代码
- 使用静态分析工具(如CodeQL)进行自动化检测
对于安全团队,建议将此类漏洞模式纳入AI产品的安全测试用例库,并在SDL流程中加入专门的AST解析安全检查点。