跳转至

灵字辈 MCP 集成审计报告 v0.16

审计日期: 2026-04-07 审计范围: 灵依 v0.16.0 + 灵克 v0.3.0 MCP Server 实现 审计类型: 安全审计 + 一致性审计 + 代码质量审查 审计者: 灵依 (LingYi)


📊 审计总览

维度 评分 说明
功能完整性 ⭐⭐⭐⭐⭐ (5/5) 灵依12工具 + 灵克15工具,全部注册可用
测试覆盖 ⭐⭐⭐⭐ (4/5) 灵克21测试全过,灵依252测试全过;缺少MCP stdio集成测试
安全性 ⭐⭐⭐ (3/5) ast_edit.py 路径穿越漏洞(HIGH);bash blocklist 绕过风险(HIGH)
一致性 ⭐⭐⭐⭐ (4/5) 版本号、入口点已同步;3份文档待更新
代码质量 ⭐⭐⭐⭐⭐ (5/5) FastMCP装饰器模式简洁、Result monad解包正确

🔴 安全审计(6项发现)

SEC-01: ast_edit.py 路径穿越漏洞 [HIGH]

位置: lingclaude/engine/ast_edit.py:replace_function_body()list_functions() 严重性: 🔴 HIGH 描述: replace_function_body()list_functions() 直接使用 Path(file_path) 读取文件,没有路径解析和边界检查。攻击者可通过 ../../etc/passwd 等路径读取或修改任意文件。

对比: file_read.pyfile_edit.py 均实现了 _resolve() 方法,使用 resolve() + relative_to() 防止路径穿越。

修复方案:

# 在 ast_edit.py 中添加路径解析,参考 file_read.py 的 _resolve() 模式
def _resolve_path(file_path: str, base_dir: str = ".") -> Result[Path]:
    p = Path(file_path)
    if p.is_absolute():
        resolved = p.resolve()
    else:
        resolved = (Path(base_dir).resolve() / p).resolve()
    try:
        resolved.relative_to(Path(base_dir).resolve())
    except ValueError:
        return Result.fail(f"路径越界: {file_path}")
    return Result.ok(resolved)

状态: 待修复


SEC-02: BashExecutor blocklist 绕过风险 [HIGH]

位置: lingclaude/engine/bash.py:BashExecutor.run() 严重性: 🔴 HIGH 描述: BashExecutor 使用 shell=True 执行命令,虽有命令黑名单(rm, sudo, wget 等),但可通过 shell 元字符绕过: - r''m -rf / (空字符串拼接) - /bin/rm -rf / (绝对路径) - \rm -rf / (转义字符)

影响: MCP 工具 run_bash 继承此风险。远程 MCP 调用者可能执行任意命令。

缓解因素: - BashExecutor 有 512MB 内存限制和 30s CPU 限制 - MCP 运行环境为可信内网 - 黑名单已覆盖常见危险命令

建议: 长期应改用 shell=False + subprocess.run(["bash", "-c", command]) 并加强参数校验。短期可增强黑名单(添加 /bin/, /usr/bin/ 前缀匹配)。

状态: 已知风险,引擎层面问题(非MCP层)


SEC-03: grep.py ReDoS 风险 [MEDIUM]

位置: lingclaude/engine/grep.py:GrepTool.search() 严重性: 🟡 MEDIUM 描述: GrepTool 接受用户提供的正则表达式,未对正则复杂度做限制。恶意正则如 (a+)+b 可导致灾难性回溯(ReDoS),使服务无响应。

缓解因素: - max_results=200 限制匹配数 - max_line_length=500 截断长行 - BashExecutor 的 30s 超时也限制了 grep 执行时间

建议: 添加正则复杂度校验或改用 ripgrep--regex-size-limit 参数。

状态: 已知风险,影响有限


SEC-04: 灵依 mcp_server.py 缺少工作目录隔离 [LOW]

位置: src/lingyi/mcp_server.py 严重性: 🟢 LOW 描述: 灵依的 MCP 工具直接调用 memo.add_memo() 等函数,这些函数内部使用全局 DB 路径。MCP 调用者无法指定工作目录或数据库路径,意味着所有 MCP 调用共享同一个 SQLite 数据库。

影响: 如果多个 MCP 客户端同时调用灵依工具,可能出现 SQLite 写入冲突。

缓解因素: SQLite WAL 模式已启用,支持并发读取。

状态: 可接受(单用户场景)


SEC-05: 灵克 MCP 工具默认工作目录 [LOW]

位置: lingclaude/mcp/server.py 各工具函数 严重性: 🟢 LOW 描述: read_file, write_file, edit_code, search_codeworking_dir 为空时默认 base_dir="."。如果 MCP Server 从非预期目录启动,可能导致文件操作作用到错误目录。

缓解因素: 已在测试中发现并修复(添加 working_dir 参数),实际使用时调用者应始终指定 working_dir

状态: 已通过测试验证


SEC-06: advisor.py save_report 路径保护不完整 [LOW]

位置: lingclaude/self_optimizer/advisor.py:OptimizationAdvisor.save_report() 严重性: 🟢 LOW 描述: save_report()output_path 做了基本的 resolve() 检查,但未限制写入到特定基础目录,理论上可写入任意位置。

缓解因素: MCP 工具 get_advice 不调用 save_report(),仅调用 generate_report() 返回字符串。

状态: 不影响 MCP 安全面


🔄 一致性审计(7项发现)

CON-01: 灵克版本号不一致 [FIXED]

位置: lingclaude/__init__.py 发现: __version__"0.2.0",但 pyproject.toml"0.3.0"修复: 已将 __version__ 更新为 "0.3.0"


CON-02: 灵依 pyproject.toml 版本号不一致 [FIXED]

位置: pyproject.toml 发现: version"0.15.0",但 __init__.py"0.16.0"修复: 已将 pyproject.toml 更新为 "0.16.0"


CON-03: 灵依 mcp_server.py 缺少 main() 入口 [FIXED]

位置: src/lingyi/mcp_server.py 发现: 文件没有 main() 函数和 __main__ 块,lingyi-mcp 入口点无法启动。 修复: 已添加 main()if __name__ == "__main__" 块。


CON-04: 灵克 mcp/init.py 为空 [FIXED]

位置: lingclaude/mcp/__init__.py 发现: 文件为空,未导出 mcpmain修复: 已添加 from .server import mcp, main__all__


CON-05: LING_FAMILY_MEMBERS.md 灵克版本过期 [PENDING]

位置: docs/LING_FAMILY_MEMBERS.md 发现: 灵克版本仍为 0.2.1,实际已升级到 0.3.0修复: 待更新。


CON-06: LING_FAMILY_MCP_ASSESSMENT.md 灵克工具名过期 [PENDING]

位置: docs/LING_FAMILY_MCP_ASSESSMENT.md 发现: 灵克 MCP 的 15 个工具中,有 6 个与实际实现不一致:

评估文档中的名称 实际实现名称 中文名变化
generate_code (灵衍) list_functions (灵析) 新增AST函数列举
refactor_code (灵构) replace_function (灵构) 改为AST级别函数替换
git_branch (灵支) git_status (灵态) 改为只读Git状态
git_commit (灵提) git_log (灵史) 改为只读提交历史
git_merge (灵合) git_diff (灵异) 改为只读差异对比
(无) index_project (灵索) 已实现,名称不变

设计决策: 选择只读 Git 工具(status/log/diff)而非写入工具(branch/commit/merge),因为 MCP 暴露写入操作风险更高。选择 AST 级别工具(list_functions/replace_function)映射到实际引擎 API。

修复: 待更新。


CON-07: LING_FAMILY_MCP_COORDINATION.md B1 任务清单过期 [PENDING]

位置: docs/LING_FAMILY_MCP_COORDINATION.md 发现: B1 灵克任务清单中的工具名与实际不符: - 灵衍 → 灵析(generate_code → list_functions) - 灵支/灵提/灵合 → 灵态/灵史/灵异(git写入 → git只读)

修复: 待更新。


🧪 测试审计

灵克 MCP Server 测试

文件: tests/test_mcp_server.py (183行, 21个测试) 结果: ✅ 21/21 通过

测试类 测试数 覆盖范围
TestMCPToolRegistration 5 15工具注册、分类、灵系命名
TestReadFile 2 正常读取、不存在文件
TestWriteFile 1 创建新文件
TestEditCode 1 替换文本
TestSearchCode 2 正则搜索、字面搜索
TestRunBash 2 简单命令、危险命令拦截
TestGitTools 3 status/log/diff
TestIndexProject 1 项目索引
TestListFunctions 1 函数列举
TestEvaluateCode 1 代码评估
TestCheckTriggers 1 触发条件检查
TestGetAdvice 1 优化建议

缺失测试: replace_function、run_optimization(run_optimization 因依赖 optuna 可选包,跳过合理)

灵依测试

文件: tests/test_basic.py (252个测试) 结果: ✅ 252/252 通过

版本断言已从 0.15.0 更新为 0.16.0(lines 784, 793)。


📐 代码质量审查

架构模式

两个 MCP Server 均采用 FastMCP 装饰器模式

@mcp.tool(name="tool_name", description="描述(灵X)")
def tool_xxx(params...) -> ReturnType:
    from .module import func
    result = func(params)
    return _unwrap(result)

优点: - 每个工具 ~5-10 行,极简 - 懒加载导入(from ..engine.xxx import Yyy),避免循环依赖 - Result monad 解包统一(_unwrap() helper) - dataclass 自动转 dict(_to_dict() helper)

_unwrap() 实现

灵克版本比灵依更复杂,因需要处理 Result[T] monad:

def _unwrap(result: Any) -> Any:
    if hasattr(result, "is_ok") and not result.is_ok:
        return {"error": str(result.error), "ok": False}
    if hasattr(result, "data"):
        val = result.data  # 注意:是 .data 不是 .value
        return _to_dict(val) if dataclasses.is_dataclass(val) else val
    ...

关键: 灵克 Result monad 用 .data.value,已在初始测试中确认。

依赖管理

项目 MCP依赖 入口点 Build配置
灵依 mcp>=1.0 lingyi-mcp = "lingyi.mcp_server:main" packages.find.where = ["src"]
灵克 mcp>=1.0 lingclaude-mcp = "lingclaude.mcp.server:main" packages.find.include = ["lingclaude*"]

灵克 Build 修复: 灵克曾因 flat-layout 导致 "Multiple top-level packages discovered" 错误,通过添加 [tool.setuptools.packages.find] with include = ["lingclaude*"] 修复。


📋 审计结论

已完成

  • ✅ 灵依 v0.16.0 pyproject.toml 版本同步
  • ✅ 灵克 v0.3.0 版本号全面同步(__init__.py + pyproject.toml
  • ✅ 灵依 mcp_server.py main() 入口添加
  • ✅ 灵克 mcp/init.py 模块导出
  • ✅ 灵克 pyproject.toml build 配置修复
  • ✅ 灵克 21 个 MCP 测试全部通过
  • ✅ 灵依 252 个测试全部通过
  • ✅ 安全审计完成(6项发现)
  • ✅ 一致性审计完成(7项发现)

待完成

  • 🔴 SEC-01: ast_edit.py 路径穿越修复(HIGH)
  • 🟡 CON-05: LING_FAMILY_MEMBERS.md 灵克版本更新
  • 🟡 CON-06: LING_FAMILY_MCP_ASSESSMENT.md 工具名更新
  • 🟡 CON-07: LING_FAMILY_MCP_COORDINATION.md 任务清单更新
  • 🟡 重新安装灵依/灵克验证入口点

风险接受

以下风险在当前可接受范围内: - SEC-02 (bash blocklist 绕过) — 引擎层面问题,MCP层无法修复 - SEC-03 (grep ReDoS) — 有超时和结果数限制 - SEC-04 (灵依 DB 隔离) — 单用户场景


灵依审计,众智混元