@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,111 @@
1
+ # CWE-915: Node.js 过度绑定/批量赋值检测规则
2
+ # 逐码 ZhuMa V4.1 Sprint 2 — JS/TS 规则库
3
+ # 覆盖: Object.assign(req.body, target)、lodash.merge、Mongoose Model(req.body)、Sequelize bulkCreate
4
+
5
+ rules:
6
+
7
+ # ZM-JS-MA-001: Object.assign / lodash.merge 将 req.body 合并到数据库对象
8
+ - id: zm-js-ma-001
9
+ severity: ERROR
10
+ message: |
11
+ Object.assign() 或 lodash.merge() 直接将 req.body / req.query / req.params
12
+ 合并或赋值给数据库模型/内部对象,攻击者可注入额外字段(如 role: "admin"、isAdmin: true)
13
+ 实现权限提升或数据篡改。
14
+
15
+ 修复:
16
+ 1. 只提取白名单字段: { username, email } = req.body; Object.assign(dbUser, { username, email })
17
+ 2. 使用 pick() 辅助函数从 req.body 提取允许字段
18
+ 3. 使用 Mongoose Schema 定义字段白名单
19
+ 4. ORM层面设置 strict: 'throw' (Mongoose) 或 fields 白名单 (Sequelize)
20
+ 5. 使用 joi / zod Schema 验证并 strip 未知字段
21
+ languages:
22
+ - javascript
23
+ - typescript
24
+ pattern-either:
25
+ - pattern: Object.assign($TARGET, $REQ.body, ...)
26
+ - pattern: Object.assign($TARGET, $REQ.query, ...)
27
+ - pattern: Object.assign($TARGET, $REQ.params, ...)
28
+ - pattern: lodash.merge($TARGET, $REQ.body, ...)
29
+ - pattern: lodash.merge($TARGET, $REQ.query, ...)
30
+ - pattern: lodash.merge($TARGET, $REQ.params, ...)
31
+ - pattern: _.merge($TARGET, $REQ.body, ...)
32
+ - pattern: _.merge($TARGET, $REQ.query, ...)
33
+ - pattern: _.merge($TARGET, $REQ.params, ...)
34
+ - pattern: _.assign($TARGET, $REQ.body, ...)
35
+ - pattern: _.assign($TARGET, $REQ.query, ...)
36
+ - pattern: _.assign($TARGET, $REQ.params, ...)
37
+ - pattern: _.defaults($TARGET, $REQ.body, ...)
38
+ - pattern: _.extend($TARGET, $REQ.body, ...)
39
+ - pattern: $merge($TARGET, $REQ.body, ...)
40
+ metadata:
41
+ cwe: "CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes"
42
+ owasp: "A01:2021 - Broken Access Control"
43
+ category: mass-assignment
44
+ precision: high
45
+ references:
46
+ - "https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html"
47
+ - "https://mongoosejs.com/docs/guide.html#strict"
48
+
49
+ # ZM-JS-MA-002: Mongoose/Sequelize 直接传入 req.body 创建/更新 (无字段过滤)
50
+ - id: zm-js-ma-002
51
+ severity: ERROR
52
+ message: |
53
+ Mongoose Model 构造函数、create()、findByIdAndUpdate() 或 Sequelize Model.create()
54
+ 直接传入 req.body / req.query 作为参数,未过滤允许字段,存在过度绑定风险。
55
+
56
+ 攻击者可通过注入 protected 字段(如 role、credit、verified)绕过业务限制。
57
+
58
+ 修复:
59
+ 1. Mongoose: Schema 设置 { strict: true } 或 { strict: 'throw' }
60
+ 2. Mongoose 查询: 先 destructure 白名单字段再传入
61
+ 3. Sequelize: Model.create() 前使用 fields/attributes 白名单
62
+ 4. 统一中间件层做字段过滤
63
+ languages:
64
+ - javascript
65
+ - typescript
66
+ pattern-either:
67
+ - pattern: $MODEL.create($REQ.body, ...)
68
+ - pattern: $MODEL.create($REQ.query, ...)
69
+ - pattern: new $MODEL($REQ.body, ...)
70
+ - pattern: new $MODEL($REQ.query, ...)
71
+ - pattern: $MODEL.insertMany($REQ.body, ...)
72
+ - pattern: $MODEL.findByIdAndUpdate($_, $REQ.body, ...)
73
+ - pattern: $MODEL.findOneAndUpdate($_, $REQ.body, ...)
74
+ - pattern: $MODEL.updateOne($_, $REQ.body, ...)
75
+ - pattern: $MODEL.updateMany($_, $REQ.body, ...)
76
+ - pattern: $MODEL.replaceOne($_, $REQ.body, ...)
77
+ - pattern: $MODEL.bulkWrite($REQ.body, ...)
78
+ metadata:
79
+ cwe: "CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes"
80
+ owasp: "A01:2021 - Broken Access Control"
81
+ category: mass-assignment
82
+ precision: high
83
+ references:
84
+ - "https://mongoosejs.com/docs/guide.html#strict"
85
+ - "https://sequelize.org/docs/v6/core-concepts/model-basics/#data-types"
86
+
87
+ # ZM-JS-MA-003: Sequelize bulkCreate 无 fields 白名单
88
+ - id: zm-js-ma-003
89
+ severity: WARNING
90
+ message: |
91
+ Sequelize Model.bulkCreate() 接收 req.body 且可能未设置 fields 白名单。
92
+ 攻击者可批量注入额外字段,影响大量记录。
93
+
94
+ 修复:
95
+ 1. Model.bulkCreate(data, { fields: ['name', 'email'] }) 显式指定白名单
96
+ 2. 在 Controller 层做字段提取: const { name, email } = req.body
97
+ 3. 使用 Sequelize beforeBulkCreate hook 做字段验证
98
+ languages:
99
+ - javascript
100
+ - typescript
101
+ pattern-either:
102
+ - pattern: $MODEL.bulkCreate($REQ.body, ...)
103
+ - pattern: $MODEL.bulkCreate($REQ.query, ...)
104
+ - pattern: $MODEL.bulkBuild($REQ.body, ...)
105
+ metadata:
106
+ cwe: "CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes"
107
+ owasp: "A01:2021 - Broken Access Control"
108
+ category: mass-assignment
109
+ precision: medium
110
+ references:
111
+ - "https://sequelize.org/docs/v6/core-concepts/model-querying-basics/#bulkcreate"
@@ -0,0 +1,134 @@
1
+ # CWE-918: Node.js SSRF 深度覆盖 — fetch/axios/node-fetch/got 全量sink
2
+ # 逐码 ZhuMa V4.1 Sprint — JS/TS 规则库
3
+ # 覆盖: fetch() / axios({url:...}) / node-fetch / got / undici 对象式请求
4
+
5
+ rules:
6
+
7
+ # ZM-JS-SSRF-FETCH-001: fetch/axios/node-fetch 直接传入用户输入URL
8
+ - id: zm-js-ssrf-fetch-001
9
+ severity: ERROR
10
+ message: |
11
+ 检测到 fetch / axios / node-fetch / got / undici.fetch 等 HTTP 客户端直接使用用户输入作为请求URL,
12
+ 存在SSRF(服务端请求伪造)风险。
13
+ 攻击者可控制目标URL使服务器发起对内网服务的恶意请求,绕过防火墙访问内部资源
14
+ (如 http://169.254.169.254/latest/meta-data/ 获取云环境元数据)。
15
+
16
+ 修复:
17
+ 1. 对用户传入的URL做白名单校验,仅允许预设的外部域名
18
+ 2. 禁止用户输入直接决定请求目标,使用URL映射表替代
19
+ 3. 使用SSRF保护库(如 ssrf-filter / safe-request)
20
+ 4. 配置防火墙禁止服务器访问内网地址(169.254.0.0/16, 10.0.0.0/8, 127.0.0.0/8等)
21
+ 5. 禁用不必要的HTTP重定向跟踪
22
+ languages:
23
+ - javascript
24
+ - typescript
25
+ pattern-either:
26
+ # fetch()
27
+ - pattern: fetch($REQ.query.$PARAM, ...)
28
+ - pattern: fetch($REQ.params.$PARAM, ...)
29
+ - pattern: fetch($REQ.body.$PARAM, ...)
30
+ # node-fetch
31
+ - pattern: nodeFetch($REQ.query.$PARAM, ...)
32
+ - pattern: nodeFetch($REQ.params.$PARAM, ...)
33
+ - pattern: nodeFetch($REQ.body.$PARAM, ...)
34
+ # axios object-style
35
+ - pattern: |
36
+ axios({url: $REQ.query.$PARAM, ...})
37
+ - pattern: |
38
+ axios({url: $REQ.params.$PARAM, ...})
39
+ - pattern: |
40
+ axios({url: $REQ.body.$PARAM, ...})
41
+ - pattern: |
42
+ $AXIOS({url: $REQ.query.$PARAM, ...})
43
+ - pattern: |
44
+ $AXIOS({url: $REQ.params.$PARAM, ...})
45
+ - pattern: |
46
+ $AXIOS({url: $REQ.body.$PARAM, ...})
47
+ # got object-style
48
+ - pattern: |
49
+ got({url: $REQ.query.$PARAM, ...})
50
+ - pattern: |
51
+ got({url: $REQ.params.$PARAM, ...})
52
+ - pattern: |
53
+ got({url: $REQ.body.$PARAM, ...})
54
+ # undici.fetch
55
+ - pattern: undici.fetch($REQ.query.$PARAM, ...)
56
+ - pattern: undici.fetch($REQ.params.$PARAM, ...)
57
+ - pattern: undici.fetch($REQ.body.$PARAM, ...)
58
+ metadata:
59
+ cwe: "CWE-918: Server-Side Request Forgery (SSRF)"
60
+ owasp: "A10:2021 - Server-Side Request Forgery (SSRF)"
61
+ category: ssrf
62
+ precision: high
63
+ confidence: high
64
+ references:
65
+ - "https://owasp.org/www-community/attacks/Server_Side_Request_Forgery"
66
+ - "https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html"
67
+
68
+ # ZM-JS-SSRF-FETCH-002: 用户输入拼接URL后传入fetch/axios
69
+ - id: zm-js-ssrf-fetch-002
70
+ severity: WARNING
71
+ message: |
72
+ fetch / axios 请求URL由用户输入拼接构造,需确认拼接变量是否可直接控制完整URL。
73
+ 若用户可控制协议+域名部分(如 http://evil.com ),存在SSRF风险。
74
+
75
+ 修复:
76
+ 1. 使用 new URL() 解析目标并验证 hostname 白名单
77
+ 2. 使用URL映射表(key->URL)替代直接拼接
78
+ 3. 限制协议仅允许 https
79
+ 4. 使用SSRF防护库过滤内网IP
80
+ languages:
81
+ - javascript
82
+ - typescript
83
+ pattern-either:
84
+ - pattern: fetch($URL + $INPUT, ...)
85
+ - pattern: nodeFetch($URL + $INPUT, ...)
86
+ - pattern: |
87
+ axios({url: $URL + $INPUT, ...})
88
+ - pattern: got($URL + $INPUT, ...)
89
+ - pattern: undici.fetch($URL + $INPUT, ...)
90
+ metadata:
91
+ cwe: "CWE-918: Server-Side Request Forgery (SSRF)"
92
+ owasp: "A10:2021 - Server-Side Request Forgery (SSRF)"
93
+ category: ssrf
94
+ precision: low
95
+ confidence: medium
96
+ references:
97
+ - "https://owasp.org/www-community/attacks/Server_Side_Request_Forgery"
98
+
99
+ # ZM-JS-SSRF-FETCH-003: got.stream / needle / superagent 对象式URL注入
100
+ - id: zm-js-ssrf-fetch-003
101
+ severity: ERROR
102
+ message: |
103
+ got / superagent / needle 等 HTTP 库的对象式请求中,hostname/href/uri 字段由用户输入控制,
104
+ 可导致SSRF攻击。
105
+
106
+ 修复:
107
+ 1. 白名单限制目标域名
108
+ 2. 使用固定的baseURL + 相对路径模式
109
+ 3. 禁止用户输入覆盖hostname/href/uri字段
110
+ languages:
111
+ - javascript
112
+ - typescript
113
+ pattern-either:
114
+ - pattern: "got({hostname: $REQ.query.$PARAM})"
115
+ - pattern: "got({hostname: $REQ.params.$PARAM})"
116
+ - pattern: "got({hostname: $REQ.body.$PARAM})"
117
+ - pattern: "got({href: $REQ.query.$PARAM})"
118
+ - pattern: "got({href: $REQ.params.$PARAM})"
119
+ - pattern: "got({uri: $REQ.query.$PARAM})"
120
+ - pattern: "got({uri: $REQ.params.$PARAM})"
121
+ - pattern: superagent($METHOD, $REQ.query.$PARAM)
122
+ - pattern: superagent($METHOD, $REQ.params.$PARAM)
123
+ - pattern: superagent($METHOD, $REQ.body.$PARAM)
124
+ - pattern: needle($METHOD, $REQ.query.$PARAM, ...)
125
+ - pattern: needle($METHOD, $REQ.params.$PARAM, ...)
126
+ - pattern: needle($METHOD, $REQ.body.$PARAM, ...)
127
+ metadata:
128
+ cwe: "CWE-918: Server-Side Request Forgery (SSRF)"
129
+ owasp: "A10:2021 - Server-Side Request Forgery (SSRF)"
130
+ category: ssrf
131
+ precision: high
132
+ confidence: high
133
+ references:
134
+ - "https://owasp.org/www-community/attacks/Server_Side_Request_Forgery"
@@ -0,0 +1,132 @@
1
+ # CWE-918: Node.js SSRF 服务端请求伪造检测规则
2
+ # 逐码 ZhuMa V4.1 Sprint 2 — JS/TS 规则库
3
+ # 覆盖: http/https native、axios、fetch/node-fetch、got、superagent、needle、undici
4
+
5
+ rules:
6
+
7
+ # ZM-JS-SSRF-001: HTTP库直接传入 req.query/params/body 作为URL (高精度)
8
+ - id: zm-js-ssrf-001
9
+ severity: ERROR
10
+ message: |
11
+ HTTP请求库直接将 req.query / req.params / req.body 的值作为URL参数传入,
12
+ 存在SSRF(服务端请求伪造)风险。
13
+
14
+ 攻击者可控制目标URL使服务器发起对内网服务的恶意请求,绕过防火墙访问内部资源
15
+ (如 http://169.254.169.254/latest/meta-data/ 获取云环境元数据)。
16
+
17
+ 修复:
18
+ 1. 对用户传入的URL做白名单校验,仅允许预设的外部域名
19
+ 2. 禁止用户输入直接决定请求目标,使用URL映射表替代
20
+ 3. 使用SSRF保护库(如 ssrf-filter / safe-request)
21
+ 4. 配置防火墙禁止服务器访问内网地址(169.254.0.0/16, 10.0.0.0/8, 127.0.0.0/8等)
22
+ 5. 禁用不必要的HTTP重定向跟随
23
+ languages:
24
+ - javascript
25
+ - typescript
26
+ pattern-either:
27
+ # Native http/https
28
+ - pattern: http.get($REQ.query.$PARAM, ...)
29
+ - pattern: http.get($REQ.params.$PARAM, ...)
30
+ - pattern: http.get($REQ.body.$PARAM, ...)
31
+ - pattern: http.request($REQ.query.$PARAM, ...)
32
+ - pattern: http.request($REQ.params.$PARAM, ...)
33
+ - pattern: http.request($REQ.body.$PARAM, ...)
34
+ - pattern: https.get($REQ.query.$PARAM, ...)
35
+ - pattern: https.get($REQ.params.$PARAM, ...)
36
+ - pattern: https.get($REQ.body.$PARAM, ...)
37
+ - pattern: https.request($REQ.query.$PARAM, ...)
38
+ - pattern: https.request($REQ.params.$PARAM, ...)
39
+ - pattern: https.request($REQ.body.$PARAM, ...)
40
+ # axios
41
+ - pattern: axios.get($REQ.query.$PARAM, ...)
42
+ - pattern: axios.get($REQ.params.$PARAM, ...)
43
+ - pattern: axios.get($REQ.body.$PARAM, ...)
44
+ - pattern: axios.request($REQ.query.$PARAM, ...)
45
+ - pattern: axios.request($REQ.params.$PARAM, ...)
46
+ - pattern: axios.request($REQ.body.$PARAM, ...)
47
+ - pattern: $AXIOS.get($REQ.query.$PARAM, ...)
48
+ - pattern: $AXIOS.get($REQ.params.$PARAM, ...)
49
+ - pattern: $AXIOS.get($REQ.body.$PARAM, ...)
50
+ - pattern: $AXIOS.request($REQ.query.$PARAM, ...)
51
+ - pattern: $AXIOS.request($REQ.params.$PARAM, ...)
52
+ - pattern: $AXIOS.request($REQ.body.$PARAM, ...)
53
+ - pattern: $AXIOS.post($REQ.query.$PARAM, ...)
54
+ - pattern: $AXIOS.put($REQ.query.$PARAM, ...)
55
+ - pattern: $AXIOS.delete($REQ.query.$PARAM, ...)
56
+ # fetch / node-fetch
57
+ - pattern: fetch($REQ.query.$PARAM, ...)
58
+ - pattern: fetch($REQ.params.$PARAM, ...)
59
+ - pattern: fetch($REQ.body.$PARAM, ...)
60
+ # got
61
+ - pattern: got($REQ.query.$PARAM, ...)
62
+ - pattern: got($REQ.params.$PARAM, ...)
63
+ - pattern: got($REQ.body.$PARAM, ...)
64
+ - pattern: got.get($REQ.query.$PARAM, ...)
65
+ - pattern: got.get($REQ.params.$PARAM, ...)
66
+ - pattern: got.get($REQ.body.$PARAM, ...)
67
+ - pattern: got.post($REQ.query.$PARAM, ...)
68
+ - pattern: got.put($REQ.query.$PARAM, ...)
69
+ # superagent
70
+ - pattern: superagent.get($REQ.query.$PARAM)
71
+ - pattern: superagent.get($REQ.params.$PARAM)
72
+ - pattern: superagent.get($REQ.body.$PARAM)
73
+ - pattern: request.get($REQ.query.$PARAM)
74
+ - pattern: request.get($REQ.params.$PARAM)
75
+ - pattern: request.get($REQ.body.$PARAM)
76
+ # needle
77
+ - pattern: needle.get($REQ.query.$PARAM, ...)
78
+ - pattern: needle.get($REQ.params.$PARAM, ...)
79
+ - pattern: needle.get($REQ.body.$PARAM, ...)
80
+ - pattern: needle.request('get', $REQ.query.$PARAM, ...)
81
+ - pattern: needle.request('get', $REQ.params.$PARAM, ...)
82
+ - pattern: needle.request('get', $REQ.body.$PARAM, ...)
83
+ # undici
84
+ - pattern: undici.request($REQ.query.$PARAM, ...)
85
+ - pattern: undici.request($REQ.params.$PARAM, ...)
86
+ - pattern: undici.request($REQ.body.$PARAM, ...)
87
+ - pattern: undici.fetch($REQ.query.$PARAM, ...)
88
+ - pattern: undici.fetch($REQ.params.$PARAM, ...)
89
+ - pattern: undici.fetch($REQ.body.$PARAM, ...)
90
+ metadata:
91
+ cwe: "CWE-918: Server-Side Request Forgery (SSRF)"
92
+ owasp: "A10:2021 - Server-Side Request Forgery (SSRF)"
93
+ category: ssrf
94
+ precision: high
95
+ references:
96
+ - "https://owasp.org/www-community/attacks/Server_Side_Request_Forgery"
97
+ - "https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html"
98
+
99
+ # ZM-JS-SSRF-002: HTTP库URL字符串拼接 (低精度,需人工确认)
100
+ - id: zm-js-ssrf-002
101
+ severity: WARNING
102
+ message: |
103
+ HTTP请求库使用了字符串拼接或模板字符串构建请求URL,需确认拼接变量是否来自用户输入。
104
+ 若变量可控则存在SSRF风险。
105
+
106
+ 修复:
107
+ 1. 使用 new URL() 解析目标并验证 hostname 白名单
108
+ 2. 使用URL映射表(key->URL)替代直接拼接
109
+ 3. 使用SSRF防护库过滤内网IP
110
+ languages:
111
+ - javascript
112
+ - typescript
113
+ pattern-either:
114
+ - pattern: http.get($URL + $INPUT, ...)
115
+ - pattern: http.request($URL + $INPUT, ...)
116
+ - pattern: https.get($URL + $INPUT, ...)
117
+ - pattern: https.request($URL + $INPUT, ...)
118
+ - pattern: $AXIOS.get($URL + $INPUT, ...)
119
+ - pattern: $AXIOS.request($URL + $INPUT, ...)
120
+ - pattern: axios.get($URL + $INPUT, ...)
121
+ - pattern: fetch($URL + $INPUT, ...)
122
+ - pattern: got($URL + $INPUT, ...)
123
+ - pattern: got.get($URL + $INPUT, ...)
124
+ - pattern: superagent.get($URL + $INPUT)
125
+ - pattern: needle.get($URL + $INPUT, ...)
126
+ metadata:
127
+ cwe: "CWE-918: Server-Side Request Forgery (SSRF)"
128
+ owasp: "A10:2021 - Server-Side Request Forgery (SSRF)"
129
+ category: ssrf
130
+ precision: low
131
+ references:
132
+ - "https://owasp.org/www-community/attacks/Server_Side_Request_Forgery"
@@ -0,0 +1,130 @@
1
+ # CWE-94: Node.js 服务端模板注入 (SSTI) 深度检测
2
+ # 逐码 ZhuMa V4.1 Sprint — JS/TS 规则库
3
+ # 覆盖: EJS / Vue SSR / Pug / Handlebars / doT 模板引擎 + 用户输入渲染
4
+
5
+ rules:
6
+
7
+ # ZM-JS-SSTI-001: EJS render/renderFile 用户输入直接传入模板数据
8
+ - id: zm-js-ssti-001
9
+ severity: ERROR
10
+ message: |
11
+ 检测到 EJS 模板渲染函数(ejs.render / ejs.renderFile)的模板字符串或数据参数由用户输入控制。
12
+ 攻击者可注入 <% process.exit() %>/<%= 7*7 %>/<% require('child_process').exec('cmd') %> 等EJS标签,
13
+ 导致远程代码执行(RCE)。
14
+
15
+ 修复:
16
+ 1. 禁止用户输入直接作为模板字符串传入渲染函数
17
+ 2. 使用固定的模板文件和严格的白名单变量
18
+ 3. 开启EJS delimiter 严格模式,限制标签类型
19
+ 4. 使用沙箱环境渲染用户内容(如 vm2/isolated-vm)
20
+ 5. 评估是否需要用模板引擎处理用户数据——大多数场景不需要
21
+ languages:
22
+ - javascript
23
+ - typescript
24
+ pattern-either:
25
+ - pattern: ejs.render($REQ.query.$PARAM, ...)
26
+ - pattern: ejs.render($REQ.params.$PARAM, ...)
27
+ - pattern: ejs.render($REQ.body.$PARAM, ...)
28
+ - pattern: ejs.render($REQ.body, ...)
29
+ - pattern: ejs.renderFile($REQ.query.$PARAM, ...)
30
+ - pattern: ejs.renderFile($REQ.params.$PARAM, ...)
31
+ - pattern: ejs.renderFile($REQ.body.$PARAM, ...)
32
+ - pattern: ejs.compile($REQ.query.$PARAM, ...)
33
+ - pattern: ejs.compile($REQ.params.$PARAM, ...)
34
+ - pattern: ejs.compile($REQ.body.$PARAM, ...)
35
+ metadata:
36
+ cwe: "CWE-94: Improper Control of Generation of Code (Code Injection)"
37
+ owasp: "A03:2021 - Injection"
38
+ category: ssti
39
+ precision: high
40
+ confidence: high
41
+ references:
42
+ - "https://ejs.co/#docs"
43
+ - "https://portswigger.net/web-security/server-side-template-injection"
44
+
45
+ # ZM-JS-SSTI-002: Pug / Handlebars / Nunjucks 用户输入模板渲染
46
+ - id: zm-js-ssti-002
47
+ severity: ERROR
48
+ message: |
49
+ 检测到 Pug / Handlebars / Nunjucks 模板引擎的 compile/render 函数接收用户可控的模板字符串。
50
+ 各引擎支持自定义helper/函数调用,攻击者可注入恶意代码。
51
+
52
+ Pug: #{process.exit()} / each val in process.mainModule.require('child_process')
53
+ Handlebars: {{constructor.constructor('return process')()}}
54
+ Nunjucks: {{range.constructor('return process')().mainModule.require('child_process')}}
55
+
56
+ 修复:
57
+ 1. 禁止用户输入作为模板内容或模板路径
58
+ 2. 禁用危险的 helper/过滤器注册
59
+ 3. 对用户数据仅作为模板变量(非模板本身)传入
60
+ 4. 使用沙箱环境
61
+ languages:
62
+ - javascript
63
+ - typescript
64
+ pattern-either:
65
+ # Pug
66
+ - pattern: pug.compile($REQ.query.$PARAM, ...)
67
+ - pattern: pug.compile($REQ.params.$PARAM, ...)
68
+ - pattern: pug.compile($REQ.body.$PARAM, ...)
69
+ - pattern: pug.render($REQ.query.$PARAM, ...)
70
+ - pattern: pug.render($REQ.params.$PARAM, ...)
71
+ - pattern: pug.render($REQ.body.$PARAM, ...)
72
+ # Handlebars
73
+ - pattern: Handlebars.compile($REQ.query.$PARAM, ...)
74
+ - pattern: Handlebars.compile($REQ.params.$PARAM, ...)
75
+ - pattern: Handlebars.compile($REQ.body.$PARAM, ...)
76
+ # Nunjucks
77
+ - pattern: nunjucks.renderString($REQ.query.$PARAM, ...)
78
+ - pattern: nunjucks.renderString($REQ.params.$PARAM, ...)
79
+ - pattern: nunjucks.renderString($REQ.body.$PARAM, ...)
80
+ metadata:
81
+ cwe: "CWE-94: Improper Control of Generation of Code (Code Injection)"
82
+ owasp: "A03:2021 - Injection"
83
+ category: ssti
84
+ precision: high
85
+ confidence: high
86
+ references:
87
+ - "https://portswigger.net/web-security/server-side-template-injection"
88
+
89
+ # ZM-JS-SSTI-003: doT.js / lodash.template / mustache 模板注入
90
+ - id: zm-js-ssti-003
91
+ severity: ERROR
92
+ message: |
93
+ 检测到 doT.js / lodash.template / mustache 等轻量模板引擎的模板字符串由用户输入控制。
94
+
95
+ lodash.template 底层使用 Function() 构造函数,直接传入用户输入可导致任意代码执行。
96
+ doT.js 的 {{ }} 标签可执行 JavaScript 表达式。
97
+ mustache 虽相对安全(无逻辑标签),但仍可能被利用做信息泄露。
98
+
99
+ 修复:
100
+ 1. 禁止用户输入作为模板字符串
101
+ 2. 使用固定的预定义模板
102
+ 3. 如需动态模板,仅允许安全的占位符替换(如简单的 String.replace)
103
+ 4. 模板引擎仅用于开发阶段,生产环境避免动态编译
104
+ languages:
105
+ - javascript
106
+ - typescript
107
+ pattern-either:
108
+ - pattern: _.template($REQ.query.$PARAM, ...)
109
+ - pattern: _.template($REQ.params.$PARAM, ...)
110
+ - pattern: _.template($REQ.body.$PARAM, ...)
111
+ - pattern: lodash.template($REQ.query.$PARAM, ...)
112
+ - pattern: lodash.template($REQ.params.$PARAM, ...)
113
+ - pattern: dot.template($REQ.query.$PARAM, ...)
114
+ - pattern: dot.template($REQ.params.$PARAM, ...)
115
+ - pattern: dot.template($REQ.body.$PARAM, ...)
116
+ - pattern: Mustache.render($REQ.query.$PARAM, ...)
117
+ - pattern: Mustache.render($REQ.params.$PARAM, ...)
118
+ - pattern: Mustache.render($REQ.body.$PARAM, ...)
119
+ - pattern: mustache.render($REQ.query.$PARAM, ...)
120
+ - pattern: mustache.render($REQ.params.$PARAM, ...)
121
+ - pattern: mustache.render($REQ.body.$PARAM, ...)
122
+ metadata:
123
+ cwe: "CWE-94: Improper Control of Generation of Code (Code Injection)"
124
+ owasp: "A03:2021 - Injection"
125
+ category: ssti
126
+ precision: high
127
+ confidence: high
128
+ references:
129
+ - "https://lodash.com/docs/#template"
130
+ - "https://portswigger.net/web-security/server-side-template-injection"
@@ -0,0 +1,49 @@
1
+ # CWE-942: CORS 配置缺陷检测规则
2
+ # 逐码 ZhuMa V4.1 Sprint 1
3
+
4
+ rules:
5
+
6
+ - id: zm-js-cors-001
7
+ severity: WARNING
8
+ message: |
9
+ CORS 中间件 origin 配置为 '*' 通配符,允许任意域跨域访问 API。
10
+ 修复: 1.将origin设为白名单数组或校验函数 2.需要凭证时禁用通配符 3.尽量同域部署
11
+ languages:
12
+ - javascript
13
+ - typescript
14
+ patterns:
15
+ - pattern-either:
16
+ - pattern: 'cors({..., origin: "*", ...})'
17
+ - pattern: "cors({..., origin: '*', ...})"
18
+ - pattern: |
19
+ $APP.use(cors({..., origin: "*", ...}))
20
+ - pattern: |
21
+ $APP.use(cors({..., origin: '*', ...}))
22
+ metadata:
23
+ cwe: "CWE-942"
24
+ precision: very-high
25
+ category: config
26
+ owasp: "A05:2021 - Security Misconfiguration"
27
+
28
+ - id: zm-js-cors-002
29
+ severity: WARNING
30
+ message: |
31
+ 手动设置 Access-Control-Allow-Origin 响应头为 '*' 通配符。
32
+ 修复: 1.限制origin为受信域名列表 2.如必须使用通配符,确保接口不返回敏感数据
33
+ languages:
34
+ - javascript
35
+ - typescript
36
+ pattern-either:
37
+ - pattern: |
38
+ res.setHeader('Access-Control-Allow-Origin', '*')
39
+ - pattern: |
40
+ res.setHeader("Access-Control-Allow-Origin", "*")
41
+ - pattern: |
42
+ res.header("Access-Control-Allow-Origin", "*")
43
+ - pattern: |
44
+ res.header('Access-Control-Allow-Origin', '*')
45
+ metadata:
46
+ cwe: "CWE-942"
47
+ precision: very-high
48
+ category: config
49
+ owasp: "A05:2021 - Security Misconfiguration"
@@ -0,0 +1,52 @@
1
+ # CWE-943: Node.js NoSQL 注入检测规则
2
+ # 逐码 ZhuMa V4.1 Sprint 1 — JS/TS 通用规则库
3
+
4
+ rules:
5
+
6
+ # ZM-JS-NSQLI-001: MongoDB find/findOne 直接传入请求体
7
+ - id: zm-js-nosqli-001
8
+ severity: ERROR
9
+ message: |
10
+ 检测到 MongoDB find() / findOne() / updateMany() 直接接收 req.body 或 req.query
11
+ 作为查询条件,存在 NoSQL 注入风险。
12
+
13
+ 攻击者可通过注入 $gt / $ne / $regex 等 MongoDB 操作符绕过认证逻辑,
14
+ 例如: { username: { $gt: "" }, password: { $gt: "" } } 可绕过登录。
15
+
16
+ 修复建议:
17
+ 1. 使用 mongo-sanitize 或 express-mongo-sanitize 库过滤 $ 和 . 字符
18
+ 2. 对用户输入做严格的类型校验(如只允许字符串,拒绝对象)
19
+ 3. 使用 joi / zod 等 Schema 验证库,禁止传入嵌套对象
20
+ 4. 认证场景使用 bcrypt.compare 而非直接查询
21
+ languages:
22
+ - javascript
23
+ - typescript
24
+ pattern-either:
25
+ - pattern: |
26
+ $COLLECTION.find($REQ.body, ...)
27
+ - pattern: |
28
+ $COLLECTION.findOne($REQ.body, ...)
29
+ - pattern: |
30
+ $COLLECTION.find($REQ.body)
31
+ - pattern: |
32
+ $COLLECTION.findOne($REQ.body)
33
+ - pattern: |
34
+ $COLLECTION.find($REQ.query, ...)
35
+ - pattern: |
36
+ $COLLECTION.findOne($REQ.query, ...)
37
+ - pattern: |
38
+ $COLLECTION.updateMany($REQ.body, ...)
39
+ - pattern: |
40
+ $COLLECTION.updateOne($REQ.body, ...)
41
+ - pattern: |
42
+ $COLLECTION.deleteMany($REQ.body, ...)
43
+ - pattern: |
44
+ $COLLECTION.deleteOne($REQ.body, ...)
45
+ metadata:
46
+ cwe: "CWE-943: Improper Neutralization of Special Elements in Data Query Logic"
47
+ owasp: "A03:2021 - Injection"
48
+ category: sql-injection
49
+ precision: medium
50
+ references:
51
+ - "https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/07-Input_Validation_Testing/05.6-Testing_for_NoSQL_Injection"
52
+ - "https://www.mongodb.com/docs/manual/faq/fundamentals/#javascript"
@@ -0,0 +1,59 @@
1
+ # CWE-95: eval() 代码注入检测规则
2
+ # 逐码 ZhuMa V4.1 Sprint 1 — JS/TS 通用规则库
3
+
4
+ rules:
5
+
6
+ # ZM-JS-CI-001: eval() 动态代码执行
7
+ - id: zm-js-ci-001
8
+ severity: ERROR
9
+ message: |
10
+ 检测到 eval() 调用,参数为非字面量字符串。
11
+ eval() 会执行传入的任意 JavaScript 代码,攻击者可注入恶意代码导致
12
+ 远程代码执行(RCE)。
13
+
14
+ 修复建议:
15
+ 1. 禁止使用 eval() 处理用户输入
16
+ 2. JSON 数据解析使用 JSON.parse() 替代
17
+ 3. 动态属性访问使用 obj[key] 替代 eval
18
+ 4. 如确实需要动态执行,使用沙箱环境(如 vm2 / isolated-vm)
19
+ languages:
20
+ - javascript
21
+ - typescript
22
+ patterns:
23
+ - pattern: eval(...)
24
+ - pattern-not: eval("...")
25
+ metadata:
26
+ cwe: "CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')"
27
+ owasp: "A03:2021 - Injection"
28
+ category: code-injection
29
+ precision: high
30
+ references:
31
+ - "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval"
32
+ - "https://owasp.org/www-community/attacks/Code_Injection"
33
+
34
+ # ZM-JS-CI-002: 间接 eval 调用 (通过 globalThis / (0, eval))
35
+ - id: zm-js-ci-002
36
+ severity: ERROR
37
+ message: |
38
+ 检测到间接 eval() 调用(如 globalThis.eval / global.eval / (0, eval)),
39
+ 可能被用于绕过静态检测工具。
40
+
41
+ 修复建议:
42
+ 1. 移除所有 eval 调用,包括间接调用形式
43
+ 2. 替代方案: Function 构造器(仍有风险)、沙箱执行或重新设计逻辑
44
+ languages:
45
+ - javascript
46
+ - typescript
47
+ pattern-either:
48
+ - pattern: globalThis.eval(...)
49
+ - pattern: global.eval(...)
50
+ - pattern: (0, eval)(...)
51
+ - pattern: (1, eval)(...)
52
+ - pattern: window.eval(...)
53
+ metadata:
54
+ cwe: "CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')"
55
+ owasp: "A03:2021 - Injection"
56
+ category: code-injection
57
+ precision: high
58
+ references:
59
+ - "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#direct_and_indirect_eval"