@zhuma4/cli 4.0.0-alpha.1

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 (288) hide show
  1. package/README.md +42 -0
  2. package/dist/commands/config.d.ts +3 -0
  3. package/dist/commands/config.d.ts.map +1 -0
  4. package/dist/commands/config.js +18 -0
  5. package/dist/commands/config.js.map +1 -0
  6. package/dist/commands/init.d.ts +3 -0
  7. package/dist/commands/init.d.ts.map +1 -0
  8. package/dist/commands/init.js +11 -0
  9. package/dist/commands/init.js.map +1 -0
  10. package/dist/commands/scan.d.ts +3 -0
  11. package/dist/commands/scan.d.ts.map +1 -0
  12. package/dist/commands/scan.js +96 -0
  13. package/dist/commands/scan.js.map +1 -0
  14. package/dist/commands/scan_appid.d.ts +20 -0
  15. package/dist/commands/scan_appid.d.ts.map +1 -0
  16. package/dist/commands/scan_appid.js +301 -0
  17. package/dist/commands/scan_appid.js.map +1 -0
  18. package/dist/commands/scan_manifest.d.ts +13 -0
  19. package/dist/commands/scan_manifest.d.ts.map +1 -0
  20. package/dist/commands/scan_manifest.js +103 -0
  21. package/dist/commands/scan_manifest.js.map +1 -0
  22. package/dist/engine/api-submit.d.ts +16 -0
  23. package/dist/engine/api-submit.d.ts.map +1 -0
  24. package/dist/engine/api-submit.js +66 -0
  25. package/dist/engine/api-submit.js.map +1 -0
  26. package/dist/engine/batch_scan.d.ts +36 -0
  27. package/dist/engine/batch_scan.d.ts.map +1 -0
  28. package/dist/engine/batch_scan.js +192 -0
  29. package/dist/engine/batch_scan.js.map +1 -0
  30. package/dist/engine/config.d.ts +12 -0
  31. package/dist/engine/config.d.ts.map +1 -0
  32. package/dist/engine/config.js +27 -0
  33. package/dist/engine/config.js.map +1 -0
  34. package/dist/engine/errors.d.ts +36 -0
  35. package/dist/engine/errors.d.ts.map +1 -0
  36. package/dist/engine/errors.js +99 -0
  37. package/dist/engine/errors.js.map +1 -0
  38. package/dist/engine/filter.d.ts +13 -0
  39. package/dist/engine/filter.d.ts.map +1 -0
  40. package/dist/engine/filter.js +64 -0
  41. package/dist/engine/filter.js.map +1 -0
  42. package/dist/engine/finding_classifier.d.ts +108 -0
  43. package/dist/engine/finding_classifier.d.ts.map +1 -0
  44. package/dist/engine/finding_classifier.js +440 -0
  45. package/dist/engine/finding_classifier.js.map +1 -0
  46. package/dist/engine/incremental/engine.d.ts +25 -0
  47. package/dist/engine/incremental/engine.d.ts.map +1 -0
  48. package/dist/engine/incremental/engine.js +337 -0
  49. package/dist/engine/incremental/engine.js.map +1 -0
  50. package/dist/engine/incremental/git-diff.d.ts +19 -0
  51. package/dist/engine/incremental/git-diff.d.ts.map +1 -0
  52. package/dist/engine/incremental/git-diff.js +175 -0
  53. package/dist/engine/incremental/git-diff.js.map +1 -0
  54. package/dist/engine/incremental/types.d.ts +33 -0
  55. package/dist/engine/incremental/types.d.ts.map +1 -0
  56. package/dist/engine/incremental/types.js +11 -0
  57. package/dist/engine/incremental/types.js.map +1 -0
  58. package/dist/engine/manifest_scanner.d.ts +48 -0
  59. package/dist/engine/manifest_scanner.d.ts.map +1 -0
  60. package/dist/engine/manifest_scanner.js +599 -0
  61. package/dist/engine/manifest_scanner.js.map +1 -0
  62. package/dist/engine/project.d.ts +22 -0
  63. package/dist/engine/project.d.ts.map +1 -0
  64. package/dist/engine/project.js +279 -0
  65. package/dist/engine/project.js.map +1 -0
  66. package/dist/engine/sarif.d.ts +13 -0
  67. package/dist/engine/sarif.d.ts.map +1 -0
  68. package/dist/engine/sarif.js +44 -0
  69. package/dist/engine/sarif.js.map +1 -0
  70. package/dist/engine/sca-integration.d.ts +36 -0
  71. package/dist/engine/sca-integration.d.ts.map +1 -0
  72. package/dist/engine/sca-integration.js +91 -0
  73. package/dist/engine/sca-integration.js.map +1 -0
  74. package/dist/engine/scanner.d.ts +18 -0
  75. package/dist/engine/scanner.d.ts.map +1 -0
  76. package/dist/engine/scanner.js +138 -0
  77. package/dist/engine/scanner.js.map +1 -0
  78. package/dist/index.d.ts +13 -0
  79. package/dist/index.d.ts.map +1 -0
  80. package/dist/index.js +41 -0
  81. package/dist/index.js.map +1 -0
  82. package/dist/report/render.d.ts +23 -0
  83. package/dist/report/render.d.ts.map +1 -0
  84. package/dist/report/render.js +335 -0
  85. package/dist/report/render.js.map +1 -0
  86. package/package.json +41 -0
  87. package/rules/android/mobile-cleartext-traffic.yaml +46 -0
  88. package/rules/android/mobile-component-security.yaml +107 -0
  89. package/rules/android/mobile-crypto-weakness.yaml +139 -0
  90. package/rules/android/mobile-cwe-1021-tapjacking.yaml +81 -0
  91. package/rules/android/mobile-cwe-114-dynamic-dex-loading.yaml +41 -0
  92. package/rules/android/mobile-cwe-200-clipboard-data-leak.yaml +66 -0
  93. package/rules/android/mobile-cwe-200-debug-builds.yaml +111 -0
  94. package/rules/android/mobile-cwe-200-log-sensitive-data.yaml +61 -0
  95. package/rules/android/mobile-cwe-200-webview-debugging.yaml +56 -0
  96. package/rules/android/mobile-cwe-200-webview-universal-access.yaml +30 -0
  97. package/rules/android/mobile-cwe-200-window-flags.yaml +96 -0
  98. package/rules/android/mobile-cwe-22-content-provider-openfile.yaml +73 -0
  99. package/rules/android/mobile-cwe-22-path-traversal.yaml +86 -0
  100. package/rules/android/mobile-cwe-287-biometric-weakness.yaml +102 -0
  101. package/rules/android/mobile-cwe-295-cert-pinning-missing.yaml +78 -0
  102. package/rules/android/mobile-cwe-295-webview-ssl-bypass.yaml +104 -0
  103. package/rules/android/mobile-cwe-312-cleartext-storage.yaml +109 -0
  104. package/rules/android/mobile-cwe-319-cleartext-communication.yaml +84 -0
  105. package/rules/android/mobile-cwe-321-hardcoded-crypto-keys.yaml +132 -0
  106. package/rules/android/mobile-cwe-326-short-rsa.yaml +108 -0
  107. package/rules/android/mobile-cwe-327-rc4-3des.yaml +107 -0
  108. package/rules/android/mobile-cwe-329-cbc-padding-oracle.yaml +76 -0
  109. package/rules/android/mobile-cwe-470-reflection-injection.yaml +39 -0
  110. package/rules/android/mobile-cwe-489-root-detection-weak.yaml +125 -0
  111. package/rules/android/mobile-cwe-489-stetho-debug.yaml +107 -0
  112. package/rules/android/mobile-cwe-502-insecure-deserialization.yaml +76 -0
  113. package/rules/android/mobile-cwe-552-world-readable-files.yaml +63 -0
  114. package/rules/android/mobile-cwe-749-webview-java-objects.yaml +78 -0
  115. package/rules/android/mobile-cwe-749-webview-jsbridge.yaml +57 -0
  116. package/rules/android/mobile-cwe-749-webview-loadurl-injection.yaml +80 -0
  117. package/rules/android/mobile-cwe-78-command-injection.yaml +77 -0
  118. package/rules/android/mobile-cwe-780-rsa-no-oaep.yaml +80 -0
  119. package/rules/android/mobile-cwe-79-webview-setdata.yaml +78 -0
  120. package/rules/android/mobile-cwe-79-webview-xss.yaml +65 -0
  121. package/rules/android/mobile-cwe-798-hardcoded-credentials.yaml +108 -0
  122. package/rules/android/mobile-cwe-89-sql-injection.yaml +100 -0
  123. package/rules/android/mobile-cwe-927-implicit-intent.yaml +121 -0
  124. package/rules/android/mobile-cwe-927-ipc-file-provider.yaml +102 -0
  125. package/rules/android/mobile-cwe-939-deeplink-validation.yaml +76 -0
  126. package/rules/android/mobile-sdk-google-firebase-open.yaml +117 -0
  127. package/rules/android/mobile-sdk-tencent-tpns-config-leak.yaml +131 -0
  128. package/rules/android/mobile-secrets-storage.yaml +136 -0
  129. package/rules/android/mobile-webview-security.yaml +88 -0
  130. package/rules/common/cwe-200-sensitive-data-exposure.yaml +61 -0
  131. package/rules/common/cwe-22-path-traversal.yaml +47 -0
  132. package/rules/common/cwe-295-ssl-bypass.yaml +217 -0
  133. package/rules/common/cwe-295-ssl-verification-disabled.yaml +64 -0
  134. package/rules/common/cwe-306-missing-authentication.yaml +44 -0
  135. package/rules/common/cwe-326-weak-key-size.yaml +107 -0
  136. package/rules/common/cwe-327-weak-crypto.yaml +177 -0
  137. package/rules/common/cwe-328-weak-hash.yaml +96 -0
  138. package/rules/common/cwe-329-cbc-mode.yaml +26 -0
  139. package/rules/common/cwe-352-csrf.yaml +23 -0
  140. package/rules/common/cwe-434-unrestricted-file-upload.yaml +41 -0
  141. package/rules/common/cwe-502-insecure-deserialization.yaml +44 -0
  142. package/rules/common/cwe-601-url-redirect.yaml +110 -0
  143. package/rules/common/cwe-611-xxe.yaml +70 -0
  144. package/rules/common/cwe-732-incorrect-permission.yaml +49 -0
  145. package/rules/common/cwe-770-resource-exhaustion.yaml +44 -0
  146. package/rules/common/cwe-78-os-command-injection.yaml +43 -0
  147. package/rules/common/cwe-787-out-of-bounds-write.yaml +37 -0
  148. package/rules/common/cwe-79-xss.yaml +51 -0
  149. package/rules/common/cwe-862-missing-authorization.yaml +40 -0
  150. package/rules/common/cwe-89-sqli.yaml +89 -0
  151. package/rules/common/cwe-918-ssrf.yaml +45 -0
  152. package/rules/common/cwe-94-code-injection.yaml +59 -0
  153. package/rules/common/zm-go-cwe22-path-traversal-fs.yaml +117 -0
  154. package/rules/common/zm-go-cwe22-path-traversal.yaml +103 -0
  155. package/rules/common/zm-go-cwe307-brute-force.yaml +129 -0
  156. package/rules/common/zm-go-cwe326-weak-crypto.yaml +124 -0
  157. package/rules/common/zm-go-cwe327-weak-cipher.yaml +152 -0
  158. package/rules/common/zm-go-cwe384-session-fixation.yaml +128 -0
  159. package/rules/common/zm-go-cwe502-deserialization.yaml +120 -0
  160. package/rules/common/zm-go-cwe78-command-injection.yaml +95 -0
  161. package/rules/common/zm-go-cwe79-xss.yaml +104 -0
  162. package/rules/common/zm-go-cwe798-hardcoded-creds.yaml +153 -0
  163. package/rules/common/zm-go-cwe89-sqli.yaml +89 -0
  164. package/rules/common/zm-go-cwe918-ssrf.yaml +117 -0
  165. package/rules/common/zm-java-cwe117-log-injection.yaml +83 -0
  166. package/rules/common/zm-java-cwe117-logforging.yaml +153 -0
  167. package/rules/common/zm-java-cwe200-actuator-exposure.yaml +8 -0
  168. package/rules/common/zm-java-cwe200-info-disclosure.yaml +91 -0
  169. package/rules/common/zm-java-cwe22-file-depth.yaml +135 -0
  170. package/rules/common/zm-java-cwe22-path-traversal-spring.yaml +81 -0
  171. package/rules/common/zm-java-cwe284-missing-auth-spring.yaml +131 -0
  172. package/rules/common/zm-java-cwe295-webview-ssl.yaml +123 -0
  173. package/rules/common/zm-java-cwe327-weakcrypto.yaml +197 -0
  174. package/rules/common/zm-java-cwe347-jwt.yaml +30 -0
  175. package/rules/common/zm-java-cwe352-csrf-depth.yaml +107 -0
  176. package/rules/common/zm-java-cwe352-csrf-disabled.yaml +15 -0
  177. package/rules/common/zm-java-cwe501-trust-boundary.yaml +124 -0
  178. package/rules/common/zm-java-cwe502-deserial-depth.yaml +128 -0
  179. package/rules/common/zm-java-cwe502-fastjson.yaml +137 -0
  180. package/rules/common/zm-java-cwe502-gadget.yaml +158 -0
  181. package/rules/common/zm-java-cwe502-jndi-injection.yaml +91 -0
  182. package/rules/common/zm-java-cwe502-shiro.yaml +108 -0
  183. package/rules/common/zm-java-cwe601-url-redirect-spring.yaml +85 -0
  184. package/rules/common/zm-java-cwe611-xxe-enhanced.yaml +80 -0
  185. package/rules/common/zm-java-cwe611-xxe-transformer.yaml +85 -0
  186. package/rules/common/zm-java-cwe639-idor.yaml +123 -0
  187. package/rules/common/zm-java-cwe79-xss-depth.yaml +98 -0
  188. package/rules/common/zm-java-cwe862-authz-depth.yaml +127 -0
  189. package/rules/common/zm-java-cwe915-mass-assignment.yaml +16 -0
  190. package/rules/common/zm-java-cwe917-expression-injection.yaml +120 -0
  191. package/rules/common/zm-java-cwe918-resttemplate.yaml +67 -0
  192. package/rules/common/zm-java-cwe918-ssrf-depth.yaml +103 -0
  193. package/rules/common/zm-java-cwe918-ssrf-resttemplate.yaml +77 -0
  194. package/rules/common/zm-java-cwe918-webclient.yaml +44 -0
  195. package/rules/common/zm-java-cwe94-ognl.yaml +66 -0
  196. package/rules/common/zm-java-cwe94-spel-injection.yaml +85 -0
  197. package/rules/common/zm-java-cwe94-spel.yaml +112 -0
  198. package/rules/common/zm-java-cwe94-ssti.yaml +22 -0
  199. package/rules/common/zm-java-cwe942-cors.yaml +15 -0
  200. package/rules/common/zm-js-cwe1321-prototype-pollution.yaml +61 -0
  201. package/rules/common/zm-js-cwe200-info-disclosure.yaml +95 -0
  202. package/rules/common/zm-js-cwe22-path-traversal-fs.yaml +113 -0
  203. package/rules/common/zm-js-cwe22-pathtraversal.yaml +111 -0
  204. package/rules/common/zm-js-cwe307-brute-force.yaml +136 -0
  205. package/rules/common/zm-js-cwe345-postmessage.yaml +75 -0
  206. package/rules/common/zm-js-cwe347-jwt-weak.yaml +95 -0
  207. package/rules/common/zm-js-cwe352-csrf.yaml +52 -0
  208. package/rules/common/zm-js-cwe384-session-fixation.yaml +132 -0
  209. package/rules/common/zm-js-cwe502-deserialization.yaml +119 -0
  210. package/rules/common/zm-js-cwe611-xxe.yaml +108 -0
  211. package/rules/common/zm-js-cwe639-idor.yaml +122 -0
  212. package/rules/common/zm-js-cwe693-helmet-missing.yaml +46 -0
  213. package/rules/common/zm-js-cwe78-exec.yaml +37 -0
  214. package/rules/common/zm-js-cwe78-spawn.yaml +37 -0
  215. package/rules/common/zm-js-cwe79-domxss.yaml +84 -0
  216. package/rules/common/zm-js-cwe79-react-xss.yaml +18 -0
  217. package/rules/common/zm-js-cwe79-xss-ejs.yaml +70 -0
  218. package/rules/common/zm-js-cwe89-sqli.yaml +153 -0
  219. package/rules/common/zm-js-cwe915-mass-assignment.yaml +111 -0
  220. package/rules/common/zm-js-cwe918-ssrf-fetch.yaml +134 -0
  221. package/rules/common/zm-js-cwe918-ssrf.yaml +132 -0
  222. package/rules/common/zm-js-cwe94-template-injection.yaml +130 -0
  223. package/rules/common/zm-js-cwe942-cors.yaml +49 -0
  224. package/rules/common/zm-js-cwe943-nosql-injection.yaml +52 -0
  225. package/rules/common/zm-js-cwe95-eval.yaml +59 -0
  226. package/rules/common/zm-js-cwe95-function-ctor.yaml +31 -0
  227. package/rules/common/zm-py-cwe22-path-traversal.yaml +86 -0
  228. package/rules/common/zm-py-cwe327-weak-crypto.yaml +103 -0
  229. package/rules/common/zm-py-cwe502-pickle.yaml +92 -0
  230. package/rules/common/zm-py-cwe611-xxe.yaml +100 -0
  231. package/rules/common/zm-py-cwe78-command-injection.yaml +121 -0
  232. package/rules/common/zm-py-cwe79-xss.yaml +123 -0
  233. package/rules/common/zm-py-cwe798-hardcoded-creds.yaml +86 -0
  234. package/rules/common/zm-py-cwe89-sqli.yaml +59 -0
  235. package/rules/common/zm-py-cwe918-ssrf.yaml +123 -0
  236. package/rules/common/zm-py-cwe94-ssti.yaml +87 -0
  237. package/rules/common/zm-py-cwe943-nosql-injection.yaml +123 -0
  238. package/rules/iac/ansible/zm-ansible-cwe269-privilege-escalation.yaml +63 -0
  239. package/rules/iac/ansible/zm-ansible-cwe78-command-injection.yaml +67 -0
  240. package/rules/iac/ansible/zm-ansible-cwe798-hardcoded-creds.yaml +93 -0
  241. package/rules/iac/terraform/zm-tf-cwe200-s3-bucket-public.yaml +100 -0
  242. package/rules/iac/terraform/zm-tf-cwe284-sg-wide-open.yaml +88 -0
  243. package/rules/iac/terraform/zm-tf-cwe311-iam-wildcard.yaml +83 -0
  244. package/rules/iac/terraform/zm-tf-cwe319-rds-public.yaml +72 -0
  245. package/rules/iac/terraform/zm-tf-cwe798-hardcoded-creds.yaml +102 -0
  246. package/rules/iac/zm-docker-cwe250-root-user.yaml +50 -0
  247. package/rules/iac/zm-docker-cwe400-resource-limit.yaml +92 -0
  248. package/rules/iac/zm-docker-security.yaml +104 -0
  249. package/rules/iac/zm-k8s-cwe200-service-account.yaml +83 -0
  250. package/rules/iac/zm-k8s-cwe250-privileged.yaml +56 -0
  251. package/rules/iac/zm-k8s-security.yaml +79 -0
  252. package/rules/rules_index.yaml.off +477 -0
  253. package/rules/semgrep-registry/anonymous-ldap-bind.yaml +34 -0
  254. package/rules/semgrep-registry/bad-hexa-conversion.yaml +32 -0
  255. package/rules/semgrep-registry/blowfish-insufficient-key-size.yaml +39 -0
  256. package/rules/semgrep-registry/cbc-padding-oracle.yaml +38 -0
  257. package/rules/semgrep-registry/command-injection-formatted-runtime-call.yaml +90 -0
  258. package/rules/semgrep-registry/command-injection-process-builder.yaml +148 -0
  259. package/rules/semgrep-registry/cookie-missing-httponly.yaml +38 -0
  260. package/rules/semgrep-registry/cookie-missing-secure-flag.yaml +38 -0
  261. package/rules/semgrep-registry/crlf-injection-logs.yaml +86 -0
  262. package/rules/semgrep-registry/dangerous-groovy-shell.yaml +46 -0
  263. package/rules/semgrep-registry/el-injection.yaml +137 -0
  264. package/rules/semgrep-registry/formatted-sql-string.yaml +95 -0
  265. package/rules/semgrep-registry/http-response-splitting.yaml +44 -0
  266. package/rules/semgrep-registry/index.txt +1 -0
  267. package/rules/semgrep-registry/insecure-smtp-connection.yaml +34 -0
  268. package/rules/semgrep-registry/java-reverse-shell.yaml +43 -0
  269. package/rules/semgrep-registry/jdbc-sql-formatted-string.yaml +120 -0
  270. package/rules/semgrep-registry/ldap-entry-poisoning.yaml +41 -0
  271. package/rules/semgrep-registry/ldap-injection.yaml +82 -0
  272. package/rules/semgrep-registry/md5-used-as-password.yaml +44 -0
  273. package/rules/semgrep-registry/object-deserialization.yaml +34 -0
  274. package/rules/semgrep-registry/ognl-injection.yaml +839 -0
  275. package/rules/semgrep-registry/overly-permissive-file-permission.yaml +49 -0
  276. package/rules/semgrep-registry/permissive-cors.yaml +77 -0
  277. package/rules/semgrep-registry/script-engine-injection.yaml +66 -0
  278. package/rules/semgrep-registry/tainted-cmd-from-http-request.yaml +74 -0
  279. package/rules/semgrep-registry/tainted-env-from-http-request.yaml +46 -0
  280. package/rules/semgrep-registry/tainted-ldapi-from-http-request.yaml +42 -0
  281. package/rules/semgrep-registry/tainted-session-from-http-request.yaml +70 -0
  282. package/rules/semgrep-registry/tainted-xpath-from-http-request.yaml +38 -0
  283. package/rules/semgrep-registry/unsafe-reflection.yaml +39 -0
  284. package/rules/semgrep-registry/unvalidated-redirect.yaml +127 -0
  285. package/rules/semgrep-registry/url-rewriting.yaml +82 -0
  286. package/rules/semgrep-registry/weak-ssl-context.yaml +34 -0
  287. package/rules/semgrep-registry/xml-decoder.yaml +53 -0
  288. package/rules/semgrep-registry/xssrequestwrapper-is-insecure.yaml +40 -0
@@ -0,0 +1,99 @@
1
+ /**
2
+ * 逐码 CLI 错误处理 — 友好提示 + 排查建议
3
+ *
4
+ * 设计原则:
5
+ * 1. 所有错误输出为汉语 + 排查建议
6
+ * 2. 区分用户错误 (4xx) vs 系统错误 (5xx)
7
+ * 3. 不崩堆栈 — 仅在 --debug 模式输出完整 trace
8
+ */
9
+ export class ZhumaError extends Error {
10
+ /** 错误码: 4xx=用户侧, 5xx=系统侧 */
11
+ code;
12
+ /** 排查建议 (面向终端用户) */
13
+ suggestion;
14
+ constructor(code, message, suggestion) {
15
+ super(message);
16
+ this.name = 'ZhumaError';
17
+ this.code = code;
18
+ this.suggestion = suggestion;
19
+ }
20
+ }
21
+ /** Semgrep 未安装 */
22
+ export function semgrepNotFound(err) {
23
+ return new ZhumaError(500, '未找到 Semgrep CLI', `请执行: pip install semgrep\n` +
24
+ `验证安装: semgrep --version\n` +
25
+ `如果已安装仍报错,检查 PATH 环境变量是否包含 Semgrep 所在目录`);
26
+ }
27
+ /** 目标路径不存在 */
28
+ export function targetNotFound(target) {
29
+ return new ZhumaError(404, `目标路径不存在: ${target}`, `请检查路径拼写是否正确\n` +
30
+ `提示: 使用绝对路径 (如 C:\\projects\\my-app) 可避免相对路径歧义`);
31
+ }
32
+ /** Semgrep 扫描超时 */
33
+ export function scanTimeout(target, timeoutSec) {
34
+ return new ZhumaError(504, `扫描超时 (${timeoutSec}秒): ${target}`, `项目过大或文件过多导致超时\n` +
35
+ `建议:\n` +
36
+ ` 1. 使用 --quick 快速模式 (仅运行 L0 高优先级规则)\n` +
37
+ ` 2. 使用 --timeout 增加超时时间\n` +
38
+ ` 3. 排除测试目录: zhuma config set exclude "**/test/**"`);
39
+ }
40
+ /** Semgrep 非零退出 (非1) */
41
+ export function semgrepCrashed(exitCode, stderr) {
42
+ return new ZhumaError(500, `Semgrep 扫描异常退出 (exit ${exitCode})`, `错误详情:\n${stderr.slice(-500)}\n\n` +
43
+ `常见原因:\n` +
44
+ ` 1. Semgrep 版本过旧 → pip install --upgrade semgrep\n` +
45
+ ` 2. 规则文件语法错误 → 检查自定义规则 YAML\n` +
46
+ ` 3. 目标项目编译错误 → 先确保项目能正常编译\n` +
47
+ ` 4. 内存不足 → 尝试 --quick 模式或增加系统内存`);
48
+ }
49
+ /** SARIF JSON 解析失败 */
50
+ export function sarifParsedFailed(context) {
51
+ return new ZhumaError(500, `Semgrep 输出解析失败`, `Semgrep 产生的 SARIF JSON 无法解析\n\n` +
52
+ `输出快照:\n${context.slice(0, 300)}\n\n` +
53
+ `请确认 Semgrep 版本 ≥ 1.168.0\n` +
54
+ `如问题持续,运行 semgrep scan --debug 查看完整输出`);
55
+ }
56
+ /** 规则目录不存在 */
57
+ export function rulesNotFound(rulesPath) {
58
+ return new ZhumaError(404, `规则目录不存在: ${rulesPath}`, `请检查 --rules 参数指定的路径\n` +
59
+ `默认规则目录: packages/rules/common/\n` +
60
+ `列出可用规则: zhuma config show`);
61
+ }
62
+ /** 不支持的输出格式 */
63
+ export function unsupportedFormat(format) {
64
+ return new ZhumaError(400, `不支持的输出格式: ${format}`, `支持的格式: json | html | sarif\n` +
65
+ `示例: zhuma scan ./src -o html`);
66
+ }
67
+ /** 项目初始化失败 */
68
+ export function initFailed(reason) {
69
+ return new ZhumaError(500, `项目初始化失败: ${reason}`, `请检查:\n` +
70
+ ` 1. 目标目录是否有读写权限\n` +
71
+ ` 2. 磁盘空间是否充足\n` +
72
+ ` 3. 是否已有 .zhuma.yaml (先删除后重试)`);
73
+ }
74
+ /**
75
+ * 全局错误拦截 — 打印友好错误 + 退出
76
+ */
77
+ export function handleError(err, debug = false) {
78
+ if (err instanceof ZhumaError) {
79
+ console.error(`\n❌ 错误 (${err.code}): ${err.message}\n`);
80
+ console.error(`💡 排查建议:\n${err.suggestion}\n`);
81
+ if (debug) {
82
+ console.error('--- DEBUG ---');
83
+ console.error(err.stack);
84
+ }
85
+ }
86
+ else if (err instanceof Error) {
87
+ console.error(`\n❌ 未预期错误: ${err.message}\n`);
88
+ console.error('请使用 --debug 查看完整堆栈\n');
89
+ if (debug) {
90
+ console.error('--- DEBUG ---');
91
+ console.error(err.stack);
92
+ }
93
+ }
94
+ else {
95
+ console.error(`\n❌ 未知错误: ${String(err)}\n`);
96
+ }
97
+ process.exitCode = 1;
98
+ }
99
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/engine/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * 白名单过滤器 — SDK / 框架类 / 已知噪声过滤
3
+ *
4
+ * 从 V3.3 filter_findings.js 迁移 + 方法级白名单扩展
5
+ */
6
+ import type { Finding } from '@zhuma4/sdk';
7
+ /**
8
+ * 过滤 SDk 和已知噪声发现
9
+ * @param findings 原始发现列表
10
+ * @returns 过滤后的结果
11
+ */
12
+ export declare function filterFindings(findings: Finding[]): Finding[];
13
+ //# sourceMappingURL=filter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../../src/engine/filter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAoC3C;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAyB7D"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * 白名单过滤器 — SDK / 框架类 / 已知噪声过滤
3
+ *
4
+ * 从 V3.3 filter_findings.js 迁移 + 方法级白名单扩展
5
+ */
6
+ /**
7
+ * 已知无害的包路径前缀 (SDK / 框架类)
8
+ */
9
+ const SDK_WHITELIST = [
10
+ 'android.',
11
+ 'androidx.',
12
+ 'com.google.',
13
+ 'com.facebook.',
14
+ 'com.amazon.',
15
+ 'io.netty.',
16
+ 'org.springframework.test.',
17
+ 'com.fasterxml.jackson.',
18
+ 'org.hibernate.',
19
+ 'junit.',
20
+ 'org.junit.',
21
+ 'org.mockito.',
22
+ 'com.sun.',
23
+ 'sun.',
24
+ 'java.',
25
+ 'javax.',
26
+ ];
27
+ /**
28
+ * 已知无害的方法/模式 (产生噪声的框架方法)
29
+ */
30
+ const METHOD_WHITELIST = [
31
+ 'toString()',
32
+ 'equals(Object)',
33
+ 'hashCode()',
34
+ 'clone()',
35
+ 'finalize()',
36
+ 'readObject(ObjectInputStream)',
37
+ ];
38
+ /**
39
+ * 过滤 SDk 和已知噪声发现
40
+ * @param findings 原始发现列表
41
+ * @returns 过滤后的结果
42
+ */
43
+ export function filterFindings(findings) {
44
+ const before = findings.length;
45
+ const filtered = findings.filter((f) => {
46
+ // 文件级白名单
47
+ for (const prefix of SDK_WHITELIST) {
48
+ if (f.file.includes(prefix.replace(/\./g, '/'))) {
49
+ return false;
50
+ }
51
+ }
52
+ // 方法级白名单 (如果 message 中包含匹配)
53
+ for (const method of METHOD_WHITELIST) {
54
+ if (f.message.includes(method)) {
55
+ return false;
56
+ }
57
+ }
58
+ return true;
59
+ });
60
+ // TODO: V4.0 日志
61
+ // console.log(`[逐码] filter: ${before} → ${filtered.length} (${Math.round(filtered.length/before*100)}%)`);
62
+ return filtered;
63
+ }
64
+ //# sourceMappingURL=filter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter.js","sourceRoot":"","sources":["../../src/engine/filter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;GAEG;AACH,MAAM,aAAa,GAAG;IACpB,UAAU;IACV,WAAW;IACX,aAAa;IACb,eAAe;IACf,aAAa;IACb,WAAW;IACX,2BAA2B;IAC3B,wBAAwB;IACxB,gBAAgB;IAChB,QAAQ;IACR,YAAY;IACZ,cAAc;IACd,UAAU;IACV,MAAM;IACN,OAAO;IACP,QAAQ;CACT,CAAC;AAEF;;GAEG;AACH,MAAM,gBAAgB,GAAG;IACvB,YAAY;IACZ,gBAAgB;IAChB,YAAY;IACZ,SAAS;IACT,YAAY;IACZ,+BAA+B;CAChC,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,QAAmB;IAChD,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;IAE/B,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QACrC,SAAS;QACT,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;YACnC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;gBAChD,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAED,4BAA4B;QAC5B,KAAK,MAAM,MAAM,IAAI,gBAAgB,EAAE,CAAC;YACtC,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC/B,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,gBAAgB;IAChB,2GAA2G;IAE3G,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * ApplicationId-aware Finding Classifier — APP vs SDK vs UNKNOWN
3
+ *
4
+ * V4.1 AppID Boundary Engine
5
+ *
6
+ * 核心问题:
7
+ * jadx 反编译 APK → 80%+ Java 文件是三方 SDK/库代码
8
+ * 当前静态包白名单过滤不可靠(混入/混淆框架无效)
9
+ *
10
+ * 方案:
11
+ * 解析 AndroidManifest.xml 提取 applicationId + 组件声明包前缀
12
+ * 对每条 Semgrep finding 基于文件路径分类为 APP/SDK/UNKNOWN
13
+ *
14
+ * 分类优先级:
15
+ * EXACT match (appId 前缀) → APP very-high
16
+ * COMPONENT match (声明的组件前缀) → APP high
17
+ * SDK whitelist match → SDK very-high
18
+ * Nested SDK (app 包内嵌入 SDK) → SDK medium
19
+ * Fallback → UNKNOWN low
20
+ */
21
+ /** Semgrep --json 输出的单条 finding */
22
+ export interface SemgrepResult {
23
+ check_id: string;
24
+ path: string;
25
+ start: {
26
+ line: number;
27
+ col: number;
28
+ };
29
+ end?: {
30
+ line: number;
31
+ col: number;
32
+ };
33
+ extra: {
34
+ severity: string;
35
+ message: string;
36
+ metadata?: Record<string, unknown>;
37
+ lines?: string;
38
+ };
39
+ }
40
+ /** 分类后的 finding */
41
+ export interface ClassifiedFinding {
42
+ path: string;
43
+ package: string;
44
+ check_id: string;
45
+ severity: string;
46
+ line: number;
47
+ message: string;
48
+ classification: 'APP' | 'SDK' | 'UNKNOWN';
49
+ confidence: 'very-high' | 'high' | 'medium' | 'low';
50
+ source: 'exact-appid' | 'component-list' | 'sdk-whitelist' | 'nested-sdk' | 'fallback';
51
+ reason: string;
52
+ }
53
+ /** 分类统计 */
54
+ export interface ClassificationStats {
55
+ total: number;
56
+ app: number;
57
+ sdk: number;
58
+ unknown: number;
59
+ byConfidence: Record<string, number>;
60
+ bySource: Record<string, number>;
61
+ }
62
+ /**
63
+ * 从 AndroidManifest.xml 提取 applicationId (package 属性)
64
+ */
65
+ export declare function extractApplicationId(manifestPath: string): string;
66
+ /**
67
+ * 从 AndroidManifest.xml 提取所有声明的组件包前缀
68
+ *
69
+ * 解析 <activity>/<service>/<receiver>/<provider> 的 android:name 属性
70
+ * 提取其包前缀 (最后一段类名之前的包路径)
71
+ *
72
+ * 处理相对类名: 如果 android:name 以 "." 开头,拼接 applicationId
73
+ */
74
+ export declare function getComponentPackages(manifestPath: string): Set<string>;
75
+ /**
76
+ * 将 jadx 反编译文件路径转换为 Java 包名
77
+ *
78
+ * 输入: "sources/com/jxd/whj_learn/utils/AesUtils.java"
79
+ * 输出: "com.jxd.whj_learn.utils"
80
+ *
81
+ * 容错: 路径可能不含 "sources/" 前缀 (Semgrep 输出路径取决于扫描根目录)
82
+ */
83
+ export declare function pathToPackage(filePath: string): string;
84
+ /**
85
+ * 对单条 Semgrep finding 进行分类
86
+ */
87
+ export declare function classifyFinding(finding: SemgrepResult, appId: string, componentPrefixes: Set<string>): ClassifiedFinding;
88
+ /**
89
+ * 批量分类 Semgrep findings
90
+ *
91
+ * @param findings - Semgrep --json 输出的 results 数组
92
+ * @param manifestPath - jadx 输出中的 AndroidManifest.xml 路径
93
+ * @returns 带分类标签的 finding 列表
94
+ */
95
+ export declare function classifyFindings(findings: SemgrepResult[], manifestPath: string): ClassifiedFinding[];
96
+ /**
97
+ * 按分类筛选 findings
98
+ *
99
+ * @param findings - 已分类的 findings
100
+ * @param classifications - 要保留的分类列表 (e.g. ['APP', 'UNKNOWN'])
101
+ * @returns 筛选后的 findings
102
+ */
103
+ export declare function filterByClassification(findings: ClassifiedFinding[], classifications: string[]): ClassifiedFinding[];
104
+ /**
105
+ * 生成分类统计摘要
106
+ */
107
+ export declare function getClassificationStats(findings: ClassifiedFinding[]): ClassificationStats;
108
+ //# sourceMappingURL=finding_classifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding_classifier.d.ts","sourceRoot":"","sources":["../../src/engine/finding_classifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAMH,mCAAmC;AACnC,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC,GAAG,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACpC,KAAK,EAAE;QACL,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACnC,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED,mBAAmB;AACnB,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,KAAK,GAAG,KAAK,GAAG,SAAS,CAAC;IAC1C,UAAU,EAAE,WAAW,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACpD,MAAM,EAAE,aAAa,GAAG,gBAAgB,GAAG,eAAe,GAAG,YAAY,GAAG,UAAU,CAAC;IACvF,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,WAAW;AACX,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAqKD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAejE;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CA0CtE;AAID;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAmBtD;AA2CD;;GAEG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,aAAa,EACtB,KAAK,EAAE,MAAM,EACb,iBAAiB,EAAE,GAAG,CAAC,MAAM,CAAC,GAC7B,iBAAiB,CAoFnB;AAID;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,aAAa,EAAE,EACzB,YAAY,EAAE,MAAM,GACnB,iBAAiB,EAAE,CAKrB;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,iBAAiB,EAAE,EAC7B,eAAe,EAAE,MAAM,EAAE,GACxB,iBAAiB,EAAE,CAGrB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,iBAAiB,EAAE,GAAG,mBAAmB,CAwBzF"}