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_appdisable_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_bannersget_too_many_findings_msg 处理 (cli/src/semgrep/app/version.py:35-66)。

interfaces/semgrep_interfaces/README.md 强调:修改 schema 后必须运行 makemake 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 提供可复用的内部库...

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 认证与会话(auth、session)

继续阅读本节完整说明和来源证据。

章节 扫描上报(scans)

继续阅读本节完整说明和来源证据。

章节 仓库配置(projectconfig)

继续阅读本节完整说明和来源证据。

模块定位与总体职责

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_tokenget_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 负责:

  1. disable_nosem 标志决定是否将 nosemgrep 注释的匹配重新归类为 keptignored
  2. 调用 prepare_matches_for_app 对匹配数据做"代码脱敏/裁剪"——只有当用户在 App 端启用了 Autofix 时才会附带源码片段。
  3. 返回 (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 的具体类型。修改流程为:

  1. 编辑 *.atd 源文件。
  2. 执行 make,重新生成目标语言代码。
  3. 执行 make test,检查向后兼容性与类型检查。
  4. 手工确认后端能消费旧版 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 返回非 2xxget_deployment_from_token 返回 None,CLI 走匿名模式
.semgrepconfig 解析失败YAML 格式错误或 tags 非字符串列表抛出 SemgrepError,退出码 UNPARSEABLE_YAML_EXIT_CODE
扫描代码泄露App 端未开启 Autofixprepare_matches_for_app 自动剥离代码片段
MCP 客户端版本不匹配stdio/HTTP 协议不兼容通过 glama.aimcp.so 注册表选择兼容版本
规则 TooManyMatches模式过于宽泛(如 $STYLEperf/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 解析 DeploymentConfigget_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.pyProjectConfig 类负责解析 .semgrepconfig.yml(或 .yaml)。CONFIG_FILE_PATTERN 通过正则匹配文件名,load_all() 从 Git 根目录向当前目录遍历栈,收集到的文件按目录深度升序排序后合并 versiontags——深度更深的配置优先级更高。最终通过 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)描述。修改流程为:

  1. 编辑 .atd 源文件并调整 generate.py
  2. 运行 make,将改动传播到 .py.ts.ml 等目标。
  3. 运行 make test,检查向后兼容性、校验 schema、类型检查 Python 文件。
  4. 手动确认 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.ymlr2c-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

参见

资料来源: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 中定义的 UserAgentapp_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。

配置对象文件关键字段
UserAgentcli/src/semgrep/app/session.pyname, version, tags
DeploymentConfigcli/src/semgrep/app/auth.py/api/agent/deployments/current 解析
ProjectConfigcli/src/semgrep/app/project_config.pyversion, tagsFILE_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 文件。该类支持的字段为:

字段类型说明
versionstr配置文件格式版本,常量 FILE_VERSION = "v1"
tagsOptional[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.keptmatches_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 包含 findingsignoressearched_pathsrenamed_pathsskipped_pathsrule_idscontributions 字段;当 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 元数据等同步到云...

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 MCP 子模块

继续阅读本节完整说明和来源证据。

章节 ProjectConfig:.semgrepconfig 加载器

继续阅读本节完整说明和来源证据。

章节 Scans:扫描完成回调

继续阅读本节完整说明和来源证据。

模块定位与作用

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 方法负责一次扫描结束后的所有收尾工作,流程如下:

  1. 把规则匹配结果扁平化为 all_matches_in_scan 列表,同时覆盖 .kept.removed 两个分桶;
  2. 根据 disable_nosem 标志把匹配拆分为 findings_matchesignored_matches;
  3. 通过 prepare_matches_for_app 把内部对象转换为平台兼容格式;
  4. 仅当用户在 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 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。

high 来源证据:wrong GLIBC dependency

可能增加新用户试用和生产接入成本。

medium 来源证据:Please make the pyjwt depdency looser

可能影响升级、迁移或版本选择。

medium 能力判断依赖假设

假设不成立时,用户拿不到承诺的能力。

medium 来源证据:i got this issue when i tried to singup through email id

可能增加新用户试用和生产接入成本。

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 发现、验证与编译记录