@comate/zulu 1.4.0-beta.5 → 1.4.0-beta.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. package/comate-engine/assets/skills/auto-commit/SKILL.md +2 -0
  2. package/comate-engine/assets/skills/auto-commit-sandbox-comate/SKILL.md +2 -2
  3. package/comate-engine/assets/skills/code-security/SKILL.md +110 -41
  4. package/comate-engine/assets/skills/code-security/references/credential_hosting.md +190 -28
  5. package/comate-engine/assets/skills/code-security/references/vul_analysis-go_sql_injection.md +149 -0
  6. package/comate-engine/assets/skills/code-security/references/vul_analysis-java_sql_injection.md +185 -0
  7. package/comate-engine/assets/skills/code-security/references/vul_analysis-php_sql_injection.md +147 -0
  8. package/comate-engine/assets/skills/code-security/references/vul_analysis-python_sql_injection.md +143 -0
  9. package/comate-engine/assets/skills/code-security/references/vul_repair-go_sql_injection.md +2 -2
  10. package/comate-engine/assets/skills/code-security/references/vul_repair-sca.md +225 -0
  11. package/comate-engine/assets/skills/code-security/scripts/credential_hosting.py +12 -10
  12. package/comate-engine/assets/skills/code-security/scripts/credential_open_page.py +125 -0
  13. package/comate-engine/assets/skills/code-security/scripts/credential_poll.py +12 -9
  14. package/comate-engine/assets/skills/code-security/scripts/credential_url.py +81 -0
  15. package/comate-engine/assets/skills/code-security/scripts/ducc/get_claude_session_id.sh +33 -0
  16. package/comate-engine/assets/skills/code-security/scripts/ducc/open_browser.py +191 -0
  17. package/comate-engine/assets/skills/code-security/scripts/parse_scan_result.py +99 -16
  18. package/comate-engine/assets/skills/code-security/scripts/repair_vulnerability.py +66 -13
  19. package/comate-engine/assets/skills/code-security/scripts/scan_vulnerability.py +44 -12
  20. package/comate-engine/assets/skills/create-automation/SKILL.md +3 -0
  21. package/comate-engine/assets/skills/create-subagent/SKILL.md +16 -4
  22. package/comate-engine/server.js +137 -77
  23. package/dist/bundle/index.js +3 -3
  24. package/package.json +1 -1
@@ -5,6 +5,8 @@ user-invocable: false
5
5
  metadata:
6
6
  enableWhen:
7
7
  - isInternal
8
+ disableWhen:
9
+ - isZuluCli
8
10
  ---
9
11
 
10
12
  # 智能提交助手
@@ -3,7 +3,7 @@ name: auto-commit-sandbox
3
3
  description: 当用户完成代码修改、需要提交代码时,必须使用此 skill,而非直接执行 git commit。自动获取 git diff、匹配 iCafe 活跃卡片、生成 commit message,并自动完成绑定卡片和代码提交。
4
4
  metadata:
5
5
  enableWhen:
6
- - isInternal
6
+ - isInternalZuluCli
7
7
  ---
8
8
 
9
9
  # 智能提交助手(自动版)
@@ -261,4 +261,4 @@ cd /Users/ddz/project && git push origin HEAD:refs/for/feature/login
261
261
  | 脚本 | `scripts/git_utils.py` | Git 工具函数 |
262
262
  | 参考 | `references/data_structures.md` | 数据结构定义 |
263
263
  | 参考 | `references/query_reference.md` | IQL 语法参考 |
264
- | 参考 | `references/issue_type_mapping.json` | 卡片类型映射 |
264
+ | 参考 | `references/issue_type_mapping.json` | 卡片类型映射 |
@@ -1,21 +1,24 @@
1
1
  ---
2
2
  name: code-security
3
- description: 代码安全漏洞扫描与修复工具。当用户涉及以下任何场景时,务必使用本 skill:(1) 扫描项目代码中的安全漏洞(SQL注入、XSS、XXE、路径遍历、硬编码凭证等);(2) 自动修复扫描发现的漏洞;(3) 查看漏洞扫描报告;(4) 对 Java、Go、Python、JavaScript、C/C++ 等语言的项目进行安全检测;(5) 硬编码凭证的修复和托管。即使用户只是提到"代码安全"、"漏洞"、"扫描"、"审计"、"SAST"、"硬编码"、"凭证"等关键词,也应触发本 skill。用户说"检查代码有没有安全问题"或"帮我扫一下代码"时也应触发,不要尝试自行分析代码安全性,而应使用本 skill 的专业扫描服务。
4
- disable-model-invocation: true
3
+ description: 代码安全漏洞扫描与修复工具。当用户涉及以下任何场景时,务必使用本 skill:(1) 扫描项目代码中的安全漏洞(SQL注入、XSS、XXE、路径遍历、硬编码凭证等);(2) 自动修复扫描发现的漏洞;(3) 查看漏洞扫描报告;(4) 对 Java、Go、Python、JavaScript、C/C++ 等语言的项目进行安全检测;(5) 硬编码凭证的修复和托管;(6)硬编码风险治理。即使用户只是提到"代码安全"、"漏洞"、"扫描"、"审计"、"SAST"、"硬编码"、"凭证"等关键词,也应触发本 skill。用户说"检查代码有没有安全问题"或"帮我扫一下代码"时也应触发,不要尝试自行分析代码安全性,而应使用本 skill 的专业扫描服务。
5
4
  metadata:
6
5
  enableWhen:
7
6
  - isInternal
8
- version: V1.3.0
7
+ version: V1.4.0
9
8
  ---
10
9
 
11
10
  # Code Security - 代码安全漏洞扫描与修复
12
11
 
13
12
  ## 概述
14
13
 
15
- 本 skill 将用户项目代码上传至安全扫描服务端进行扫描,返回 SARIF 格式漏洞报告,并支持自动修复。当前支持普通漏洞修复,硬编码凭证修复与托管功能暂未开放。
14
+ 本 skill 将用户项目代码上传至安全扫描服务端进行扫描,返回 SARIF 格式漏洞报告,并支持自动修复。**当前仅支持普通漏洞修复,硬编码凭证修复与托管功能暂未开放**:扫描结果中如有硬编码漏洞,仅在报告中展示供用户知悉,不进入任何修复或凭证托管流程,也不向用户提供"修复硬编码漏洞"的选项。
16
15
 
17
16
  所有中间结果文件(`scan_result.json`、`parsed_result.json`、`repair_result.json`)默认保存在 skill 安装目录下的 `.tmp/<项目名>_<哈希>/` 目录中,按项目隔离、不会污染用户项目。脚本标准输出会打印文件绝对路径,使用该路径读取即可。每次执行扫描脚本时,会自动清理超过 24 小时的过期临时数据。
18
17
 
18
+ ## 文件改动强制约束
19
+
20
+ **【强制执行】** 当需要改动用户项目中的文件时(包括但不限于漏洞修复、代码替换、凭证替换等所有写文件场景),**必须使用 `edit_file` 工具进行修改**。严禁自行编写脚本(如 sed、awk、python 脚本、shell 重定向等)对代码文件进行批量或单点操作。即使脚本返回了 `diff_content`,也必须由 Agent 逐条调用 `edit_file` 工具完成替换,不得通过自写脚本绕过此约束。
21
+
19
22
  ## 异常处理
20
23
 
21
24
  当遇到影响流程的致命错误时(如扫描服务不可用、修复接口异常等),向用户提示:
@@ -26,6 +29,37 @@ metadata:
26
29
 
27
30
  ## 工作流
28
31
 
32
+ ### 准备工作:环境检测与变量初始化
33
+
34
+ **【强制执行】** 在执行任何工作流之前,必须先完成环境检测,初始化以下三个统一变量,后续所有脚本命令均使用这些变量。**环境检测命令必须直接执行,无需向用户确认或等待用户点击同意后再执行。**
35
+
36
+ | 变量 | 说明 |
37
+ |------|------|
38
+ | `_USERNAME` | 当前登录用户名 |
39
+ | `_CHAT_ID` | 当前会话 ID |
40
+ | `_IDE` | IDE 类型 |
41
+
42
+ 检测规则:
43
+
44
+ ```bash
45
+ if [ -n "${COMATE_SESSION_ID}" ]; then
46
+ # Comate 环境
47
+ _USERNAME="${COMATE_USERNAME}"
48
+ _CHAT_ID="${COMATE_SESSION_ID}"
49
+ _IDE="${COMATE_IDE_NAME:-comate}"
50
+ elif [ -n "${BAIDU_CC_USERNAME}" ]; then
51
+ # DUCC 环境
52
+ _USERNAME="${BAIDU_CC_USERNAME}"
53
+ _CHAT_ID=$(bash scripts/ducc/get_claude_session_id.sh)
54
+ _IDE="ducc"
55
+ else
56
+ echo "错误:无法识别当前环境,COMATE_SESSION_ID 和 BAIDU_CC_USERNAME 均未设置" >&2
57
+ exit 1
58
+ fi
59
+ ```
60
+
61
+ 初始化完成后,后续所有命令中的 `${_USERNAME}`、`${_CHAT_ID}`、`${_IDE}` 均替换为上述值。
62
+
29
63
  ### 漏洞扫描
30
64
 
31
65
  扫描分为两个阶段执行,确保用户能尽早看到初步结果。
@@ -35,7 +69,7 @@ metadata:
35
69
  使用 `--no-wait-ai` 跳过 AI 分析等待,扫描完成后立即返回:
36
70
 
37
71
  ```bash
38
- python3 scripts/scan_vulnerability.py --root-path <项目目录> --username ${COMATE_USERNAME} --chat-id ${COMATE_SESSION_ID} --no-wait-ai
72
+ python3 scripts/scan_vulnerability.py --root-path <项目目录> --username ${_USERNAME} --chat-id ${_CHAT_ID} --no-wait-ai
39
73
  ```
40
74
 
41
75
  `<项目目录>` 是指用户项目的根目录(即待扫描代码所在目录),而非 skill 安装目录。`--chat-id` 用于关联扫描任务与当前对话。
@@ -52,7 +86,7 @@ python3 scripts/scan_vulnerability.py --root-path <项目目录> --username ${CO
52
86
  1. **必须立即执行数据上报**(参数说明见「数据上报」章节):
53
87
 
54
88
  ```bash
55
- python3 scripts/report_chat.py --username ${COMATE_USERNAME} --chat-id ${COMATE_SESSION_ID} --scan-result <scan_result.json路径> --root-path <项目目录> --ide ${COMATE_IDE_NAME} --query <用户输入>
89
+ python3 scripts/report_chat.py --username ${_USERNAME} --chat-id ${_CHAT_ID} --scan-result <scan_result.json路径> --root-path <项目目录> --ide ${_IDE} --query <用户输入>
56
90
  ```
57
91
 
58
92
  扫描失败时不执行数据上报,直接向用户展示错误信息。
@@ -65,21 +99,52 @@ python3 scripts/report_chat.py --username ${COMATE_USERNAME} --chat-id ${COMATE_
65
99
  当有漏洞仍在 AI 分析中时,执行此阶段等待分析完成:
66
100
 
67
101
  ```bash
68
- python3 scripts/scan_vulnerability.py --root-path <项目目录> --username ${COMATE_USERNAME} --chat-id ${COMATE_SESSION_ID} --wait-ai-only --scan-result <scan_result.json路径>
102
+ python3 scripts/scan_vulnerability.py --root-path <项目目录> --username ${_USERNAME} --chat-id ${_CHAT_ID} --wait-ai-only --scan-result <scan_result.json路径>
69
103
  ```
70
104
 
71
- 脚本会轮询等待所有漏洞的 AI 分析完成(超时 20 分钟),然后**原地更新** `scan_result.json`。如果超时仍有漏洞未完成分析(`aiAnalysisStatus` 仍为 1),这些漏洞会被忽略,不进入修复流程。
105
+ 脚本会轮询等待所有漏洞的 AI 分析完成(超时 20 分钟),然后**原地更新** `scan_result.json`。如果超时仍有漏洞未完成分析(`aiAnalysisStatus` 仍为 1),会进入「本地兜底分析」阶段,由 Agent 根据语言对应的本地分析文档判定误报,避免直接被忽略导致漏修。
72
106
 
73
107
  AI 分析完成或超时后:
74
- 1. 重新执行解析脚本,**将标准输出原样展示给用户**(此时误报漏洞已被过滤)
75
- 2. 根据最新的 `parsed_result.json` 进入修复流程
108
+ 1. 重新执行解析脚本,**将标准输出原样展示给用户**(此时已完成分析的误报漏洞已被过滤)
109
+ 2. 检查最新的 `parsed_result.json`:如果 `analyzing_count > 0`,进入「本地兜底分析」阶段;否则进入「漏洞解析与展示」章节的用户选择流程
76
110
 
77
111
  **AI 误报分析状态说明**:
78
112
  - `aiAnalysisStatus=0`:无需分析
79
- - `aiAnalysisStatus=1`:分析中(不进入修复流程,超时后直接忽略)
113
+ - `aiAnalysisStatus=1`:分析中(超时后进入本地兜底分析)
80
114
  - `aiAnalysisStatus=2`:真实漏洞(需要修复)
81
115
  - `aiAnalysisStatus=3`:误报(自动跳过,不进入修复流程)
82
116
 
117
+ #### 本地兜底分析(AI 分析超时漏洞)
118
+
119
+ 当 `parsed_result.json` 的 `analyzing_count > 0`(即有漏洞 AI 分析超时未完成)时,由 Agent 参考本地分析文档对这些漏洞逐条判定误报,**仅对普通漏洞执行**。
120
+
121
+ **适用范围(严格遵守)**:
122
+ - ✅ 仅对 `analyzing_vuls` 中的**普通漏洞**(即非 SCA、非硬编码)进行本地兜底分析
123
+ - ❌ **SCA 漏洞**(漏洞条目 `importPath` 字段非空):跳过分析,直接按真实漏洞处理(进入 SCA 本地修复流程)
124
+ - ❌ **硬编码漏洞**(`ruleID` 含 `sensitive`):跳过分析,由于硬编码修复流程当前未开放,直接在报告中展示,不做任何修复
125
+
126
+ **兜底分析步骤**:
127
+
128
+ 1. 从 `parsed_result.json` 的 `analyzing_vuls` 中筛选出待分析的普通漏洞(按上述适用范围排除 SCA / 硬编码)
129
+ 2. 对每条漏洞,根据其 `ruleID` 在下表中查找对应的本地分析文档:
130
+
131
+ **ruleID 与分析参考文档映射表**:
132
+
133
+ | ruleID 关键词 | 分析文档 |
134
+ |--------------|---------|
135
+ | `java_sqli`、`java_sql_injection` | [references/vul_analysis-java_sql_injection.md](references/vul_analysis-java_sql_injection.md) |
136
+ | `go_sqli`、`go_sql_injection` | [references/vul_analysis-go_sql_injection.md](references/vul_analysis-go_sql_injection.md) |
137
+ | `php_sqli`、`php_sql_injection` | [references/vul_analysis-php_sql_injection.md](references/vul_analysis-php_sql_injection.md) |
138
+ | `python_sqli`、`python_sql_injection` | [references/vul_analysis-python_sql_injection.md](references/vul_analysis-python_sql_injection.md) |
139
+
140
+ 匹配规则:ruleID 中包含表中任一关键词即命中(不区分大小写)。如果未匹配到任何分析文档,按真实漏洞处理(保守策略)进入修复流程。
141
+
142
+ 3. 读取分析文档后严格按其流程对每条漏洞进行复核,输出 `analyze_report.json`(与 `parsed_result.json` 同目录),格式见各分析文档的「结果输出」章节。
143
+ 4. 根据 `analyze_report.json` 处理:
144
+ - `result=false_positive` 的漏洞:**跳过**,不进入修复流程,并在最终展示给用户的报告中标注"经本地兜底分析判定为误报"
145
+ - `result=true_positive` 的漏洞:与 `aiAnalysisStatus=2` 的真实漏洞合并,进入修复流程
146
+ 5. 重新计算修复列表后,统一进入「漏洞解析与展示」章节的用户选择流程(不要直接跳到修复)。展示时需明确告知用户:"X 个漏洞 AI 分析超时,已通过本地兜底分析复核,其中 Y 个判定为误报、Z 个判定为真实漏洞"。
147
+
83
148
  ### 漏洞解析与展示
84
149
 
85
150
  扫描完成后,执行解析脚本对结果进行分类和格式化展示:
@@ -90,48 +155,54 @@ python3 scripts/parse_scan_result.py --scan-result <scan_result.json路径> --pr
90
155
 
91
156
  脚本功能:
92
157
  1. 解析 SARIF 格式扫描结果,自动按 ruleID 是否包含 `sensitive` 分类为普通漏洞和硬编码漏洞
93
- 2. **排除过滤**:`aiAnalysisStatus=3`(误报)和 `aiAnalysisStatus=1`(分析中/超时)的漏洞会被单独归类,不进入修复流程
158
+ 2. **状态归类**:`aiAnalysisStatus=3`(误报)和 `aiAnalysisStatus=1`(分析中/超时)的漏洞会被单独归类。误报永远不进入修复流程;分析中漏洞需先经「本地兜底分析」复核,被判定为真实漏洞的会被合并回修复列表
94
159
  3. 标准输出打印 Markdown 格式漏洞报告,包含漏洞名称、描述、位置链接、等级、数据流、修复建议。如果有漏洞仍在 AI 分析中,报告会自动提示
95
160
  4. 在输出目录生成 `parsed_result.json`(路径打印到 stderr),包含结构化漏洞数据供后续修复使用。其中 `analyzing_count` 字段表示仍在 AI 分析中的漏洞数量
96
161
 
97
162
  **展示要求(严格遵守)**:脚本标准输出的内容是已经格式化好的 Markdown 漏洞报告,**必须将标准输出内容原样展示给用户,禁止总结、改写、精简或重新组织**。不要用自己的话概述漏洞信息,直接复制粘贴脚本的标准输出即可。
98
163
 
99
- 然后根据 `parsed_result.json` 中的 `common_count` 进入修复流程:
164
+ **统计数字的权威来源(严格遵守)**:任何涉及“漏洞总数 / 真实漏洞 / 误报数量 / 分析中数量 / 修复率 / 修复前后对比”的表述,**必须**读取 `parsed_result.json` `total`、`common_count`、`sensitive_count`、`false_positive_count`、`analyzing_count` 字段,或使用脚本 stdout/stderr 首行打印的 `STATS: total=… common=… sensitive=… false_positive=… analyzing=…` 作为事实来源。禁止通过数 Markdown 列表条目、或凭印象推断计数。当长报告可能被截断时,`STATS:` 行和 `parsed_result.json` 是唯一可信的数字来源;特别注意“分析中(analyzing)”的漏洞既不是真实漏洞也不是误报,不得在统计中被合并到任意一侧。
165
+
166
+ **【强制执行】** 展示报告后,必须使用 Questions 组件让用户选择后续操作,不得自动进入修复流程。根据 `parsed_result.json` 中的 `common_count` 提供选项。`common_count` > 0 表示存在普通漏洞。
167
+
168
+ > 注:硬编码凭证修复与托管功能暂未开放。即使 `sensitive_count > 0`,也**不**向用户提供"修复硬编码漏洞"选项;硬编码漏洞仅在报告中展示供用户知悉,不进入任何修复流程。
100
169
 
101
- - 如果存在普通漏洞(`common_count > 0`),直接进入普通漏洞修复流程
102
- - 如果没有普通漏洞(包括所有漏洞都是误报的情况),仅展示扫描报告,不进行修复
170
+ 选项必须严格按以下格式书写:
103
171
 
104
- <!-- TODO: 后续版本恢复硬编码漏洞修复支持
105
- - 如果同时存在两种漏洞,给出3个选项让用户选择(使用Questions组件):
172
+ - 如果存在普通漏洞(`common_count > 0`),提供以下选项:
106
173
  1. 修复普通漏洞 - 自动修复 SQL 注入、XXE 等常规漏洞
107
- 2. 修复硬编码漏洞 - 进入凭证托管流程,将硬编码凭证替换为环境变量
108
- 3. 仅查看漏洞信息,暂不修复
109
- - 如果只有普通漏洞,直接进入普通修复流程
110
- - 如果只有硬编码漏洞,直接进入硬编码修复流程
111
- -->
174
+ 2. 仅查看漏洞信息,暂不修复
175
+ - 如果没有普通漏洞(`common_count == 0`),无论是否存在硬编码漏洞,都直接告知用户当前无可自动修复的漏洞,流程结束
176
+
177
+ 用户必须选择其中一项后才能继续。选择「暂不修复」则流程结束。
112
178
 
113
179
  ### 普通漏洞修复
114
180
 
181
+ **SCA 类漏洞特殊处理**:SCA 漏洞的修复方式是升级依赖版本,与代码改写无关,后端修复接口对其无能为力。判定规则:**漏洞条目 `importPath` 字段非空**。
182
+
183
+ 处理策略统一为:**先由 Agent 在本地参考 [references/vul_repair-sca.md](references/vul_repair-sca.md) 用 `edit_file` 工具修复全部 SCA 漏洞(修改 `pom.xml` / `go.mod` / `requirements.txt` / `package.json` 等依赖声明文件),再调用 `repair_vulnerability.py` 处理剩余的非 SCA 普通漏洞。** 脚本会自动按 `importPath` 过滤掉 SCA 漏洞,不会重复发后端请求;如果 `common_vuls` 全部为 SCA,脚本会直接返回 `status=-3`、`fallback=true`、`sca_only=true`,此时无需再调用脚本,本地修复完成后直接进入复测。
184
+
115
185
  直接传入解析结果文件执行修复:
116
186
 
117
187
  ```bash
118
- python3 scripts/repair_vulnerability.py --root-path <项目目录> --username ${COMATE_USERNAME} --chat-id ${COMATE_SESSION_ID} --parsed-result <parsed_result.json路径>
188
+ python3 scripts/repair_vulnerability.py --root-path <项目目录> --username ${_USERNAME} --chat-id ${_CHAT_ID} --parsed-result <parsed_result.json路径>
119
189
  ```
120
190
 
121
191
  脚本自动从 `parsed_result.json` 提取普通漏洞并按文件聚合,然后调用修复接口。
122
192
 
123
193
  修复逻辑:
124
- 1. 一定要先调用工具脚本进行修复,不要擅自修改其他部分的代码
125
- 2. 结果保存到 skill 临时目录下的 `repair_result.json`,标准输出打印结果文件绝对路径
126
- 3. 执行完成后,使用 Read 工具读取结果文件获取修复结果
127
- 4. **兜底修复**:如果脚本未能返回修复结果(如接口报错、返回空结果)或执行超时(超过 20 分钟),则跳过脚本修复,改为 Agent 参考修复指导手册自行修复。兜底流程:
128
- 1. `parsed_result.json` `common_vuls` 中获取每个漏洞的 `ruleID`
194
+ 1. **优先本地修复 SCA 漏洞**:在调用脚本前,先扫描 `parsed_result.json` 的 `common_vuls`,对所有 `importPath` 字段非空的漏洞,读取 [references/vul_repair-sca.md](references/vul_repair-sca.md) 并使用 `edit_file` 工具完成本地修复。SCA 修复完成后再调用脚本处理剩余漏洞;如果 `common_vuls` 全部是 SCA 漏洞,则跳过脚本调用,直接进入第 8 步复测
195
+ 2. 一定要先调用工具脚本进行修复,不要擅自修改其他部分的代码
196
+ 3. 结果保存到 skill 临时目录下的 `repair_result.json`,标准输出打印结果文件绝对路径
197
+ 4. 执行完成后,读取结果文件获取修复结果
198
+ 5. **兜底修复**:如果脚本未能返回修复结果(如接口报错、返回空结果)、执行超时(超过 5 分钟),或返回 `fallback=true`(如 `sca_only=true` 表示全部为 SCA 漏洞),则跳过脚本修复,改为 Agent 参考修复指导手册自行修复。兜底流程:
199
+ 1. 从 `parsed_result.json` 的 `common_vuls` 中获取每个漏洞的 `ruleID`(SCA 漏洞按上述步骤 1 已处理,此处仅处理非 SCA 漏洞)
129
200
  2. 根据下方映射表查找对应的修复参考文档,读取该文档获取修复指导
130
201
  3. 阅读漏洞所在源文件,结合参考文档中的修复模式和最佳实践,自行完成代码修复
131
202
  4. 如果 ruleID 没有匹配的参考文档,则基于漏洞的 `description`、`suggestion` 和 `codeFlows` 信息,运用自身安全知识进行修复
132
- 5. 修复完成后,继续执行后续的复测扫描流程(步骤 6
203
+ 5. 修复完成后,继续执行后续的复测扫描流程(步骤 8
133
204
 
134
- **ruleID 与修复参考文档映射表**:
205
+ **ruleID 与修复参考文档映射表**(仅适用于非 SCA 漏洞;SCA 漏洞按 `importPath` 判定,统一使用 `references/vul_repair-sca.md`):
135
206
 
136
207
  | ruleID 关键词 | 参考文档 |
137
208
  |--------------|---------|
@@ -141,9 +212,9 @@ python3 scripts/repair_vulnerability.py --root-path <项目目录> --username ${
141
212
  | `python_sqli`、`python_sql_injection` | [references/vul_repair-python_sql_injection.md](references/vul_repair-python_sql_injection.md) |
142
213
 
143
214
  匹配规则:ruleID 中包含表中任一关键词即命中(不区分大小写)。后续新增漏洞类型时,在此表中追加对应行并创建 `references/vul_repair-<类型>.md` 文件即可。
144
- 5. 每获取一个文件修复结果,就读取 `diff_content`(JSON 数组,每个元素为 `{from_content, to_content}`),遍历数组逐个执行 `file_content.replace(from_content, to_content)` 替换文件内容,并默认采纳
145
- 6. 如果是调用工具脚本进行修复的,修改完文件后要检查修改部分是否存在编码错误,比如缺失导入的包或组件、语法错误、逻辑错误等,如果存在则自动修复,直到没有编码错误为止
146
- 7. 所有文件修复完成后,自动执行一次复测扫描(流程与「漏洞扫描」章节一致),对比修复前后的漏洞数量,向用户说明修复效果。**复测扫描完成后同样必须执行数据上报**(命令和参数同「漏洞扫描」章节中的上报步骤)。展示格式:
215
+ 6. 每获取一个文件修复结果,都必须使用 `edit_file` 工具,依据 `diff_content`(JSON 数组,每个元素为 `{from_content, to_content}`)逐条完成替换。严禁通过自写脚本/sed/awk 等方式批量替换文件内容
216
+ 7. 如果是调用工具脚本进行修复的,修改完文件后要检查修改部分是否存在编码错误,比如缺失导入的包或组件、语法错误、逻辑错误等,如果存在则自动修复,直到没有编码错误为止
217
+ 8. 所有文件修复完成后,自动执行一次复测扫描(流程与「漏洞扫描」章节一致),对比修复前后的漏洞数量,向用户说明修复效果。**复测扫描完成后同样必须执行数据上报**(命令和参数同「漏洞扫描」章节中的上报步骤)。展示格式:
147
218
 
148
219
  ```
149
220
  修复完成,正在执行复测扫描验证修复效果...
@@ -153,14 +224,12 @@ python3 scripts/repair_vulnerability.py --root-path <项目目录> --username ${
153
224
 
154
225
  如果复测仍存在未修复的漏洞,展示剩余漏洞列表(格式同漏洞报告),并提示用户可以选择继续修复或忽略。
155
226
 
156
- 8. 复测完成后,临时文件无需手动删除。每次执行扫描脚本时会自动清理超过 24 小时的过期临时目录(即 `.tmp/<项目名>_<哈希>/`)。如果同时存在硬编码漏洞且用户后续还需修复,24 小时内的临时数据会保留,等硬编码流程结束后自然过期清理。
157
- 9. 进入单元测试阶段(流程见「单元测试」章节)。
227
+ 9. 复测完成后,临时文件无需手动删除。每次执行扫描脚本时会自动清理超过 24 小时的过期临时目录(即 `.tmp/<项目名>_<哈希>/`)。
228
+ 10. 进入单元测试阶段(流程见「单元测试」章节)。
158
229
 
159
- <!-- TODO: 后续版本恢复硬编码漏洞修复支持
160
230
  ### 硬编码漏洞修复与凭证托管
161
231
 
162
- 完整流程见 [references/credential_hosting.md](references/credential_hosting.md)。
163
- -->
232
+ **当前未开放**。扫描结果中的硬编码漏洞(`ruleID` 含 `sensitive` 的条目)仅在报告中展示供用户知悉,不进入任何修复或凭证托管流程,也不向用户提供相关选项。`references/credential_hosting.md`、`references/vul_repair_sensitive.md` 以及 `scripts/credential_*.py` 当前暂不被工作流引用,待后续版本重新开放。
164
233
 
165
234
  ### 单元测试
166
235
 
@@ -189,15 +258,15 @@ python3 scripts/repair_vulnerability.py --root-path <项目目录> --username ${
189
258
  每次**扫描成功**后(包括首次扫描和复测扫描),**必须执行数据上报**。扫描失败时不执行数据上报。上报失败不影响主流程,仅在 stderr 输出警告。
190
259
 
191
260
  ```bash
192
- python3 scripts/report_chat.py --username ${COMATE_USERNAME} --chat-id ${COMATE_SESSION_ID} --scan-result <扫描结果文件路径> --root-path <项目目录> [--git-url <仓库URL>] [--git-branch <分支>] --ide ${COMATE_IDE_NAME} --query <用户输入>
261
+ python3 scripts/report_chat.py --username ${_USERNAME} --chat-id ${_CHAT_ID} --scan-result <扫描结果文件路径> --root-path <项目目录> [--git-url <仓库URL>] [--git-branch <分支>] --ide ${_IDE} --query <用户输入>
193
262
  ```
194
263
 
195
264
  参数说明:
196
- - `--chat-id`:使用 `${COMATE_SESSION_ID}` 作为对话唯一标识
265
+ - `--chat-id`:使用 `${_CHAT_ID}` 作为对话唯一标识
197
266
  - `--scan-result`:扫描结果 JSON 文件路径(即 `scan_result.json`),脚本自动从中提取漏洞信息
198
267
  - `--root-path`:项目根目录,用于计算漏洞文件的哈希值
199
268
  - `--git-url` / `--git-branch`:从项目 git 信息获取
200
- - `--ide`:使用 `${COMATE_IDE_NAME}`
269
+ - `--ide`:使用 `${_IDE}`
201
270
  - `--query`:用户发起扫描时的输入文本
202
271
 
203
272
  上报时机:
@@ -1,30 +1,77 @@
1
1
  # 硬编码漏洞修复与凭证托管
2
2
 
3
- 硬编码修复有四个步骤:凭证配置 → 代码修复 → 用户确认 → 凭证托管。
3
+ **【强制执行总则】** 以下步骤必须严格按顺序执行,不得跳过任何步骤,不得调换顺序。每个步骤完成后才能进入下一步。
4
4
 
5
- ## 步骤一:打开凭证配置网页
5
+ ## 流程概览
6
6
 
7
- 输出可点击的链接让用户打开凭证托管助手网页,网页 URL 格式及输出示例如下:
8
7
  ```
9
- 请点击以下链接打开凭证托管助手,配置凭证信息:
8
+ 步骤一:打开硬编码风险治理网页
9
+
10
+ 步骤二:等待凭证配置完成(立即执行轮询脚本)
11
+
12
+ 步骤三:修复硬编码代码(本地修复,按 vul_repair_sensitive.md 规则)
13
+
14
+ 步骤四:托管凭证(用户选择托管或跳过)
15
+ ├→ 托管凭证 → 执行托管脚本 → 步骤五
16
+ └→ 跳过托管 → 步骤五
17
+
18
+ 步骤五:提交代码并合入
19
+ ├→ 选择1:代码提交且合入 → 步骤六(清理历史 commit)→ [申请结单?是] → 清理临时文件 → 结束
20
+ │ └→ [申请结单?否] → 复测扫描 → [申请结单?是] → 清理临时文件 → 结束
21
+ │ └→ [申请结单?否] → 清理临时文件 → 结束
22
+ ├→ 选择2:未提交合入,复测扫描 → 复测扫描 → [申请结单?是] → 清理临时文件 → 结束
23
+ │ └→ [申请结单?否] → 清理临时文件 → 结束
24
+ ├→ 选择3:未提交合入,单元测试 → 单元测试 → 复测扫描 → [申请结单?是] → 清理临时文件 → 结束
25
+ │ └→ [申请结单?否] → 清理临时文件 → 结束
26
+ └→ 选择4:未提交合入,流程结束 → 清理临时文件 → 结束
27
+ ```
28
+
29
+ ---
30
+
31
+ ## 步骤一:打开硬编码风险治理网页
32
+
33
+ **【强制执行】** 必须根据当前环境执行对应脚本,不得跳过此步骤。
34
+
35
+ ### Comate 环境
36
+
37
+ 脚本会自动构建凭证配置网页 URL,并在 IDE 内嵌浏览器中自动打开:
38
+
39
+ ```bash
40
+ python3 scripts/credential_open_page.py \
41
+ --chat-id "${_CHAT_ID}" \
42
+ --username "${_USERNAME}" \
43
+ --ide-name "${_IDE}" \
44
+ --project-dir "<项目目录绝对路径>"
45
+ ```
10
46
 
11
- [打开凭证托管助手](//command:simpleBrowser.api.open?https%3A%2F%2Fcomate-sec-test.baidu-int.com%2Fapp%2Fcredential%3FchatID%3D${COMATE_SESSION_ID}%26comateUID%3D<COMATE_UID>%26version%3D2.9.1%26repo%3D<REPO>%26ideType%3D${COMATE_IDE_NAME})
47
+ 脚本说明:
48
+ - `--project-dir`:当前扫描的项目目录,用于自动从 git remote 获取 `repo` 标识;若无 git 信息则使用目录名
49
+ - 脚本通过 comate-kernel socket 在 IDE 内嵌浏览器中自动打开网页
50
+ - 若 kernel socket 不可用,自动降级为 `--open-url` 触发 `simpleBrowser.api.open`
12
51
 
13
- 配置完成后请在网页中点击「生成代码」按钮,我会自动检测到配置完成并继续执行修复。
52
+ ### DUCC 环境
53
+
54
+ `credential_open_page.py` 负责输出可点击链接,`scripts/ducc/open_browser.py` 负责在内嵌浏览器中打开,两者接收相同参数,共用公共模块 `credential_url.py` 构建 URL:
55
+
56
+ ```bash
57
+ # 在内嵌浏览器中打开
58
+ python3 scripts/ducc/open_browser.py \
59
+ --chat-id "${_CHAT_ID}" \
60
+ --username "${_USERNAME}" \
61
+ --ide-name "${_IDE}" \
62
+ --project-dir "<项目目录绝对路径>"
14
63
  ```
15
64
 
16
- 其中:
17
- - `COMATE_UID` 为 `${COMATE_USERNAME}` 的 MD5 字符串的前 12 位,使用 `python3 -c "import hashlib; print(hashlib.md5('${COMATE_USERNAME}'.encode()).hexdigest()[:12])"` 计算
18
- - `REPO` 是代码库标识,可以从项目目录的 git remote 获取(如 `baidu/scan/cnap-test`),如果没有 git 信息则使用项目目录名
65
+ ---
19
66
 
20
- 要使用实际构造的字符串来替换上述的 url 参数,url 中的%26不要解码,避免 & 符号影响 markdown 链接。
67
+ **【强制执行】** 无论哪种环境,无论网页是否成功自动打开,都必须将脚本的 stdout 输出(含可点击链接)完整展示在聊天框中,不得省略。
21
68
 
22
69
  ## 步骤二:等待凭证配置完成
23
70
 
24
- 打开网页后,立即执行轮询脚本等待用户配置,使用 `--output` 将结果保存到临时目录:
71
+ **【强制执行】** 必须等到聊天框中已成功输出可点击链接后,才能开始执行以下轮询脚本,不得提前执行、不得跳过、不得等待用户回复后再执行。此步骤是后续修复流程的前置依赖,未执行将导致整个硬编码修复流程中断。
25
72
 
26
73
  ```bash
27
- python3 scripts/credential_poll.py --chat-id ${COMATE_SESSION_ID} --username ${COMATE_USERNAME} --output <临时目录>/poll_result.json
74
+ python3 scripts/credential_poll.py --chat-id ${_CHAT_ID} --username ${_USERNAME} --output <临时目录>/poll_result.json
28
75
  ```
29
76
 
30
77
  `<临时目录>` 使用与 `scan_result.json` 同一目录(即 `.tmp/<项目名>_<哈希>/`)。
@@ -35,13 +82,13 @@ python3 scripts/credential_poll.py --chat-id ${COMATE_SESSION_ID} --username ${C
35
82
  - `data.credentials`:凭证名值对列表
36
83
  - `data.deployment`:托管平台信息(platform、platformName)
37
84
  - `data.repo`:代码库语言和框架信息
38
- - `data.succMsg`:托管成功提示信息
39
- - `data.errorMsg`:托管失败提示信息
85
+ - `data.succMsg`:配置成功提示信息
86
+ - `data.errorMsg`:配置失败提示信息
40
87
  - `chatUUID`:此次会话 ID
41
88
 
42
89
  ## 步骤三:修复硬编码代码
43
90
 
44
- 收到凭证配置数据后,在本地直接修复硬编码漏洞,不调用后端修复服务。修复流程参考 `references/vul_repair_sensitive.md` 文档中的详细说明。
91
+ **【强制执行】** 收到凭证配置数据后,必须在本地直接修复硬编码漏洞,不调用后端修复服务。必须先读取 `references/vul_repair_sensitive.md` 文档中的修复规则再执行修复。
45
92
 
46
93
  修复输入数据来自 `poll_result.json` 文件(由步骤二保存),其中 `data.files`、`data.repo`、`data.deployment` 包含了修复所需的全部信息。
47
94
 
@@ -51,52 +98,167 @@ python3 scripts/credential_poll.py --chat-id ${COMATE_SESSION_ID} --username ${C
51
98
  3. 根据每个漏洞的 `extra.secret.credentialName`、`extra.secret.start`、`extra.secret.end` 定位敏感信息并替换为环境变量读取方式
52
99
  4. 如果 `data.deployment.platform` 为 4,还需引入 keyless-sdk(参考 `references/vul_repair_sensitive.md` 的「引入SDK」章节)
53
100
 
54
- ## 步骤四:凭证托管
101
+ ## 步骤四:托管凭证
55
102
 
56
- 代码修复完成后,提示用户确认修复结果,然后提供托管选项:
103
+ **【强制执行】** 代码修复完成后,以表格方式总结展示修复变化(文件路径、代码行位置、内容变化),然后必须使用 Questions 组件向用户提供以下选项,等待用户确认后再继续,不得自动跳过:
104
+
105
+ Questions 组件使用规范:
106
+ - **不得展示「Other」选项**
107
+ - **选项为必选**,用户未做选择时 Continue 按钮不可点击
57
108
 
58
109
  ```
59
- 代码修复已完成,请 Review 修复后的代码。确认无误后,选择「托管凭证」将凭证托管到平台。
110
+ 代码修复已完成,请 Review 修复后的代码。确认无误后,选择后续操作:
60
111
  1. 托管凭证 - 将凭证托管到 {platformName} 平台
61
112
  2. 跳过托管 - 仅完成代码修复,不托管凭证
62
113
  ```
63
114
 
64
- 用户选择托管后执行:
115
+ 用户必须选择其中一项后才能继续。
116
+
117
+ **用户选择「托管凭证」时**,执行:
65
118
 
66
119
  ```bash
67
- python3 scripts/credential_hosting.py --poll-result <poll_result.json路径> --username ${COMATE_USERNAME}
120
+ python3 scripts/credential_hosting.py --poll-result <poll_result.json路径> --username ${_USERNAME}
68
121
  ```
69
122
 
70
123
  脚本自动从 `poll_result.json` 中提取 `chatUUID`、`deployment.platformName`、`data.credentials`,无需手动传递这些参数。
124
+ 托管完成后,从 `poll_result.json` 中读取 `data.succMsg`, 展示给用户:
125
+ ```
126
+ {succMsg}
127
+ ```
128
+ 如果失败,从 `poll_result.json` 中读取 `data.errorMsg`, 展示给用户:
129
+ ```
130
+ {errorMsg}
131
+ ```
132
+
133
+
134
+ **用户选择「跳过托管」时**,直接进入步骤五。
135
+
136
+ 完成步骤四后,进入步骤五。
137
+
138
+ ## 步骤五:提交代码并合入
71
139
 
72
- 托管完成后,从 `poll_result.json` 中读取 `data.succMsg` 展示给用户。如果失败,展示 `data.errorMsg`。
140
+ **【强制执行】** 使用 Questions 组件向用户确认代码是否提交并推送合入远程仓库,不得自动跳过:
73
141
 
74
- 托管成功后,通过 Questions 组件提示用户进行历史 commit 清理。`succMsg` 中包含清理平台地址,需要从中提取链接并突出展示。提示格式:
142
+ Questions 组件使用规范:
143
+ - **不得展示「Other」选项**
144
+ - **选项为必选**,用户未做选择时 Continue 按钮不可点击
75
145
 
76
146
  ```
77
- 凭证托管已完成。由于历史 commit 中可能仍残留硬编码凭证,建议立即清理 Git 历史记录,防止凭证泄露。
147
+ 请确认代码是否提交并合入,选择后续操作:
148
+ 1. 代码提交且合入 - 继续清理历史 git commit 记录
149
+ 2. 代码未提交合入 - 进行复测扫描
150
+ 3. 代码未提交合入 - 进行单元测试
151
+ 4. 代码未提交合入 - 流程结束,后续由用户自行处理
152
+ ```
78
153
 
79
- {succMsg}
154
+ 根据用户选择执行对应分支:
155
+
156
+ - **选择 1(代码已合入)**→ 进入步骤六(清理历史 commit),清理完成后进入「复测扫描」→「单元测试」→「清理临时文件」
157
+ - **选择 2(复测扫描)**→ 进入「复测扫描」→「清理临时文件」
158
+ - **选择 3(单元测试)**→ 进入「单元测试」→「复测扫描」→「清理临时文件」
159
+ - **选择 4(流程结束)**→ 进入「清理临时文件」后结束
160
+
161
+ ## 步骤六:清理历史 git commit 记录
162
+
163
+ **【强制执行】** 仅当用户在步骤五选择「代码已合入」时执行此步骤。
164
+
165
+ 由于历史 commit 中可能仍残留硬编码凭证,需要提示用户清理 Git 历史记录。
166
+
167
+ `REPO` 从项目目录的 git remote URL 中提取三级路径(格式为 `一级/二级/三级`,如 `baidu/scan/cnap-test`):
168
+ - SSH 格式(`git@icode.baidu.com:baidu/scan/cnap-test.git`):取 `:` 后的部分,去掉 `.git` 后缀
169
+ - HTTP 格式(`https://icode.baidu.com/baidu/scan/cnap-test`):取域名后的路径部分,去掉 `.git` 后缀
170
+ - 若无 git 信息则使用项目目录名;`/` 不需要编码,直接拼接
171
+
172
+ 1. 在聊天框输出可点击链接:
173
+
174
+ ```
175
+ 代码已合入,建议立即清理 Git 历史记录,防止历史 commit 中残留的硬编码凭证泄露。
176
+
177
+ 请点击以下链接进入清理平台:[历史 Commit 清理平台](https://commit-clean.baidu-int.com/task?repo=<REPO>)
178
+ ```
80
179
 
180
+ 2. 执行以下命令在外部浏览器中自动打开清理平台:
181
+
182
+ ```bash
183
+ python3 -c "import webbrowser; webbrowser.open('https://commit-clean.baidu-int.com/task?repo=<REPO>')"
184
+ ```
185
+
186
+ 3. 通过 Questions 组件让用户确认(**不得展示「Other」选项,选项为必选,未选择时 Continue 按钮不可点击**):
187
+
188
+ ```
81
189
  请确认:
82
190
  1. 已完成清理 - 我已清理历史 commit,继续后续流程
83
191
  2. 稍后处理 - 跳过清理,继续后续流程
84
192
  ```
85
193
 
86
- 用户选择后继续执行复测扫描。
194
+ 用户选择后,使用 Questions 组件询问是否申请结单(**不得展示「Other」选项,选项为必选**):
195
+
196
+ ```
197
+ 是否申请结单?
198
+ 1. 是,立即申请结单
199
+ 2. 否,稍后手动处理
200
+ ```
201
+
202
+ 根据用户选择:
203
+ - **选择「是,立即申请结单」**→ 执行「申请结单」→ 清理临时文件 → **流程结束,不再执行复测扫描**
204
+ - **选择「否,稍后手动处理」**→ 进入「复测扫描」
205
+
206
+ ## 单元测试
207
+
208
+ 进入单元测试阶段(流程见 SKILL.md「单元测试」章节)。「单元测试」完成后进入「复测扫描」。
87
209
 
88
210
  ## 复测扫描
89
211
 
90
- 托管成功后,自动执行一次复测扫描(流程与「漏洞扫描」章节一致),对比修复前后的硬编码漏洞数量,向用户说明修复效果。复测结果同样需要静默执行数据上报。展示格式:
212
+ **【强制执行】** 必须自动执行一次复测扫描(流程与 SKILL.md「漏洞扫描」章节一致),不得跳过。对比修复前后的硬编码漏洞数量,向用户说明修复效果。复测结果同样必须执行数据上报。展示格式:
91
213
 
92
214
  ```
93
- 托管完成,正在执行复测扫描验证修复效果...
215
+ 正在执行复测扫描验证修复效果...
94
216
 
95
217
  **复测结果**:修复前共 N 个硬编码漏洞,修复后剩余 M 个,本次修复 X 个漏洞。
96
218
  ```
97
219
 
98
220
  如果复测仍存在未修复的硬编码漏洞,展示剩余漏洞列表(格式同漏洞报告),并提示用户可以选择继续修复或忽略。
99
221
 
222
+ 复测扫描结束后,使用 Questions 组件询问是否申请结单(**不得展示「Other」选项,选项为必选**):
223
+
224
+ ```
225
+ 是否申请结单?
226
+ 1. 是,立即申请结单
227
+ 2. 否,稍后手动处理
228
+ ```
229
+
230
+ 根据用户选择:
231
+ - **选择「是,立即申请结单」**→ 执行「申请结单」→ 清理临时文件 → **流程结束**
232
+ - **选择「否,稍后手动处理」**→ 进入清理临时文件
233
+
100
234
  ## 清理临时文件
101
235
 
102
- 复测完成后,清理临时文件:`python3 -c "import sys; sys.path.insert(0, '<skill安装目录>/scripts'); import utils; utils.safe_rmtree('<临时目录绝对路径>')"` 删除该项目的临时目录(即 `.tmp/<项目名>_<哈希>/` 整个目录)。`safe_rmtree` 会校验路径位于 `.tmp` 下防止误删。然后进入单元测试阶段(流程见「单元测试」章节)。
236
+ 所有流程结束后,清理临时文件:`python3 -c "import shutil; shutil.rmtree('<临时目录绝对路径>')"` 删除该项目的临时目录(即 `.tmp/<项目名>_<哈希>/` 整个目录)。
237
+
238
+ ## 申请结单
239
+
240
+ 用户选择「是,立即申请结单」时:
241
+
242
+ 1. 在聊天框输出以下内容,提示用户前往网站申请结单:
243
+
244
+ ```
245
+ 请点击以下链接,在工单系统中申请结单:
246
+
247
+ [申请结单](https://security.baidu.com/ticket/pending/list)
248
+ ```
249
+
250
+ 2. 执行以下命令在外部浏览器中自动打开申请结单页面:
251
+
252
+ ```bash
253
+ python3 -c "import webbrowser; webbrowser.open('https://security.baidu.com/ticket/pending/list')"
254
+ ```
255
+
256
+ 3. 输出提示:
257
+
258
+ ```
259
+ 已为您打开申请结单页面,请在工单列表中找到对应工单并申请结单。流程至此结束。
260
+ ```
261
+
262
+ 流程结束。
263
+
264
+ 用户选择「否,稍后手动处理」时,跳过此步骤,继续后续流程。