别让CVE编号卡在邮件里:GitHub提交漏洞编号的两种实践路径
2026/9/16 20:06:22 网站建设 项目流程

挖到一个漏洞后,最难的事情往往不是写POC,而是给这个漏洞一个正式的“身份证”——CVE编号。很多新手卡在提交这一步:发邮件没人回、社区问一圈被指去读文档、厂商 CNA 的入口找半天找不到。其实对开源项目相关漏洞来说,最省事的路径就在你天天用的 GitHub 里,通过仓库的 Security 功能,或者走 cve.org 在 GitHub 上的官方仓库,都能完成 CVE 申请,全程可视、可跟踪,不需要跟任何陌生人邮件拉扯。

这篇文章写给第一次接触 CVE 的人。我会把两种常见提交路径拆开讲:一种是针对你自己仓库或你参与维护的开源项目,用 GitHub Security Advisory 直接申请 CVE 编号;另一种是作为独立研究者,通过 cve.org 的 GitHub 仓库走 CNA 流程。每一步我会说清楚在哪个页面、填什么、为什么要这么填,同时用文字把截图里的关键内容描述出来,你照着界面找就行。

1. 先搞清楚:通过GitHub提交CVE到底是怎么一回事

1.1 一条从漏洞发现到CVE编号的完整路径

CVE 的全称是 Common Vulnerabilities and Exposures,中文一般叫“通用漏洞披露”。它不是一个漏洞数据库本身,而是一套编号系统,相当于给每个公开漏洞发一个唯一门牌号,格式就是 CVE-年份-序号,比如 CVE-2025-1695。这个编号由 MITRE 主导维护,但 MITRE 并不会亲自给所有漏洞编号,而是授权给全球几百个 CNA(CVE Numbering Authority,CVE 编号授权机构)来分配。

GitHub 本身就是一家 CNA,而且它只管一个特定范围:托管在 GitHub 上的开源项目相关漏洞。这对我们普通研究者来说是个巨大的便利。你不需要知道 MITRE 的联系邮箱,不需要等厂商层层转发,只要项目在 GitHub 上,你就可以通过仓库自带的 Security Advisory 功能申请编号。

整个流程可以简化成这样:发现漏洞 → 在仓库里创建一份私密的漏洞描述(Draft Security Advisory) → 填写影响版本、漏洞类型、修复信息 → 提交 CVE ID 申请 → 等 GitHub CNA 审核分配编号 → 发布公告 → 编号和描述自动同步到 cve.org。整个过程都在 GitHub 上完成,每一步都有记录,这是我最推荐新手走这条路的原因。

1.2 提交前必须准备好的三样东西

很多新手打开 Security 页面后一脸懵,不知道从哪下手,其实是因为没提前准备信息。我建议你在动手之前先把这三样东西备齐。

第一,漏洞本身的信息。包括漏洞类型(XSS、SQL注入、命令注入、越权等,需要对应到 CWE 编号)、影响版本范围、修复版本(如果有)、漏洞根因大致的描述。这些信息越完整,审核越顺利。

第二,CVSS 评分。GitHub 的安全公告表单里有自带的 CVSS 计算器,你可以直接选向量自动算出分数,也可以用 FIRST 官网的 CVSS v3.1 计算器先算好再填进去。新手最容易在这里卡壳,觉得每个字母都认识但组合起来不知道什么意思,我后面会专门拆开讲。

第三,一个描述用的英文文本。CNA 审核员看到的描述是全球统一的,建议用英文写。如果英文不好,可以先写中文再用翻译工具润色,但一定要保证描述准确,宁可简单也不要用机器翻译出来一堆歧义。

提示:如果你只是在别人仓库里发现了一个漏洞,自己没有该仓库的管理权限,走不了 Security Advisory,那就把漏洞信息整理好发给仓库维护者,让他帮你走流程,或者用后面要讲的 cve-request 方式提交。

2. 准备工作:账号权限与漏洞报告的关键字段

2.1 账号、仓库与权限要求

先确认一个最基本的问题:你有没有 GitHub 账号?没有的话先去注册,这一步不用多解释。接着你要确定目标仓库是谁的。如果你要提交漏洞的仓库是你自己的,那直接进去操作;如果是别人维护的仓库,你需要已经是这个仓库的协作者(Collaborator),或者至少能联系到维护者。

为什么强调这一点?因为 GitHub Security Advisory 的创建权和管理权绑在仓库管理员身上。一般情况下,仓库的 Admin 角色才能创建安全公告、请求 CVE 编号。如果你是独立研究者,没有权限,那就走“告知维护者”的路线。

对于自己的仓库,还有一个前置条件:仓库必须是公开的(Public)。私有仓库虽然也能创建安全公告草案,但如果想通过 GitHub 申请公开的 CVE 编号,最终发布时仓库需要是公开状态,这是我在实际操作中确认过的。你可以在仓库 Settings 里检查可见性,确认是 Public 再做后续操作。

2.2 一套可以直接抄的漏洞报告模板

在打开任何表单之前,我建议你先把信息填进下面这个模板里,然后照着往网页上搬,这样不会漏项。我长期用这个模板,CNA 基本不需要追着问补充材料。

## 漏洞基础信息 - 受影响的仓库/项目名称: - 项目主页 URL: - 漏洞类型(CWE编号): - 受影响的版本范围: - 已修复的版本(如果没有写 None): - 漏洞发现者(你的昵称): ## 技术细节 - 攻击者需要什么权限才能触发(匿名/低权限用户/普通用户/管理员): - 触发路径(例如:访问 /api/user?id=1 注入 SQL): - 漏洞根因(一两句话说明,例如:未对用户输入进行参数化查询): - 对安全性的影响(例如:可读取任意用户手机号、可在管理员页面执行 JS): ## 复现步骤 1. 在 xxx 版本下执行 xxx 2. 构造请求 xxx 3. 观察 xxx 异常 ## 修复建议 - 建议修复版本号: - 修复 PR/Commit 链接(如果有):

这个模板你可以直接复制到本地文档,每次发现漏洞就填一份。你会发现后面填 GitHub 表单基本就是“复制粘贴+微调”的过程,节省大量时间。

2.3 CVSS 评分不会算怎么办

CVSS 是安全社区用来衡量漏洞严重程度的通用标准,目前主流是 v3.1,部分新场景已经过渡到 v4.0。GitHub 的安全公告表单里提供了可视化的 CVSS 计算器,你不需要背向量公式,跟着选项选就是了。

举个例子:一个不需要身份认证、攻击者直接构造 URL 就能触发的反射型 XSS,常见向量是这样的:AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N。拆开看就是攻击途径是网络(N)、攻击复杂度低(L)、不需要权限(N)、需要用户交互(R,比如点击链接)、影响范围不超出组件(U)、机密性影响高(H)、完整性和可用性无影响(I:N/A:N)。算下来 Base Score 是 6.1,属于 Medium。

我的经验是:新手在 CVSS 上别太纠结,按实际情况如实选就行。有些人是“致命漏洞恐惧症”,什么都要往 Critical 上凑,其实没必要。CVSS 分数不影响 CVE 是否分配,只影响公开后的严重程度展示。打分虚高反而会让维护者和 CNA 觉得报告不专业。

3. 路径一:在 GitHub Security Advisory 里申请 CVE 编号(新手最稳的做法)

3.1 创建安全公告草案:进入 Security 页面

确认你的仓库满足公开条件后,打开仓库主页,在代码文件列表上方会有一排 Tab:Code、Issues、Pull Requests、Discussions、Actions、Projects、Security、Insights、Settings。点击 Security,然后选择左侧菜单里的 Security Advisories。

在 Security Advisories 页面右上方有一个绿色的按钮,写着 New draft security advisory。点击它,就会进入一个标题为 New draft security advisory 的编辑页面。

这一步对应的截图内容通常会显示:左侧是公告表单,右侧是预览和提示信息,顶部有一个 Draft 状态的标签。这说明你创建的是一份私密的公告草案,在你主动发布之前,只有仓库管理员能看到,不会泄露给外界。这一点很重要,因为安全漏洞在未修复前公开,等于给攻击者递刀子,所以 GitHub 默认先把公告做成私密的,等你准备好了再发布。

3.2 逐项填写:Description、CWE、CVSS 和影响版本

进入编辑页面后,你会看到几个必填字段。我按从上到下的顺序逐个说。

第一个是 Description,也就是漏洞描述。这里不是写长篇大论,而是在开头先用一句话概括是什么类型的漏洞,影响哪个功能点,然后换行写几点关键信息:坏影响是什么、有没有补丁。建议直接把你准备的英文描述贴进来。举个例子:

A stored Cross-Site Scripting (XSS) vulnerability in the search function of ProductName allows an authenticated attacker with low privileges to inject arbitrary JavaScript code. The payload executes when an administrator views the search history page. Patched in version 1.2.3.

这个描述包含四要素:漏洞类型(存储型 XSS)、触发者权限(低权限用户)、触发场景(管理员查看搜索历史)、修复版本(1.2.3)。CNA 审核时最关心的就是这四件事,其余花哨的修辞没必要写。

第二个是 Severity,严重程度。这里先选一个粗粒度等级:Critical、High、Medium、Low。你选完之后,下面会出现一个 Expand 按钮,点开可以看到 CVSS 计算器,里面的选项会根据你的等级预填一部分,你再微调向量即可。比如你选了 High,计算器会给你一个 7.0 到 8.9 的区间,你按实际情况调整具体值。

第三个是 Affected versions,受影响的版本范围。这里一定要用语义化版本范围格式,否则会被 CNA 打回。语法和 npm 的版本范围语法一样,常用写法有这些:

  • >= 1.0.0, < 1.2.3:表示从 1.0.0 到 1.2.3 之前的版本都受影响
  • = 1.0.0:只影响某个特定版本
  • < 0.5.0:所有小于 0.5.0 的版本
  • *:所有版本

这里有个特别容易踩坑的地方:不要写“1.0 - 2.0”这种模糊区间,也不要写“latest”这种不明确的词。GitHub 需要的是机器可读的精确范围。如果你不确定哪些版本受影响,稳妥的做法是先写你验证过的最小受影响版本,比如>= 1.0.0,并用文字补充说明“实测受影响版本为从 1.0.0 开始的版本,未继续回溯更早版本”。

第四个是 Patched versions,已修复版本。如果已经发布了包含修复的版本,直接写版本号,比如1.2.3。如果还没有修复,这里留空,但要在描述里注明漏洞是否已被公开讨论,有没有缓解措施。

第五个是 CWE。CWE 是 MITRE 的另一个体系,用于描述弱点类型。最常见的那几个最好背下来:

  • CWE-79:跨站脚本(XSS)
  • CWE-89:SQL 注入
  • CWE-20:输入验证不恰当
  • CWE-78:操作系统命令注入
  • CWE-502:不可信数据的反序列化
  • CWE-787:越界写入
  • CWE-125:越界读取

GitHub 表单里提供了搜索框,你输入关键词就能搜。比如输入 XSS,第一个结果就是 CWE-79,选上就行。有些新手看到 CWE 列表一脸懵,其实没关系,只要你能说清楚漏洞是“注入”“越权”“缓冲区溢出”这类大方向,CWE 基本能对应上。

第六个是可选的 Credits。这里可以添加贡献者,也就是漏洞发现者。如果漏洞是你发现的,在这里把你自己的 GitHub 账号加上,角色选择 Finder。如果还有第三方报告人,也可以一并加上。这样发布后,漏洞页面上会显示发现者信息,这也是安全社区认可贡献的方式之一。

3.3 请求 CVE 编号并发布公告

表单填完后,页面底部会有两个按钮,对应两条不同的路线。

如果你暂时不想要 CVE 编号,只想记录漏洞信息,可以先点 Save draft,把公告保存下来,之后再编辑。如果你想直接申请 CVE 编号,就点 Request CVE ID。点了之后,GitHub 会以 CNA 身份对你的请求做审核,审查内容主要包括:漏洞描述是否清晰、CVSS 是否合理、版本范围是否有效、项目是否真的是开源项目。

审核时长我没有办法给一个准确数字,因为差异很大。我自己经历过最快的不到两小时,慢的等过三个工作日。大多数情况下,审核员会在请求页面的评论区留言,可能会要求补充信息,比如复现步骤或者修复 commit 链接。这一阶段你需要留意 GitHub 的通知邮件。

审核通过后,表单的 CVE ID 字段会自动填入一个编号,比如 CVE-2025-xxxxx。此时你如果点击 Publish advisory,公告就会公开,任何人都能看到,同时该记录会被同步到 cve.org 的公开列表里,你的漏洞正式获得全球唯一编号。

这里我必须强调一个很多人忽略的点:只有当你确认漏洞已经修复、或者你已经和项目维护者协商好公开时间时才点发布。如果你的仓库就是项目本身,但还没发布修复版本,那就先别急着点 Publish,等修复版发出去之后再回来发布公告,这叫协调披露(Coordinated Disclosure),是安全社区的基本礼仪。

注意:在提交 CVE 申请之前,请先搜索一下 cve.org 和 GitHub Advisory Database,确认这个漏洞还没有被分配过编号。重复申请不会让你获得两个编号,反而会留下一条低质量申请记录,影响后续申请的可信度。

4. 路径二:通过 cve.org 的 GitHub 仓库走 CNA 流程

4.1 这条路径适合谁

Security Advisory 这条路虽然稳,但有前提:你得有仓库权限。如果你是第三方研究者,在别人的开源项目里发现漏洞,而项目维护者又不响应你的私信,那你就需要另一条路——通过 cve.org 官方在 GitHub 上的仓库提交 CVE 请求。

cve.org 的官方 GitHub 组织下有几个核心仓库,其中最常用到的是 cve-request。这个仓库是 cve.org 对外接收 CVE 编号申请请求的入口之一。另一类仓库是 cvelistV5,这是所有已发布 CVE 记录的公开存储库,你可以在里面搜索、验证编号,它本身不是拿来提交申请的。

为什么说这条路适合第三方研究者?因为它的入口不依赖目标项目维护者的配合,只需要你自己有 GitHub 账号就能发起。提交之后,记录会进入 CVE 服务的流程,由相应的 CNA 处理或由 cve.org 调度分配。

4.2 正确发起一个 CVE 请求的完整写法

进入 cve-request 仓库后,点击 Issues 标签,先不要急着 New issue。先在搜索框里搜一下别人有没有提交过类似请求,用目标项目名加漏洞类型做关键词,避免重复。确认没有之后,再点 New issue。

创建 issue 时,有些 CNA 会用模板,有些没有。不管有没有模板,我都建议你使用下述标准结构:

Title: [CVE Request] <项目名> <漏洞类型> in <受影响组件/功能> Body: 项目名称: 项目 URL: 漏洞发现者 GitHub ID: 发现日期: 漏洞类型(CWE): 受影响版本范围: 修复版本(如适用): CVSS 评分及向量: 漏洞简介(英文,2-3 句): 复现步骤(简写): 参考链接(issue / commit / POC 地址):

这里我拿一个实际例子演示完整写法:

Title: [CVE Request] langflow Remote Code Execution in load_flow endpoint Body: Project name: langflow Project URL: https://github.com/langflow-ai/langflow Reporter: your_github_id Date found: 2025-03-10 CWE: CWE-78 (OS Command Injection) Affected version: >= 0.1.0, <= 1.0.0 Patched version: 1.0.1 CVSS: 9.8 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) Summary: The load_flow endpoint in the experiment feature allows an unauthenticated attacker to inject OS commands via the flow_id parameter. Reproduction: Send a crafted POST request to /api/load_flow with flow_id set to $(command). Reference: https://github.com/langflow-ai/langflow/pull/12345

信息完整度决定了 CNA 是直接受理还是先追着你问。我见过很多 issue 只写一句“I found a bug”,这种基本被礼貌地请回去补全信息,白白浪费一两周。

4.3 提交之后的沟通与状态跟踪

提交 issue 后,你不需要再做额外操作,但要把这个 issue 的状态盯住。cve.org 的相关人员或对应 CNA 的维护者会在 issue 下面回复,可能是要求补充材料,也可能是告知已受理、进入编号分配队列。

有一点必须做好心理准备:这条路比 Security Advisory 要慢,因为我观察下来,issue 渠道的积压量比较大,编号分配周期通常从几天到几周不等。如果你的漏洞是严重类型(RCE、SQL 注入等),可以在标题里如实标注,有时会加快排队优先级。

如果长时间没有回复,我建议你在第 7 天左右在同一个 issue 里礼貌地留言询问进展,例如:

Hi, just checking if there are any updates on this request. Happy to provide more details if needed.

这样既能提醒对方,又不会显得催促。切记不要在多个 issue 里重复提交同一个漏洞的请求,这样只会让流程更混乱,甚至被标记为垃圾请求。

5. 常见被拒原因、时间预期与处理办法

5.1 最容易被打回的 5 种提交

我整理了这几年自己踩坑和帮朋友看报告时最常遇到的打回原因,做成一张表,你可以对照自查。

打回现象根本原因正确处理方式
提示重复申请该漏洞已有 CVE 编号,或同一漏洞被多人同时提交先在 cve.org 和 GitHub Advisory Database 双渠道搜索,确认后再提交
要求补版本信息版本范围写得模糊,比如 1.0-2.0 或 latest用语义化范围描述,例如 >= 1.0.0, < 2.0.0
要求补漏洞类型只写了“有 bug”,没写是注入、XSS 还是越权明确 CWE 编号,并用一句话说明漏洞类别
要求证明仓库开源项目仓库是私有仓库或已删除确认仓库 Public 状态,或提供可访问快照链接
要求补修复信息没有提供补丁版本或修复 commit尽量提供修复版本号、PR 链接,哪怕只有未合并的修复分支

如果你的 issue 被关了但理由不明确,可以直接在 issue 里回复询问具体原因。CNA 一般会给出答复,把问题改掉之后重新提交是完全正常的流程,没有什么“一次不通过就会被拉黑”的说法。

5.2 从提交到公开的时间到底要多久

这是新人在群里问得最多的问题。我根据实际经验整理了一个范围,注意不同漏洞、不同 CNA、不同时期的积压情况都会影响实际时长。

  • 自有仓库走 Security Advisory 申请 CVE:最快几小时,一般 1 到 3 个工作日,极少超过一周。因为 GitHub CNA 审核的是结构化表单,信息齐全的情况下处理很快。
  • cve.org 的 cve-request issue 渠道:通常 1 到 4 周,高峰期可能更长。Issue 渠道经常需要人工来回沟通,要在时间上留足余量。
  • 厂商自有 CNA(比如某个大公司的安全团队):差异最大,从几天到几个月都有。厂商需要考虑修复计划、客户沟通、协调披露窗口,所以慢是常态。

我个人的建议是:不要在提交后的前三天频繁刷新页面,那没意义。把精力放在准备一份无懈可击的报告上,比盯进度有用得多。如果一个月还没有动静,再考虑通过公开渠道联系 CNA 的负责人询问。

5.3 高危漏洞的加急处理技巧

如果你的漏洞属于 RCE、SQL 注入、认证绕过这类高危类型,可以在标题里明确写出 Remote Code Execution、SQL Injection 等关键词,并在摘要第一行注明“This vulnerability can be exploited remotely without authentication”,这类描述会直接影响 CNA 的优先级判断。

另外有一个被很多人忽略的小技巧:如果你已经给项目维护者提了修复 PR,可以把 PR 链接直接附在 CVE 申请材料里。CNA 看到修复已经在推进,会更快地完成编号审核,因为这意味着漏洞不会再继续扩大影响范围。这也是为什么我建议研究者在提交 CVE 之前,先尝试和项目维护者合作——合作带来的信息完整性,是加急最有效的手段。

6. 最后分享几条个人实战心得

6.1 描述越“笨”越好过

很多技术人写漏洞描述时喜欢用各种炫技的词,什么“bypass”“escalate”“abuse”,看得人脑壳疼。CNA 审核的是全球各地提交的报告,他们最希望看到的是朴实无华的句子:什么组件、什么参数、什么操作、什么后果。

我的习惯是写完描述后自己把技术名词遮住,用外行的视角重读一遍,如果能看懂,审核员一定能看懂。描述里的关键信息按“发生什么、如何触发、影响是什么、修了吗”来排列,比任何修辞都有用。

6.2 善用 GitHub 通知,别错过审核追问

CVE 申请过程中,CNA 如果提出问题,回复期限通常不会太长。GitHub 的邮件通知有时候会被归类到垃圾箱,我就吃过这个亏,两天没看邮箱,导致一个加急请求被标记为“无响应疑似放弃”。

建议在提交之前,去 GitHub 的 Notification 设置里把 Security 相关通知改为邮件即时提醒。提交之后,每天至少看一次 GitHub 的通知铃铛和注册邮箱的垃圾箱,把官方域名加到联系人白名单里。这是成本最低但收益最大的一项准备工作。

6.3 拿着别人的漏洞去申请,是对自己信誉的透支

这条路走久了,你会遇到各种诱惑,比如有人拿一个不在自己项目里的漏洞问你“能不能帮我申请个 CVE 编号”,或者有人想让你把别人的贡献写成你自己的。我的立场很明确:不接。CVE 体系中,发现者(Finder)这一栏是公开的,一旦发生冒名申请或信息造假,不仅编号可能被撤销,你的 GitHub 账号在该体系里的信誉也会受到质疑。安全圈子很小,这种瑕疵很快会传开,得不偿失。

CVE 申请本质上是个流程活,只要把信息准备完整、时机把握好,它没那么神秘。我第一次走完整个流程之后最大的感受是:原来那些看起来很厉害的“安全大佬”,也不是因为他们认识什么内部人,只是比我先把这个表单填熟而已。你照着这篇文章走一遍,就拥有了同样的能力,剩下的只是时间问题。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询