elaz48/langdoctor

GitHub: elaz48/langdoctor

一款专为 LangGraph/LangChain 项目设计的离线安全与生产就绪扫描器,用于在发布前发现已知 CVE 及框架特有的安全隐患。

Stars: 0 | Forks: 0

# langdoctor 🩺 [![PyPI](https://img.shields.io/pypi/v/langdoctor.svg)](https://pypi.org/project/langdoctor/) [![Python](https://img.shields.io/pypi/pyversions/langdoctor.svg)](https://pypi.org/project/langdoctor/) [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/elaz48/langdoctor/actions/workflows/ci.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) ![langdoctor 扫描存在漏洞的项目](https://static.pigsec.cn/wp-content/uploads/repos/cas/43/43617a931925e459145ffe54ffd17c1473cbfb62b9f5b527305a0cc8f87912f4.gif) ## 快速开始 ``` pipx run langdoctor # or: uvx langdoctor ``` ``` langdoctor # scan the current directory langdoctor path/to/project # scan a specific directory langdoctor list-checks # every check, with IDs and severities langdoctor --version # tool version + advisory DB date ``` ## 为什么需要它 2026 年对 agent 技术栈来说是艰难的一年: - **Langflow 正遭受主动攻击。** `CVE-2025-3248`(未授权 RCE)已被 加入 [CISA KEV 目录](https://www.cisa.gov/known-exploited-vulnerabilities-catalog) 并[被用于部署 Flodrix 僵尸网络](https://www.trendmicro.com/en_us/research/25/f/langflow-vulnerability-flodric-botnet.html); `CVE-2026-5027`(路径遍历 → RCE)[正在约 7,000 个暴露的实例中被利用](https://www.bleepingcomputer.com/news/security/path-traversal-flaw-in-ai-dev-platform-langflow-exploited-in-attacks/)。 - **LangGraph checkpointer CVE** — SQLite/base checkpointer 中的 SQL 注入和不安全的反序列化可通过伪造的 checkpoint 链式触发 RCE。 - **供应链攻击** — 针对该生态系统依赖的 CI action 和包(tj-actions 和 LiteLLM 事件)意味着固定到 tag 的 action 或未锁版本的依赖项是一个真实的风险面。 这些正是框架专用的 linter 能在你发布前捕获的问题。langdoctor 随包携带 CVE 数据并完全离线运行。 ## 检查内容 | ID | 类别 | 严重程度 | 捕获内容 | | --- | --- | --- | --- | | `LD101` | 已知 CVE | 高 | SQLite checkpointer 中通过 metadata 过滤键进行的 SQL 注入 | | `LD102` | 已知 CVE | 中 | 加载 checkpoint 时不安全的 msgpack 反序列化 | | `LD103` | 已知 CVE | 中 | 加载 checkpoint 时不安全的 JSON 反序列化 | | `LD104` | 已知 CVE | 高 | 旧版 load_prompt 函数中的路径遍历 | | `LD105` | 已知 CVE | 严重 | dumps/loads 中利用序列化注入提取密钥 | | `LD106` | 已知 CVE | 严重 🔴KEV | /api/v1/validate/code 中的未授权 RCE (Langflow) | | `LD107` | 已知 CVE | 中 | BaseCache 对不可信数据的反序列化可能导致 RCE | | `LD108` | 已知 CVE | 高 | JsonPlusSerializer 的 "json" 模式中的 RCE | | `LD109` | 已知 CVE | 高 | SQLite store 实现中的 SQL 注入 | | `LD110` | 已知 CVE | 高 | SqliteStore 中通过过滤键进行的 SQL 注入 | | `LD111` | 已知 CVE | 高 🔴KEV | 通过 /api/v2/files 上传的路径遍历 → RCE (Langflow) | | `LD150` | 已知 CVE | 高 | 低于当前安全基线 (1.10.1) 的 Langflow | | `LD201` | Checkpointer 与状态 | 高 | 面向生产环境的项目中使用了 MemorySaver | | `LD202` | Checkpointer 与状态 | 中 | SqliteSaver 可能在写入并发下崩溃 | | `LD203` | Checkpointer 与状态 | 高 (启发式) | Checkpoint 历史记录受用户控制输入过滤 | | `LD204` | Checkpointer 与状态 | 中 | 带有 interrupts 的已编译图没有 checkpointer | | `LD301` | 图与运行时配置 | 中 | LangGraph 运行未配置 recursion_limit | | `LD302` | 图与运行时配置 | 低 (启发式) | 创建 LLM 客户端时未设置 timeout | | `LD303` | 图与运行时配置 | 信息 | 已废弃的 1.0 之前的 LangChain 导入 | | `LD304` | 图与运行时配置 | 高 | 旧版 load_prompt() 的使用 | | `LD401` | 密钥与暴露 | 严重 | 源代码中硬编码的 API key | | `LD402` | 密钥与暴露 | 高 | 存在 .env 文件但未添加至 gitignore | | `LD403` | 密钥与暴露 | 严重 | 未显式禁用 Langflow 自动登录 | | `LD501` | 规范 | 中 | 依赖项未锁定版本 | | `LD502` | 规范 | 中 | GitHub Actions 使用了未锁定版本的第三方 action | CVE 检查的严重程度源自 CVSS 评分;`🔴KEV` 标记 [已知被利用](https://www.cisa.gov/known-exploited-vulnerabilities-catalog) 的漏洞,这些漏洞始终会优先展示。 ## CI 集成 ### GitHub Action ``` # .github/workflows/langdoctor.yml name: langdoctor on: [push, pull_request] permissions: contents: read security-events: write # to upload SARIF jobs: scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: elaz48/langdoctor@v1 with: fail-on: high - uses: github/codeql-action/upload-sarif@v3 if: always() with: sarif_file: langdoctor.sarif ``` 检测结果将显示在代码库的 **Security → Code scanning** 标签页中。 ### pre-commit ``` # .pre-commit-config.yaml repos: - repo: https://github.com/elaz48/langdoctor rev: v0.1.0 hooks: - id: langdoctor ``` ### GitLab CI ``` langdoctor: image: python:3.12-slim script: - pip install langdoctor - langdoctor --format sarif > gl-langdoctor.sarif artifacts: reports: sast: gl-langdoctor.sarif ``` ## 配置 在 `pyproject.toml` 中配置默认值;命令行参数具有更高优先级。 ``` [tool.langdoctor] fail-on = "high" # critical | high | medium | low | never ignore = ["LD203", "LD302"] exclude = ["examples", "vendor"] ``` 通过 LD ID、CVE 或任何别名在内联代码中抑制单个检测项: ``` API_KEY = get_key() # langdoctor: ignore=LD401 ``` ``` langgraph==1.0.5 # langdoctor: ignore=LD102 ``` 被抑制的检测项始终会作为 `suppressed: N` 计数进行报告,因此不会有任何内容被静默忽略。 ## 输出格式 `--format console`(默认) · `json` · `sarif` · `markdown` - **sarif** — GitHub code scanning;`security-severity` 带有真实的 CVSS 值。 - **markdown** — 可直接粘贴到 PR 或 issue 中。 - **json** — 机器可读,包含按严重程度划分的摘要。 退出码:`0` 表示干净(或低于 `--fail-on` 阈值),`1` 表示存在达到/高于阈值的检测项,`2` 表示扫描错误。除非使用 `--strict`,启发式检查绝不会影响退出码。 ## langdoctor 不能做什么 - ❌ **不是运行时防护。** 它扫描代码和依赖项;不会介入您的请求路径。 - ❌ **不是 LLM 防火墙。** 它不进行提示注入或内容分析。 - ❌ **不能替代 Semgrep/Snyk。** 它是那些工具遗漏的*特定于框架的*检测层 — 专门针对 LangGraph/LangChain/Langflow 的潜在隐患,按 ID 提供并附带修复方案。 它是确定性的(无 AI 调用)、离线的(CVE 数据随包携带),并且零配置。 ## 开发 ``` pip install -e ".[dev]" pytest ruff check . ``` 需要 Python 3.10+。请参阅 [`CLAUDE.md`](CLAUDE.md) 了解设计原则、检查 ID 约定以及“将安全公告视为数据”的模型。 ## 许可证 MIT © 2026 elaz48 主题:langgraph · langchain · langflow · security · sast · ai-agents · llm-security · devsecops · cli
标签:图数据库, 逆向工具