Doramagic 项目包 · 项目说明书
semgrep 项目
轻量级静态分析工具,支持多种语言,可通过类源代码的模式查找缺陷变体。
项目概览
Semgrep 是一款开源的静态代码分析工具,以"极速扫描代码"为定位,强调本地执行、代码不上传以及对源代码语义的直接匹配。官方在 README.md 中将其描述为"Code scanning at ludicrous speed",并提供 SAST、SCA、Secrets、Assistant AI 等商业产品线,以及社区版的 CLI 和规则注册中心 Semgrep Reg...
继续阅读本节完整说明和来源证据。
Semgrep 是什么
Semgrep 是一款开源的静态代码分析工具,以"极速扫描代码"为定位,强调本地执行、代码不上传以及对源代码语义的直接匹配。官方在 README.md 中将其描述为"Code scanning at ludicrous speed",并提供 SAST、SCA、Secrets、Assistant AI 等商业产品线,以及社区版的 CLI 和规则注册中心 Semgrep Registry。社区版与商业版的差异主要体现在跨文件/跨函数数据流可达性、AI 辅助降噪与策略管理等方面。
核心架构与组件
Semgrep 项目由多个互相关联的子目录组成,每个子目录承担明确的职责:
| 子目录 / 模块 | 主要职责 |
|---|---|
cli/ | Python 编写的 CLI 入口、AppSec 平台集成、规则解析与调度逻辑 |
interfaces/semgrep_interfaces/ 与 cli/src/semgrep/semgrep_interfaces/ | 使用 ATD 描述的共享数据 schema,在 Python、TypeScript、OCaml 等多语言间同步生成类型定义 interfaces/semgrep_interfaces/README.md |
perf/r2c-rules/ | 性能基准测试与注册中心宣传用的规则包 perf/r2c-rules/README.md |
cli/src/semgrep/mcp/ | Semgrep Guardian,通过 Model Context Protocol 将扫描能力暴露给 Claude Code、Cursor、VS Code 等 AI 代理 cli/src/semgrep/mcp/README.md |
CLI 在扫描流程中负责收集匹配、过滤被 nosemgrep 注释忽略的结果,并把数据回传给 AppSec 平台。scans.py 中的 prepare_matches_for_app 与 disable_nosem 字段正是该路径的入口 (cli/src/semgrep/app/scans.py:38-78)。v1.167.0 还新增了 nosemgrep_disabled 配置项,允许平台在 CI 场景中远程关闭 nosemgrep 抑制行为。
flowchart LR
A[源代码仓库] --> B[Semgrep CLI]
B --> C[semgrep-core / 规则匹配]
C --> D[匹配结果 matches_by_rule]
D --> E{disable_nosem?}
E -- 否 --> F[按 is_ignored 拆分]
E -- 是 --> G[全部作为 findings]
F --> H[AppSec Platform / App]
G --> H
H --> I[CI 策略 / PR 注释 / IDE 提示]关键配置与扩展点
项目级配置通过 .semgrepconfig 文件加载,由 ProjectConfig 类解析并合并多目录下的配置,按目录深度升序排序以实现"深者优先" (cli/src/semgrep/app/project_config.py:43-78)。该配置最终会转换成 out.CiConfigFromRepo 结构体与后端通信。版本提示、Too-Many-Findings 横幅等内容则由 version.py 中的 _get_version_filtered_banners 与 get_too_many_findings_msg 处理 (cli/src/semgrep/app/version.py:35-66)。
interfaces/semgrep_interfaces/README.md 强调:修改 schema 后必须运行 make 与 make test,并人工校验与旧版 CLI 的向后兼容性 (interfaces/semgrep_interfaces/README.md)。perf/r2c-rules/README.md 则给出获取注册中心规则包的方式,并提醒避免 pattern: $STYLE 这类过宽匹配以免触发 TooManyMatches 错误码 12。
社区关注与已知问题
社区中讨论度较高的几类需求和痛点直接影响项目走向:
- 规则集粒度:Issue #2530 长期跟踪"在命令行按规则集排除子规则"的能力,这是 Pro 用户在 CI 中安全试运行新规则集的关键功能。
- 平台覆盖:Issue #1330 关注原生(非 WSL)Windows 支持;Issue #9685 与 #1338 分别请求 Perl 与 Rust 语言分析能力,目前尚未进入官方支持列表。
- 检测能力:Issue #2409 报告 JavaScript 浏览器中
innerHTML字符串拼接的污染传播未被识别,反映了社区对跨 Sink 数据流追踪准确性的关注。 - 常量传播增强:v1.167.0 在 const-folding 中加入减法、除法、位运算、位移与比较等算子的折叠能力,目的是在保持本地扫描体验的同时提升真阳性率。
See Also
- Semgrep MCP / Guardian 集成
- 接口 Schema 维护流程
- .semgrepconfig 加载逻辑
- 扫描结果与 App 平台通信
- 性能规则与 TooManyMatches 注意事项
来源:https://github.com/semgrep/semgrep / 项目说明书
Lib 模块
Semgrep 项目在仓库根目录下的 cli/src/semgrep/(Python 端 CLI)与 interfaces/semgrepinterfaces/(跨语言类型定义)共同构成了"Lib 模块"的主体。该模块并不直接面向终端用户暴露 API,而是为上层 CLI 入口、Semgrep AppSec Platform 集成以及 MCP Server 提供可复用的内部库...
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
模块定位与总体职责
Semgrep 项目在仓库根目录下的 cli/src/semgrep/(Python 端 CLI)与 interfaces/semgrep_interfaces/(跨语言类型定义)共同构成了"Lib 模块"的主体。该模块并不直接面向终端用户暴露 API,而是为上层 CLI 入口、Semgrep AppSec Platform 集成以及 MCP Server 提供可复用的内部库能力。
从功能层面看,Lib 模块承担了以下职责:
- 平台会话与认证:管理与 Semgrep App 之间的 HTTP 会话、Token 校验、部署标识获取等。
- 扫描上报与结果处理:将本地扫描结果打包成符合后端协议的格式,并执行
nosemgrep抑制、代码裁剪等策略。 - 仓库级配置加载:解析
.semgrepconfig.yml,将多层级元数据合并。 - 版本自检与升级提示:通过 ping App 端判断本地 CLI 是否需要升级。
- 跨语言接口契约:通过 ATD 模式定义 Python/OCaml/TypeScript 之间的数据交换类型。
- MCP 桥接能力:为 AI Agent 提供符合 Model Context Protocol 标准的工具封装。
资料来源:README.md:1-80 | cli/src/semgrep/app/auth.py:1-50 | cli/src/semgrep/app/version.py:1-40
App 子模块详解
cli/src/semgrep/app/ 目录集中了所有与 Semgrep AppSec Platform 通信的 Python 代码。下面按职责拆分其子模块。
认证与会话(auth、session)
app/auth.py 提供 get_deployment_from_token 与 get_deployment_id 等函数,用于使用 Bearer Token 调用 /api/agent/deployments/current 校验部署身份。所有请求都被 @telemetry.trace() 装饰,便于可观测性。
app/session.py 定义 UserAgent,自动拼接 Semgrep/<version> 字符串并支持通过环境变量 SEMGREP_USER_AGENT_* 注入额外标签(如 (testing))。该模块同时维护 app_session(基于 requests 的 HTTP Session)以承载跨调用的 cookie 与连接复用。
# 来自 app/session.py 的 UserAgent 摘要
class UserAgent:
name: str = field(default="Semgrep", init=False)
version: str = field(default=__VERSION__, init=False)
tags: Set[str] = field(init=False)
资料来源:cli/src/semgrep/app/auth.py:23-50 | cli/src/semgrep/app/session.py:25-60
扫描上报(scans)
app/scans.py 中的核心函数 prepare_and_send_scan_results 负责:
- 按
disable_nosem标志决定是否将nosemgrep注释的匹配重新归类为kept或ignored。 - 调用
prepare_matches_for_app对匹配数据做"代码脱敏/裁剪"——只有当用户在 App 端启用了 Autofix 时才会附带源码片段。 - 返回
(success, block_scan, block_reason)三元组,供 CI 决定是否阻断流水线。
社区关注的 issue #2530(命令行排除规则集)也涉及该模块的规则集合并逻辑,因为最终扫描数据要按用户过滤后再上报。
资料来源:cli/src/semgrep/app/scans.py:1-50
仓库配置(project_config)
app/project_config.py 实现 ProjectConfig 数据类与 load_all 工厂方法。关键点:
- 使用正则
CONFIG_FILE_PATTERN匹配.semgrepconfig或.semgrepconfig.yml/yaml。 - 从 git 根目录到当前目录逐级收集配置文件,并按目录深度升序合并(深层优先)。
tags字段经类型校验后转换为 App 协议中的out.Tag列表,并最终序列化为CiConfigFromRepo。
# ProjectConfig 文件示例
version: v1
tags:
- tag1
- tag2
资料来源:cli/src/semgrep/app/project_config.py:60-110
版本检查(version)
app/version.py 在 CLI 启动期间 ping 后端获取最新版本号,并使用 packaging.version.Version 进行 semver 比较。若发现本地版本过旧,会以彩色的 with_color 文本提示用户升级。
资料来源:cli/src/semgrep/app/version.py:20-80
跨语言接口契约
interfaces/semgrep_interfaces/ 与 cli/src/semgrep/semgrep_interfaces/ 是同一套接口的"源/派生"关系:前者保存 ATD(Adjustable Type Definitions)源文件与 generate.py,后者则由 make 把 .atd 展开为 Python/TypeScript/OCaml 的具体类型。修改流程为:
- 编辑
*.atd源文件。 - 执行
make,重新生成目标语言代码。 - 执行
make test,检查向后兼容性与类型检查。 - 手工确认后端能消费旧版 CLI 输出的 JSON。
需要注意的是,semgrep-core 的 JSON 输出与 RPC 协议被显式排除在向后兼容承诺之外;只有面向 Semgrep App 平台的协议必须保持兼容。
资料来源:interfaces/semgrep_interfaces/README.md:1-25 | cli/src/semgrep/semgrep_interfaces/README.md:1-25
MCP 与性能基准子模块
cli/src/semgrep/mcp/ 实现了 Model Context Protocol 服务器,使 Claude Code、Cursor、VS Code、Windsurf 等 AI 客户端能够调用 Semgrep 进行代码扫描。该模块仍处于活跃开发阶段,社区通过 #mcp Slack 渠道收集反馈。
perf/r2c-rules/ 则存放 Semgrep 官网 https://semgrep.dev/explore 上展示的官方规则包,每个 YAML 通过 curl https://semgrep.dev/c/p/<name> > <name>.yml 拉取;性能测试时会将其复制到目标代码库的输入目录运行。当出现 TooManyMatches 错误(如 react-css-injection 规则的 pattern: $STYLE)时,会被注释掉以避免基准挂死。
资料来源:cli/src/semgrep/mcp/README.md:1-60 | perf/r2c-rules/README.md:1-10
数据流概览
flowchart LR
CLI[semgrep CLI 入口] --> App[app/* 子模块]
App --> Auth[auth.get_deployment_from_token]
App --> Session[session.UserAgent/app_session]
App --> Project[project_config.ProjectConfig]
App --> Scans[scans.prepare_and_send_scan_results]
App --> Version[version.check_version]
App --> ATD[semgrep_interfaces.atd]
ATD --> Py[Python types]
ATD --> TS[TypeScript types]
ATD --> ML[OCaml types]
App --> MCP[mcp server]
MCP --> Agent[Claude/Cursor/VS Code]常见失败模式
| 场景 | 触发条件 | 缓解策略 |
|---|---|---|
| Token 无效 | /api/agent/deployments/current 返回非 2xx | get_deployment_from_token 返回 None,CLI 走匿名模式 |
.semgrepconfig 解析失败 | YAML 格式错误或 tags 非字符串列表 | 抛出 SemgrepError,退出码 UNPARSEABLE_YAML_EXIT_CODE |
| 扫描代码泄露 | App 端未开启 Autofix | prepare_matches_for_app 自动剥离代码片段 |
| MCP 客户端版本不匹配 | stdio/HTTP 协议不兼容 | 通过 glama.ai 或 mcp.so 注册表选择兼容版本 |
规则 TooManyMatches | 模式过于宽泛(如 $STYLE) | 在 perf/r2c-rules/ 中临时注释该规则 |
See Also
- CLI 入口与命令参数
- Semgrep 接口定义(ATD)
- MCP Server 集成
- 性能基准与 r2c 规则集
资料来源:README.md:1-80 | cli/src/semgrep/app/auth.py:1-50 | cli/src/semgrep/app/version.py:1-40
Src 模块
Semgrep 仓库的源码遵循「Python CLI 前端 + 共享 ATD 接口 + 应用集成」的分层架构:CLI 主要位于 cli/src/semgrep/,跨语言类型契约集中在顶层 interfaces/semgrepinterfaces/,性能基准规则集存放在 perf/。这种结构让 Python CLI、OCaml 核心(semgrep-core)以及外部集成(S...
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
Semgrep 仓库的源码遵循「Python CLI 前端 + 共享 ATD 接口 + 应用集成」的分层架构:CLI 主要位于 cli/src/semgrep/,跨语言类型契约集中在顶层 interfaces/semgrep_interfaces/,性能基准规则集存放在 perf/。这种结构让 Python CLI、OCaml 核心(semgrep-core)以及外部集成(Semgrep AppSec Platform、MCP 服务器)可以共享同一份数据契约,并按子目录隔离关注点。
资料来源:README.md
源码目录结构
graph TD
Root[semgrep 仓库] --> CLI[cli/src/semgrep/]
Root --> IF[interfaces/semgrep_interfaces/]
Root --> Perf[perf/]
CLI --> App[app/]
CLI --> Mcp[mcp/]
CLI --> Si[semgrep_interfaces/]
App --> Auth[auth.py]
App --> Sess[session.py]
App --> Scan[scans.py]
App --> PC[project_config.py]
Mcp --> SemgrepGuardian[Semgrep Guardian MCP 服务器]
Si --> PyWrap[Python 接口包装]
IF --> ATD[ATD 源文件]
Perf --> Rules[r2c-rules]各子目录职责如下:
cli/src/semgrep/app/:与 Semgrep AppSec Platform 通信的模块,负责认证、会话、扫描上报、项目配置加载。cli/src/semgrep/mcp/:基于 Model Context Protocol 的服务器实现,使 LLM 与 IDE(Claude Code、Cursor、VS Code、Windsurf、Kiro)可调用 Semgrep 扫描。cli/src/semgrep/semgrep_interfaces/:CLI 端对interfaces/中 ATD 接口的 Python 包装,由make生成。interfaces/semgrep_interfaces/:跨语言接口规范(ATD)。修改后须运行generate.py+make以同步到.py、.ts、.ml。perf/r2c-rules/:官网「Explore」页面展示的官方规则包,可作为大型语料上的性能基准输入。
资料来源:cli/src/semgrep/semgrep_interfaces/README.md,interfaces/semgrep_interfaces/README.md,perf/r2c-rules/README.md
应用集成层(cli/src/semgrep/app/)
认证与会话
auth.py 通过 Bearer Token 调用 /api/agent/deployments/current 解析 DeploymentConfig;get_deployment_id() 返回与该 token 关联的部署 ID。session.py 中的 UserAgent 自动将版本号(如 semgrep/0.1.2)及 SEMGREP_USER_AGENT_* 等环境标签注入到所有出站请求头,便于后端识别调用来源。
资料来源:cli/src/semgrep/app/auth.py,cli/src/semgrep/app/session.py
项目配置加载
project_config.py 的 ProjectConfig 类负责解析 .semgrepconfig.yml(或 .yaml)。CONFIG_FILE_PATTERN 通过正则匹配文件名,load_all() 从 Git 根目录向当前目录遍历栈,收集到的文件按目录深度升序排序后合并 version 与 tags——深度更深的配置优先级更高。最终通过 to_CiConfigFromRepo() 转换为 out.CiConfigFromRepo 上报给 AppSec Platform。YAML 解析失败会以 UNPARSEABLE_YAML_EXIT_CODE 抛出 SemgrepError。
资料来源:cli/src/semgrep/app/project_config.py
扫描上报
scans.py 中的 report_findings 是核心入口。值得注意的是:在 --sarif 或 --disable-nosem 模式下,被 # nosemgrep 抑制的命中会落在 .kept 而非 .removed,因此代码会重新遍历 kept + removed 后再用 m.match.extra.is_ignored 拆分;同时强调「autofix 是当前唯一表示会上传源码的开关」,除 autofix 之外的请求都会剥离源码字段。这一逻辑与 v1.167.0 新增的 nosemgrep_disabled 字段直接呼应。
资料来源:cli/src/semgrep/app/scans.py
MCP 服务器模块(cli/src/semgrep/mcp/)
mcp/ 实现了 Semgrep Guardian:将 Semgrep Code、Supply Chain、Secrets 打包为 MCP 工具集,原生集成 Claude Code、Cursor、VS Code、Windsurf、Kiro 等客户端。安装后,AI 编程代理生成的每个文件都会被自动扫描,发现问题时提示代理重新生成,直到 Semgrep 返回干净结果或用户主动忽略。该模块同时支持 stdio 与 Streamable HTTP 两种传输方式。
资料来源:cli/src/semgrep/mcp/README.md
接口定义与修改流程
所有跨语言共享类型集中在 interfaces/semgrep_interfaces/,使用 ATD(Adjustable Type Definitions)描述。修改流程为:
- 编辑
.atd源文件并调整generate.py。 - 运行
make,将改动传播到.py、.ts、.ml等目标。 - 运行
make test,检查向后兼容性、校验 schema、类型检查 Python 文件。 - 手动确认 CLI 老版本的兼容性——AppSec Platform 后端必须仍能消费 Semgrep 1.50.0 输出的数据。注意:与 semgrep-core JSON 输出或 RPC 相关的类型不要求向后兼容。
资料来源:interfaces/semgrep_interfaces/README.md,cli/src/semgrep/semgrep_interfaces/README.md
性能规则与社区议题
perf/r2c-rules/ 收录了官网展示的规则包(如 r2c-ci.yml、r2c-bug-scan),最初通过 curl https://semgrep.dev/c/p/<name> 抓取,可作为大型语料基准的输入。过宽的 pattern(如 $STYLE)可能触发 TooManyMatches(退出码 12),r2c-ci.yml 中的 react-css-injection 已被注释以避免此问题。
社区长期关注的高互动议题(如 Windows 原生支持 #1330、Rust 语言支持 #1338、Perl 语言支持 #9685、JS 浏览器拼接绕过 #2409 以及命令行排除规则 #2530)也是源码演进的重要驱动力,常直接体现在 app/ 与 mcp/ 的功能扩展中。
资料来源:perf/r2c-rules/README.md
参见
- semgrep-rules:官方规则集合
- mcp-server-semgrep:MCP 服务器的早期灵感来源
- Semgrep 文档
- 贡献指南
- CLI 参考与退出码
资料来源:README.md
Server 模块
Semgrep 项目中存在两类承担"服务端"职责的子系统:一类面向 AI/LLM 智能体(即 Semgrep Guardian / MCP Server),另一类面向 Semgrep AppSec Platform 平台(即 cli/src/semgrep/app 下的会话、鉴权、扫描上报模块)。两者共同构成 Semgrep 的服务端交互层,分别处理"被集成"与"上报云端"...
继续阅读本节完整说明和来源证据。
模块概述
Semgrep 项目中存在两类承担"服务端"职责的子系统:一类面向 AI/LLM 智能体(即 Semgrep Guardian / MCP Server),另一类面向 Semgrep AppSec Platform 平台(即 cli/src/semgrep/app 下的会话、鉴权、扫描上报模块)。两者共同构成 Semgrep 的服务端交互层,分别处理"被集成"与"上报云端"两种方向的请求。资料来源:cli/src/semgrep/mcp/README.md:1-30。
cli/src/semgrep/mcp/ 目录下的 MCP Server 是基于 Model Context Protocol 的标准化服务器实现,可被 Claude Code、Cursor、VS Code、Windsurf、Kiro 等支持 MCP 的客户端调用,对外暴露 Semgrep Code、Supply Chain、Secrets 三类扫描能力。资料来源:cli/src/semgrep/mcp/README.md:1-10。
架构与传输协议
MCP Server 支持两种传输方式:标准输入输出(stdio) 与 流式 HTTP(streamable HTTP),分别适配本地进程内调用与跨进程/跨网络调用场景。资料来源:cli/src/semgrep/mcp/README.md:60-100。
flowchart LR
A[AI Agent<br/>Claude Code / Cursor] -->|MCP stdio| B[Semgrep MCP Server]
A -->|MCP streamable HTTP| B
B -->|spawn| C[semgrep CLI<br/>Code / Supply Chain / Secrets]
C -->|results| B
B -->|tools/call response| A
B -.->|metrics| D[Semgrep AppSec Platform]在 Semgrep AppSec Platform 通信路径上,客户端使用 cli/src/semgrep/app/session.py 中定义的 UserAgent 与 app_session 对象发起 HTTP 请求;用户代理字符串形如 semgrep/0.1.2 (testing),便于平台侧做遥测归因。资料来源:cli/src/semgrep/app/session.py:25-50。
鉴权与配置加载
鉴权流程由 cli/src/semgrep/app/auth.py 提供:通过环境变量中的 token 调用 /api/agent/deployments/current 端点,验证成功后返回 DeploymentConfig 记录;该配置会驱动后续扫描的部署上下文。资料来源:cli/src/semgrep/app/auth.py:18-50。
仓库级别的元信息(标签、版本)由 cli/src/semgrep/app/project_config.py 解析:.semgrepconfig 文件从 Git 根目录向上回溯收集,按路径深度排序后合并,生成 ProjectConfig(version, tags) 对象。资料来源:cli/src/semgrep/app/project_config.py:19-80。
| 配置对象 | 文件 | 关键字段 |
|---|---|---|
UserAgent | cli/src/semgrep/app/session.py | name, version, tags |
DeploymentConfig | cli/src/semgrep/app/auth.py | 从 /api/agent/deployments/current 解析 |
ProjectConfig | cli/src/semgrep/app/project_config.py | version, tags(FILE_VERSION="v1") |
扫描上报与结果处理
cli/src/semgrep/app/scans.py 负责将本地扫描结果整理为平台所需的 CiScanCompleteResponse。其核心逻辑是依据 disable_nosem 开关与 match.extra.is_ignored 标志,将匹配项重划分为"需修复发现"与"已忽略发现"两组;只有开启 autofix 时,代码片段才会被一并上传。资料来源:cli/src/semgrep/app/scans.py:1-60。
最新版本 v1.167.0 在扫描配置中新增 nosemgrep_disabled 字段,使平台可以集中管控 # nosemgrep 注释是否生效,从而避免"通过注释绕过"这一社区长期讨论的问题(参见社区议题 #2409 关于 JS 浏览器侧安全串联绕过的讨论)。资料来源:README.md:1-50。
部署与运行
MCP Server 既可以通过 Python 包直接运行,也可以经由 Docker 镜像 ghcr.io/semgrep/mcp 以 stdio 模式启动,命令形如 ["-i", "--rm", "ghcr.io/semgrep/mcp", "-t", "stdio"]。资料来源:cli/src/semgrep/mcp/README.md:60-100。
在 IDE 集成方面,Claude Code 通过 /plugin 市场搜索 Semgrep 并执行 /setup-semgrep-plugin 完成安装;Cursor 则可通过 ⌘⇧J > Plugins 添加该插件。资料来源:cli/src/semgrep/mcp/README.md:25-50。
性能基线与回归基准则由 perf/README.md 描述的 benchmark 流程提供,结果会上报到 semgrep dashboard,为服务端体验(如响应时间、规则匹配吞吐)提供量化依据。资料来源:perf/README.md:1-30。
See Also
- README.md — 项目总览与产品矩阵
- cli/src/semgrep/mcp/README.md — MCP Server 详细使用与集成说明
- cli/src/semgrep/app/scans.py — 扫描上报与匹配分类逻辑
- interfaces/semgrep_interfaces/README.md — 跨语言接口定义与兼容策略
来源:https://github.com/semgrep/semgrep / 项目说明书
App 模块
cli/src/semgrep/app/ 是 Semgrep CLI 与 Semgrep AppSec Platform(semgrep.dev)之间的桥接层,负责管理与云端服务交互所需的所有客户端功能。该模块封装了身份认证、会话管理、版本兼容性检查、仓库项目级配置加载以及 CI 扫描结果上报等职责,遵循 "代码本地分析、结果按需上报" 的隐私原则。资料来源:[cli/sr...
继续阅读本节完整说明和来源证据。
模块概述
cli/src/semgrep/app/ 是 Semgrep CLI 与 Semgrep AppSec Platform(semgrep.dev)之间的桥接层,负责管理与云端服务交互所需的所有客户端功能。该模块封装了身份认证、会话管理、版本兼容性检查、仓库项目级配置加载以及 CI 扫描结果上报等职责,遵循 "代码本地分析、结果按需上报" 的隐私原则。资料来源:cli/src/semgrep/app/__init__.py:1-1
模块按职责拆分为多个子模块:
| 子模块 | 职责 |
|---|---|
auth.py | 处理 CLI 与 AppSec Platform 之间的身份认证与 Token 管理 |
session.py | 提供 HTTP 会话、连接复用与请求重试 |
version.py | 检查 CLI 与服务端协议的版本兼容性 |
project_config.py | 加载、解析与校验仓库中的 .semgrepconfig 文件 |
scans.py | 在 CI 扫描结束时汇总结果并构造上报 payload |
资料来源:cli/src/semgrep/app/scans.py:1-1、cli/src/semgrep/app/project_config.py:1-1
ProjectConfig:仓库级配置加载
ProjectConfig 类负责发现并解析放置在 Git 仓库各级目录中的 .semgrepconfig 文件。该类支持的字段为:
| 字段 | 类型 | 说明 |
|---|---|---|
version | str | 配置文件格式版本,常量 FILE_VERSION = "v1" |
tags | Optional[List[str]] | 仓库级别标签,用于在 AppSec Platform 中分组与策略路由 |
资料来源:cli/src/semgrep/app/project_config.py:18-44
tags 字段通过 @tags.validator 装饰器做严格校验:值必须为字符串列表,否则抛出 ValueError("tags must be a list of strings")。资料来源:cli/src/semgrep/app/project_config.py:36-44
配置文件的发现通过静态方法 is_project_config_file(file_path) 配合 CONFIG_FILE_PATTERN 正则实现;_find_all_config_files 使用栈式遍历,从 cwd_path 一直回溯到 Git 根目录以收集所有命中文件。资料来源:cli/src/semgrep/app/project_config.py:46-69
load_all 方法先按目录深度升序排序(更深目录的配置优先),再依次 load_from_file 解析,并以浅合并方式汇总到 all_metadata 字典,最终构造统一的 ProjectConfig 实例。当 YAML 无法解析时抛出 SemgrepError,并带上 UNPARSEABLE_YAML_EXIT_CODE 退出码。资料来源:cli/src/semgrep/app/project_config.py:82-100
最终 to_CiConfigFromRepo 会将内部数据结构映射为对外协议类型 out.CiConfigFromRepo(version=out.Version(...), tags=...),供 AppSec Platform 消费。资料来源:cli/src/semgrep/app/project_config.py:102-107
Scans:CI 扫描结果处理
scans.py 中的扫描处理器负责把本地匹配结果转换为 App 所需的 payload。核心方法 process_scan 接收匹配结果、规则集合、贡献度统计、引擎类型、进度条以及 disable_nosem 标志,返回 out.CiScanCompleteResponse。资料来源:cli/src/semgrep/app/scans.py:1-9
匹配结果会先经过重新分桶:以 MatchExtra.is_ignored 为依据,从 matches_by_rule.kept 与 matches_by_rule.removed 中聚合全部 RuleMatch。当 disable_nosem=True 时,# nosem 注释抑制的命中也会被强制纳入 findings_matches,从而保证在 CI 中始终显示开发者主动忽略的告警。资料来源:cli/src/semgrep/app/scans.py:18-32
每条匹配在发送给 App 之前都通过 prepare_matches_for_app 进行清理,再调用 to_app_finding_format(commit_date, remove_dataflow_content=not self.autofix) 转换形态。remove_dataflow_content 参数确保仅在启用 autofix 时才会上传代码片段(autofix 是当前唯一表示用户同意存储代码的开关)。资料来源:cli/src/semgrep/app/scans.py:40-52
最终构造的 out.CiScanResults 包含 findings、ignores、searched_paths、renamed_paths、skipped_paths、rule_ids 与 contributions 字段;当 self.dependency_query 为真时,还会附上 out.CiScanDependencies(lockfile_dependencies) 以便 AppSec Platform 关联依赖扫描结果。资料来源:cli/src/semgrep/app/scans.py:54-70
社区提示:当用户希望"先在本地试跑某个新规则集,再决定是否纳入 CI"时(参见 issue #2530),disable_nosem 机制可以确保在试跑阶段不丢失任何命中,便于评估规则集在真实代码库上的覆盖度。
数据流与模块协作
下图描述 CLI 触发 CI 扫描时各 App 子模块的协作关系:
sequenceDiagram
participant CLI as Semgrep CLI
participant Auth as app/auth.py
participant Sess as app/session.py
participant PC as app/project_config.py
participant Scan as app/scans.py
participant App as AppSec Platform
CLI->>Auth: 获取/刷新 Token
Auth-->>CLI: 凭据
CLI->>Sess: 建立 HTTP 会话
CLI->>PC: load_all() 解析 .semgrepconfig
PC-->>CLI: CiConfigFromRepo (version, tags)
CLI->>Scan: process_scan(matches, rules, ...)
Scan->>Scan: 重新分桶 findings/ignores
Scan->>Scan: prepare_matches_for_app + to_app_finding_format
Scan-->>CLI: CiScanCompleteResponse
CLI->>App: 上报 CiScanResults资料来源:cli/src/semgrep/app/scans.py:1-70、cli/src/semgrep/app/project_config.py:82-107
常见失败模式
- 非法
.semgrepconfig:YAML 解析失败会抛出SemgrepError,附带UNPARSEABLE_YAML_EXIT_CODE;请使用semgrep validate或在编辑器中先校验。资料来源:cli/src/semgrep/app/project_config.py:93-100 tags字段类型错误:若提供非列表或非字符串元素,check_tags校验器立即抛出ValueError,CLI 会在加载阶段终止。资料来源:cli/src/semgrep/app/project_config.py:36-44- 隐私顾虑:默认情况下
remove_dataflow_content=True,代码片段不会上传;只有开启autofix时才会附带代码内容。资料来源:cli/src/semgrep/app/scans.py:40-52
See Also
- README.md — 项目概览与隐私策略
- cli/src/semgrep/mcp/README.md — Semgrep Guardian / MCP Server 集成
- interfaces/semgrep_interfaces/README.md — CLI 与 AppSec Platform 之间的接口定义与版本演进规则
资料来源:cli/src/semgrep/app/scans.py:1-1、cli/src/semgrep/app/project_config.py:1-1
Cli 模块
Semgrep 的 CLI 模块位于仓库的 cli/src/semgrep/ 目录,是用户与 Semgrep 静态分析引擎交互的主要入口。该模块用 Python 包装了底层 OCaml 编写的 semgrep-core,既可以独立运行做一次性搜索,也能在登录后与 Semgrep AppSec 平台双向通信,把扫描结果、版本横幅、.semgrepconfig 元数据等同步到云...
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
模块定位与作用
Semgrep 的 CLI 模块位于仓库的 cli/src/semgrep/ 目录,是用户与 Semgrep 静态分析引擎交互的主要入口。该模块用 Python 包装了底层 OCaml 编写的 semgrep-core,既可以独立运行做一次性搜索,也能在登录后与 Semgrep AppSec 平台双向通信,把扫描结果、版本横幅、.semgrepconfig 元数据等同步到云端,并把平台下发的策略拉回到本地执行。
根据 README.md 的描述,CLI 默认不上传用户代码,所有分析都在本地完成;只有显式启用 Autofix 时,代码片段才会随修复方案一起提交。CLI 还通过 --metrics=off 提供可选的指标上报开关,关闭后远程 Registry 规则指标将不会回传。
目录结构与子模块
CLI 模块在仓库中按职责被拆分为若干子目录,核心划分如下:
| 子目录 | 职责描述 |
|---|---|
cli/src/semgrep/app/ | 与 AppSec 平台通信、扫描会话管理、版本与横幅处理 |
cli/src/semgrep/mcp/ | 通过 Model Context Protocol 将 Semgrep 暴露给 AI 编码代理 |
cli/src/semgrep/semgrep_interfaces/ | 由 ATD 源文件生成的 Python 数据契约 |
资料来源:cli/src/semgrep/semgrep_interfaces/README.md
MCP 子模块
cli/src/semgrep/mcp/ 子模块实现了 Semgrep Guardian,它把 Semgrep Code、Supply Chain 和 Secrets 三类扫描打包成一个统一的 MCP 服务器,支持 Claude Code、Cursor、VS Code、Windsurf 和 Kiro 等客户端。安装完成后,AI 代理生成的每一个文件都会立即经过 Semgrep 扫描,发现问题时代理会被提示重写代码,直到结果清空或用户主动 dismiss。
资料来源:cli/src/semgrep/mcp/README.md
核心组件
ProjectConfig:`.semgrepconfig` 加载器
cli/src/semgrep/app/project_config.py 定义了 ProjectConfig 类,用于发现、加载并校验项目根目录下的 .semgrepconfig 配置文件。当前 schema 版本固定为 v1,支持以下字段:
version:schema 版本号,默认"v1"tags:字符串列表,可选,用于在 AppSec 平台给扫描打标签
加载流程由 ProjectConfig.load_all() 实现:从 Path.cwd() 一路向上遍历到 Git 根,收集所有匹配 CONFIG_FILE_PATTERN 的配置文件;按目录深度升序排序后逐个合并,越深的配置覆盖较浅的配置,最终通过 to_CiConfigFromRepo() 方法转换为平台协议所需的 out.CiConfigFromRepo 消息。
资料来源:cli/src/semgrep/app/project_config.py
Scans:扫描完成回调
cli/src/semgrep/app/scans.py 中的 Scans.complete_scan 方法负责一次扫描结束后的所有收尾工作,流程如下:
- 把规则匹配结果扁平化为
all_matches_in_scan列表,同时覆盖.kept和.removed两个分桶; - 根据
disable_nosem标志把匹配拆分为findings_matches与ignored_matches; - 通过
prepare_matches_for_app把内部对象转换为平台兼容格式; - 仅当用户在 App 中开启了 Autofix 时,才会上传代码片段。
v1.167.0 发布说明中提到的 nosemgrep_disabled 字段,正是由平台下发给 disable_nosem 参数,使本地扫描可以忽略 nosemgrep 注释,避免审计盲区。
资料来源:cli/src/semgrep/app/scans.py
version.py:版本横幅与终端美化
cli/src/semgrep/app/version.py 负责把后端下发的版本横幅渲染到终端。核心函数 get_too_many_findings_msg() 在 _get_version_filtered_banners() 中筛选 identifier == "too_many_findings" 的横幅,再通过 with_color(Colors.cyan, ...) 为链接文本上色,并用 re.split 把链接与正文分开渲染。当启用新 CLI UX 时,还会额外加 ✨ 前缀和缩进。
flowchart LR
A[扫描结束] --> B[Scans.complete_scan]
B --> C{disable_nosem?}
C -- 是 --> D[全部作为 findings]
C -- 否 --> E[按 is_ignored 拆分]
E --> F[prepare_matches_for_app]
D --> F
F --> G[POST 到 AppSec 平台]
G --> H[banners 响应]
H --> I[version.py 渲染]资料来源:cli/src/semgrep/app/version.py
接口与契约
interfaces/semgrep_interfaces/ 与 cli/src/semgrep/semgrep_interfaces/ 两个目录保存着 Semgrep 各组件之间的共享数据契约。这些接口由 .atd (Adjustable Type Definitions) 源文件驱动,通过 make 自动生成对应的 Python、TypeScript 与 OCaml 代码;修改流程要求:先编辑 .atd 源文件 → 运行 make 传播变更 → 运行 make test 校验向后兼容性和 schema。
需要特别注意的是,与 semgrep-core 的 JSON 输出或 RPC 相关的类型不需要向后兼容,但与后端通信的类型必须保持兼容,以保证 Semgrep 1.50.0 等旧版本仍能被新后端正确消费。
资料来源:interfaces/semgrep_interfaces/README.md
性能与基准
perf/ 目录下的基准脚本会在 CI 中以 juice-shop 和 njsscan 等真实仓库作为输入,反复扫描以收集耗时指标,例如 semgrep.bench.njs.std.total-time。本地执行 make 仅做基准测量,不会把结果上传,只在 CI 环境中才会把数据上报到 metabase 仪表盘,便于团队跟踪性能回归。perf/r2c-rules/ 则收录了 Semgrep 官网首页宣传的官方规则包,源自 https://semgrep.dev/c/p/<name>。
资料来源:perf/README.md、perf/r2c-rules/README.md
社区关注与已知限制
围绕 CLI 模块,社区反馈集中在以下方向:
- 原生 Windows 支持 (#1330,30 条评论):官方目前只承诺 WSL + pip 安装路径,缺少
cmd.exe下的原生 CLI 体验,是跨平台用户最常被提及的痛点。 - 规则集按需排除 (#2530,34 条评论):希望在 CLI 层面支持从
--config=p/...中临时禁用个别规则,便于在 CI 中安全试用新规则集,而不会一次性引入大量误报。 - 新语言支持:Perl (#9685) 与 Rust (#1338) 等语言长期有需求,但目前仍依赖社区贡献者或商业版。
- JS 浏览器安全扫描精度 (#2409):报告显示某些
eval/Function构造的字符串拼接绕过模式尚未被现有规则覆盖。
资料来源:README.md
See Also
资料来源:cli/src/semgrep/semgrep_interfaces/README.md
失败模式与踩坑日记
保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。
可能增加新用户试用和生产接入成本。
可能影响升级、迁移或版本选择。
假设不成立时,用户拿不到承诺的能力。
可能增加新用户试用和生产接入成本。
Pitfall Log / 踩坑日志
项目:semgrep/semgrep
摘要:发现 11 个潜在踩坑项,其中 1 个为 high/blocking;最高优先级:安装坑 - 来源证据:wrong GLIBC dependency。
1. 安装坑 · 来源证据:wrong GLIBC dependency
- 严重度:high
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:wrong GLIBC dependency
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 证据:community_evidence:github | https://github.com/semgrep/semgrep/issues/11760 | 来源讨论提到 python 相关条件,需在安装/试用前复核。
2. 安装坑 · 来源证据:Please make the pyjwt depdency looser
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:Please make the pyjwt depdency looser
- 对用户的影响:可能影响升级、迁移或版本选择。
- 证据:community_evidence:github | https://github.com/semgrep/semgrep/issues/11738 | 来源类型 github_issue 暴露的待验证使用条件。
3. 能力坑 · 能力判断依赖假设
- 严重度:medium
- 证据强度:source_linked
- 发现:README/documentation is current enough for a first validation pass.
- 对用户的影响:假设不成立时,用户拿不到承诺的能力。
- 证据:capability.assumptions | https://github.com/semgrep/semgrep | README/documentation is current enough for a first validation pass.
4. 运行坑 · 来源证据:i got this issue when i tried to singup through email id
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个运行相关的待验证问题:i got this issue when i tried to singup through email id
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 证据:community_evidence:github | https://github.com/semgrep/semgrep/issues/11759 | 来源类型 github_issue 暴露的待验证使用条件。
5. 维护坑 · 维护活跃度未知
- 严重度:medium
- 证据强度:source_linked
- 发现:未记录 last_activity_observed。
- 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
- 证据:evidence.maintainer_signals | https://github.com/semgrep/semgrep | last_activity_observed missing
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 证据:downstream_validation.risk_items | https://github.com/semgrep/semgrep | no_demo; severity=medium
7. 安全/权限坑 · 存在评分风险
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:风险会影响是否适合普通用户安装。
- 证据:risks.scoring_risks | https://github.com/semgrep/semgrep | no_demo; severity=medium
8. 安全/权限坑 · 来源证据:PartialParsing on PHP readonly-promoted constructor parameter (typed promoted property)
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:PartialParsing on PHP readonly-promoted constructor parameter (typed promoted property)
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 证据:community_evidence:github | https://github.com/semgrep/semgrep/issues/11740 | 来源讨论提到 docker 相关条件,需在安装/试用前复核。
9. 安全/权限坑 · 来源证据:Remove EOL PCRE 8.4 for security compliance
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:Remove EOL PCRE 8.4 for security compliance
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 证据:community_evidence:github | https://github.com/semgrep/semgrep/issues/11757 | 来源类型 github_issue 暴露的待验证使用条件。
10. 维护坑 · issue/PR 响应质量未知
- 严重度:low
- 证据强度:source_linked
- 发现:issue_or_pr_quality=unknown。
- 对用户的影响:用户无法判断遇到问题后是否有人维护。
- 证据:evidence.maintainer_signals | https://github.com/semgrep/semgrep | issue_or_pr_quality=unknown
11. 维护坑 · 发布节奏不明确
- 严重度:low
- 证据强度:source_linked
- 发现:release_recency=unknown。
- 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
- 证据:evidence.maintainer_signals | https://github.com/semgrep/semgrep | release_recency=unknown
来源:Doramagic 发现、验证与编译记录