@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.
- package/README.md +42 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +18 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +11 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/scan.d.ts +3 -0
- package/dist/commands/scan.d.ts.map +1 -0
- package/dist/commands/scan.js +96 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/commands/scan_appid.d.ts +20 -0
- package/dist/commands/scan_appid.d.ts.map +1 -0
- package/dist/commands/scan_appid.js +301 -0
- package/dist/commands/scan_appid.js.map +1 -0
- package/dist/commands/scan_manifest.d.ts +13 -0
- package/dist/commands/scan_manifest.d.ts.map +1 -0
- package/dist/commands/scan_manifest.js +103 -0
- package/dist/commands/scan_manifest.js.map +1 -0
- package/dist/engine/api-submit.d.ts +16 -0
- package/dist/engine/api-submit.d.ts.map +1 -0
- package/dist/engine/api-submit.js +66 -0
- package/dist/engine/api-submit.js.map +1 -0
- package/dist/engine/batch_scan.d.ts +36 -0
- package/dist/engine/batch_scan.d.ts.map +1 -0
- package/dist/engine/batch_scan.js +192 -0
- package/dist/engine/batch_scan.js.map +1 -0
- package/dist/engine/config.d.ts +12 -0
- package/dist/engine/config.d.ts.map +1 -0
- package/dist/engine/config.js +27 -0
- package/dist/engine/config.js.map +1 -0
- package/dist/engine/errors.d.ts +36 -0
- package/dist/engine/errors.d.ts.map +1 -0
- package/dist/engine/errors.js +99 -0
- package/dist/engine/errors.js.map +1 -0
- package/dist/engine/filter.d.ts +13 -0
- package/dist/engine/filter.d.ts.map +1 -0
- package/dist/engine/filter.js +64 -0
- package/dist/engine/filter.js.map +1 -0
- package/dist/engine/finding_classifier.d.ts +108 -0
- package/dist/engine/finding_classifier.d.ts.map +1 -0
- package/dist/engine/finding_classifier.js +440 -0
- package/dist/engine/finding_classifier.js.map +1 -0
- package/dist/engine/incremental/engine.d.ts +25 -0
- package/dist/engine/incremental/engine.d.ts.map +1 -0
- package/dist/engine/incremental/engine.js +337 -0
- package/dist/engine/incremental/engine.js.map +1 -0
- package/dist/engine/incremental/git-diff.d.ts +19 -0
- package/dist/engine/incremental/git-diff.d.ts.map +1 -0
- package/dist/engine/incremental/git-diff.js +175 -0
- package/dist/engine/incremental/git-diff.js.map +1 -0
- package/dist/engine/incremental/types.d.ts +33 -0
- package/dist/engine/incremental/types.d.ts.map +1 -0
- package/dist/engine/incremental/types.js +11 -0
- package/dist/engine/incremental/types.js.map +1 -0
- package/dist/engine/manifest_scanner.d.ts +48 -0
- package/dist/engine/manifest_scanner.d.ts.map +1 -0
- package/dist/engine/manifest_scanner.js +599 -0
- package/dist/engine/manifest_scanner.js.map +1 -0
- package/dist/engine/project.d.ts +22 -0
- package/dist/engine/project.d.ts.map +1 -0
- package/dist/engine/project.js +279 -0
- package/dist/engine/project.js.map +1 -0
- package/dist/engine/sarif.d.ts +13 -0
- package/dist/engine/sarif.d.ts.map +1 -0
- package/dist/engine/sarif.js +44 -0
- package/dist/engine/sarif.js.map +1 -0
- package/dist/engine/sca-integration.d.ts +36 -0
- package/dist/engine/sca-integration.d.ts.map +1 -0
- package/dist/engine/sca-integration.js +91 -0
- package/dist/engine/sca-integration.js.map +1 -0
- package/dist/engine/scanner.d.ts +18 -0
- package/dist/engine/scanner.d.ts.map +1 -0
- package/dist/engine/scanner.js +138 -0
- package/dist/engine/scanner.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +41 -0
- package/dist/index.js.map +1 -0
- package/dist/report/render.d.ts +23 -0
- package/dist/report/render.d.ts.map +1 -0
- package/dist/report/render.js +335 -0
- package/dist/report/render.js.map +1 -0
- package/package.json +41 -0
- package/rules/android/mobile-cleartext-traffic.yaml +46 -0
- package/rules/android/mobile-component-security.yaml +107 -0
- package/rules/android/mobile-crypto-weakness.yaml +139 -0
- package/rules/android/mobile-cwe-1021-tapjacking.yaml +81 -0
- package/rules/android/mobile-cwe-114-dynamic-dex-loading.yaml +41 -0
- package/rules/android/mobile-cwe-200-clipboard-data-leak.yaml +66 -0
- package/rules/android/mobile-cwe-200-debug-builds.yaml +111 -0
- package/rules/android/mobile-cwe-200-log-sensitive-data.yaml +61 -0
- package/rules/android/mobile-cwe-200-webview-debugging.yaml +56 -0
- package/rules/android/mobile-cwe-200-webview-universal-access.yaml +30 -0
- package/rules/android/mobile-cwe-200-window-flags.yaml +96 -0
- package/rules/android/mobile-cwe-22-content-provider-openfile.yaml +73 -0
- package/rules/android/mobile-cwe-22-path-traversal.yaml +86 -0
- package/rules/android/mobile-cwe-287-biometric-weakness.yaml +102 -0
- package/rules/android/mobile-cwe-295-cert-pinning-missing.yaml +78 -0
- package/rules/android/mobile-cwe-295-webview-ssl-bypass.yaml +104 -0
- package/rules/android/mobile-cwe-312-cleartext-storage.yaml +109 -0
- package/rules/android/mobile-cwe-319-cleartext-communication.yaml +84 -0
- package/rules/android/mobile-cwe-321-hardcoded-crypto-keys.yaml +132 -0
- package/rules/android/mobile-cwe-326-short-rsa.yaml +108 -0
- package/rules/android/mobile-cwe-327-rc4-3des.yaml +107 -0
- package/rules/android/mobile-cwe-329-cbc-padding-oracle.yaml +76 -0
- package/rules/android/mobile-cwe-470-reflection-injection.yaml +39 -0
- package/rules/android/mobile-cwe-489-root-detection-weak.yaml +125 -0
- package/rules/android/mobile-cwe-489-stetho-debug.yaml +107 -0
- package/rules/android/mobile-cwe-502-insecure-deserialization.yaml +76 -0
- package/rules/android/mobile-cwe-552-world-readable-files.yaml +63 -0
- package/rules/android/mobile-cwe-749-webview-java-objects.yaml +78 -0
- package/rules/android/mobile-cwe-749-webview-jsbridge.yaml +57 -0
- package/rules/android/mobile-cwe-749-webview-loadurl-injection.yaml +80 -0
- package/rules/android/mobile-cwe-78-command-injection.yaml +77 -0
- package/rules/android/mobile-cwe-780-rsa-no-oaep.yaml +80 -0
- package/rules/android/mobile-cwe-79-webview-setdata.yaml +78 -0
- package/rules/android/mobile-cwe-79-webview-xss.yaml +65 -0
- package/rules/android/mobile-cwe-798-hardcoded-credentials.yaml +108 -0
- package/rules/android/mobile-cwe-89-sql-injection.yaml +100 -0
- package/rules/android/mobile-cwe-927-implicit-intent.yaml +121 -0
- package/rules/android/mobile-cwe-927-ipc-file-provider.yaml +102 -0
- package/rules/android/mobile-cwe-939-deeplink-validation.yaml +76 -0
- package/rules/android/mobile-sdk-google-firebase-open.yaml +117 -0
- package/rules/android/mobile-sdk-tencent-tpns-config-leak.yaml +131 -0
- package/rules/android/mobile-secrets-storage.yaml +136 -0
- package/rules/android/mobile-webview-security.yaml +88 -0
- package/rules/common/cwe-200-sensitive-data-exposure.yaml +61 -0
- package/rules/common/cwe-22-path-traversal.yaml +47 -0
- package/rules/common/cwe-295-ssl-bypass.yaml +217 -0
- package/rules/common/cwe-295-ssl-verification-disabled.yaml +64 -0
- package/rules/common/cwe-306-missing-authentication.yaml +44 -0
- package/rules/common/cwe-326-weak-key-size.yaml +107 -0
- package/rules/common/cwe-327-weak-crypto.yaml +177 -0
- package/rules/common/cwe-328-weak-hash.yaml +96 -0
- package/rules/common/cwe-329-cbc-mode.yaml +26 -0
- package/rules/common/cwe-352-csrf.yaml +23 -0
- package/rules/common/cwe-434-unrestricted-file-upload.yaml +41 -0
- package/rules/common/cwe-502-insecure-deserialization.yaml +44 -0
- package/rules/common/cwe-601-url-redirect.yaml +110 -0
- package/rules/common/cwe-611-xxe.yaml +70 -0
- package/rules/common/cwe-732-incorrect-permission.yaml +49 -0
- package/rules/common/cwe-770-resource-exhaustion.yaml +44 -0
- package/rules/common/cwe-78-os-command-injection.yaml +43 -0
- package/rules/common/cwe-787-out-of-bounds-write.yaml +37 -0
- package/rules/common/cwe-79-xss.yaml +51 -0
- package/rules/common/cwe-862-missing-authorization.yaml +40 -0
- package/rules/common/cwe-89-sqli.yaml +89 -0
- package/rules/common/cwe-918-ssrf.yaml +45 -0
- package/rules/common/cwe-94-code-injection.yaml +59 -0
- package/rules/common/zm-go-cwe22-path-traversal-fs.yaml +117 -0
- package/rules/common/zm-go-cwe22-path-traversal.yaml +103 -0
- package/rules/common/zm-go-cwe307-brute-force.yaml +129 -0
- package/rules/common/zm-go-cwe326-weak-crypto.yaml +124 -0
- package/rules/common/zm-go-cwe327-weak-cipher.yaml +152 -0
- package/rules/common/zm-go-cwe384-session-fixation.yaml +128 -0
- package/rules/common/zm-go-cwe502-deserialization.yaml +120 -0
- package/rules/common/zm-go-cwe78-command-injection.yaml +95 -0
- package/rules/common/zm-go-cwe79-xss.yaml +104 -0
- package/rules/common/zm-go-cwe798-hardcoded-creds.yaml +153 -0
- package/rules/common/zm-go-cwe89-sqli.yaml +89 -0
- package/rules/common/zm-go-cwe918-ssrf.yaml +117 -0
- package/rules/common/zm-java-cwe117-log-injection.yaml +83 -0
- package/rules/common/zm-java-cwe117-logforging.yaml +153 -0
- package/rules/common/zm-java-cwe200-actuator-exposure.yaml +8 -0
- package/rules/common/zm-java-cwe200-info-disclosure.yaml +91 -0
- package/rules/common/zm-java-cwe22-file-depth.yaml +135 -0
- package/rules/common/zm-java-cwe22-path-traversal-spring.yaml +81 -0
- package/rules/common/zm-java-cwe284-missing-auth-spring.yaml +131 -0
- package/rules/common/zm-java-cwe295-webview-ssl.yaml +123 -0
- package/rules/common/zm-java-cwe327-weakcrypto.yaml +197 -0
- package/rules/common/zm-java-cwe347-jwt.yaml +30 -0
- package/rules/common/zm-java-cwe352-csrf-depth.yaml +107 -0
- package/rules/common/zm-java-cwe352-csrf-disabled.yaml +15 -0
- package/rules/common/zm-java-cwe501-trust-boundary.yaml +124 -0
- package/rules/common/zm-java-cwe502-deserial-depth.yaml +128 -0
- package/rules/common/zm-java-cwe502-fastjson.yaml +137 -0
- package/rules/common/zm-java-cwe502-gadget.yaml +158 -0
- package/rules/common/zm-java-cwe502-jndi-injection.yaml +91 -0
- package/rules/common/zm-java-cwe502-shiro.yaml +108 -0
- package/rules/common/zm-java-cwe601-url-redirect-spring.yaml +85 -0
- package/rules/common/zm-java-cwe611-xxe-enhanced.yaml +80 -0
- package/rules/common/zm-java-cwe611-xxe-transformer.yaml +85 -0
- package/rules/common/zm-java-cwe639-idor.yaml +123 -0
- package/rules/common/zm-java-cwe79-xss-depth.yaml +98 -0
- package/rules/common/zm-java-cwe862-authz-depth.yaml +127 -0
- package/rules/common/zm-java-cwe915-mass-assignment.yaml +16 -0
- package/rules/common/zm-java-cwe917-expression-injection.yaml +120 -0
- package/rules/common/zm-java-cwe918-resttemplate.yaml +67 -0
- package/rules/common/zm-java-cwe918-ssrf-depth.yaml +103 -0
- package/rules/common/zm-java-cwe918-ssrf-resttemplate.yaml +77 -0
- package/rules/common/zm-java-cwe918-webclient.yaml +44 -0
- package/rules/common/zm-java-cwe94-ognl.yaml +66 -0
- package/rules/common/zm-java-cwe94-spel-injection.yaml +85 -0
- package/rules/common/zm-java-cwe94-spel.yaml +112 -0
- package/rules/common/zm-java-cwe94-ssti.yaml +22 -0
- package/rules/common/zm-java-cwe942-cors.yaml +15 -0
- package/rules/common/zm-js-cwe1321-prototype-pollution.yaml +61 -0
- package/rules/common/zm-js-cwe200-info-disclosure.yaml +95 -0
- package/rules/common/zm-js-cwe22-path-traversal-fs.yaml +113 -0
- package/rules/common/zm-js-cwe22-pathtraversal.yaml +111 -0
- package/rules/common/zm-js-cwe307-brute-force.yaml +136 -0
- package/rules/common/zm-js-cwe345-postmessage.yaml +75 -0
- package/rules/common/zm-js-cwe347-jwt-weak.yaml +95 -0
- package/rules/common/zm-js-cwe352-csrf.yaml +52 -0
- package/rules/common/zm-js-cwe384-session-fixation.yaml +132 -0
- package/rules/common/zm-js-cwe502-deserialization.yaml +119 -0
- package/rules/common/zm-js-cwe611-xxe.yaml +108 -0
- package/rules/common/zm-js-cwe639-idor.yaml +122 -0
- package/rules/common/zm-js-cwe693-helmet-missing.yaml +46 -0
- package/rules/common/zm-js-cwe78-exec.yaml +37 -0
- package/rules/common/zm-js-cwe78-spawn.yaml +37 -0
- package/rules/common/zm-js-cwe79-domxss.yaml +84 -0
- package/rules/common/zm-js-cwe79-react-xss.yaml +18 -0
- package/rules/common/zm-js-cwe79-xss-ejs.yaml +70 -0
- package/rules/common/zm-js-cwe89-sqli.yaml +153 -0
- package/rules/common/zm-js-cwe915-mass-assignment.yaml +111 -0
- package/rules/common/zm-js-cwe918-ssrf-fetch.yaml +134 -0
- package/rules/common/zm-js-cwe918-ssrf.yaml +132 -0
- package/rules/common/zm-js-cwe94-template-injection.yaml +130 -0
- package/rules/common/zm-js-cwe942-cors.yaml +49 -0
- package/rules/common/zm-js-cwe943-nosql-injection.yaml +52 -0
- package/rules/common/zm-js-cwe95-eval.yaml +59 -0
- package/rules/common/zm-js-cwe95-function-ctor.yaml +31 -0
- package/rules/common/zm-py-cwe22-path-traversal.yaml +86 -0
- package/rules/common/zm-py-cwe327-weak-crypto.yaml +103 -0
- package/rules/common/zm-py-cwe502-pickle.yaml +92 -0
- package/rules/common/zm-py-cwe611-xxe.yaml +100 -0
- package/rules/common/zm-py-cwe78-command-injection.yaml +121 -0
- package/rules/common/zm-py-cwe79-xss.yaml +123 -0
- package/rules/common/zm-py-cwe798-hardcoded-creds.yaml +86 -0
- package/rules/common/zm-py-cwe89-sqli.yaml +59 -0
- package/rules/common/zm-py-cwe918-ssrf.yaml +123 -0
- package/rules/common/zm-py-cwe94-ssti.yaml +87 -0
- package/rules/common/zm-py-cwe943-nosql-injection.yaml +123 -0
- package/rules/iac/ansible/zm-ansible-cwe269-privilege-escalation.yaml +63 -0
- package/rules/iac/ansible/zm-ansible-cwe78-command-injection.yaml +67 -0
- package/rules/iac/ansible/zm-ansible-cwe798-hardcoded-creds.yaml +93 -0
- package/rules/iac/terraform/zm-tf-cwe200-s3-bucket-public.yaml +100 -0
- package/rules/iac/terraform/zm-tf-cwe284-sg-wide-open.yaml +88 -0
- package/rules/iac/terraform/zm-tf-cwe311-iam-wildcard.yaml +83 -0
- package/rules/iac/terraform/zm-tf-cwe319-rds-public.yaml +72 -0
- package/rules/iac/terraform/zm-tf-cwe798-hardcoded-creds.yaml +102 -0
- package/rules/iac/zm-docker-cwe250-root-user.yaml +50 -0
- package/rules/iac/zm-docker-cwe400-resource-limit.yaml +92 -0
- package/rules/iac/zm-docker-security.yaml +104 -0
- package/rules/iac/zm-k8s-cwe200-service-account.yaml +83 -0
- package/rules/iac/zm-k8s-cwe250-privileged.yaml +56 -0
- package/rules/iac/zm-k8s-security.yaml +79 -0
- package/rules/rules_index.yaml.off +477 -0
- package/rules/semgrep-registry/anonymous-ldap-bind.yaml +34 -0
- package/rules/semgrep-registry/bad-hexa-conversion.yaml +32 -0
- package/rules/semgrep-registry/blowfish-insufficient-key-size.yaml +39 -0
- package/rules/semgrep-registry/cbc-padding-oracle.yaml +38 -0
- package/rules/semgrep-registry/command-injection-formatted-runtime-call.yaml +90 -0
- package/rules/semgrep-registry/command-injection-process-builder.yaml +148 -0
- package/rules/semgrep-registry/cookie-missing-httponly.yaml +38 -0
- package/rules/semgrep-registry/cookie-missing-secure-flag.yaml +38 -0
- package/rules/semgrep-registry/crlf-injection-logs.yaml +86 -0
- package/rules/semgrep-registry/dangerous-groovy-shell.yaml +46 -0
- package/rules/semgrep-registry/el-injection.yaml +137 -0
- package/rules/semgrep-registry/formatted-sql-string.yaml +95 -0
- package/rules/semgrep-registry/http-response-splitting.yaml +44 -0
- package/rules/semgrep-registry/index.txt +1 -0
- package/rules/semgrep-registry/insecure-smtp-connection.yaml +34 -0
- package/rules/semgrep-registry/java-reverse-shell.yaml +43 -0
- package/rules/semgrep-registry/jdbc-sql-formatted-string.yaml +120 -0
- package/rules/semgrep-registry/ldap-entry-poisoning.yaml +41 -0
- package/rules/semgrep-registry/ldap-injection.yaml +82 -0
- package/rules/semgrep-registry/md5-used-as-password.yaml +44 -0
- package/rules/semgrep-registry/object-deserialization.yaml +34 -0
- package/rules/semgrep-registry/ognl-injection.yaml +839 -0
- package/rules/semgrep-registry/overly-permissive-file-permission.yaml +49 -0
- package/rules/semgrep-registry/permissive-cors.yaml +77 -0
- package/rules/semgrep-registry/script-engine-injection.yaml +66 -0
- package/rules/semgrep-registry/tainted-cmd-from-http-request.yaml +74 -0
- package/rules/semgrep-registry/tainted-env-from-http-request.yaml +46 -0
- package/rules/semgrep-registry/tainted-ldapi-from-http-request.yaml +42 -0
- package/rules/semgrep-registry/tainted-session-from-http-request.yaml +70 -0
- package/rules/semgrep-registry/tainted-xpath-from-http-request.yaml +38 -0
- package/rules/semgrep-registry/unsafe-reflection.yaml +39 -0
- package/rules/semgrep-registry/unvalidated-redirect.yaml +127 -0
- package/rules/semgrep-registry/url-rewriting.yaml +82 -0
- package/rules/semgrep-registry/weak-ssl-context.yaml +34 -0
- package/rules/semgrep-registry/xml-decoder.yaml +53 -0
- package/rules/semgrep-registry/xssrequestwrapper-is-insecure.yaml +40 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# CWE-352: Java CSRF 深度检测
|
|
2
|
+
# 逐码 ZhuMa V4.1 Sprint — Java 规则库
|
|
3
|
+
# 覆盖: CSRF令牌缺失+SameSite未设+自定义Filter未校验Referer
|
|
4
|
+
|
|
5
|
+
rules:
|
|
6
|
+
|
|
7
|
+
# ZM-JAVA-CSRF-DEPTH-001: CSRF Token 缺失检测
|
|
8
|
+
- id: zm-java-csrf-depth-001
|
|
9
|
+
severity: WARNING
|
|
10
|
+
message: |
|
|
11
|
+
检测到 Spring Security 配置中 CSRF 保护被禁用(csrf().disable()),
|
|
12
|
+
同时未发现自定义 CSRF Filter 或 SameSite Cookie 设置。
|
|
13
|
+
攻击者可利用跨站请求伪造执行未授权操作(修改密码、转账等)。
|
|
14
|
+
|
|
15
|
+
修复:
|
|
16
|
+
1. 移除 .csrf().disable() 使用 Spring Security 默认 CSRF 保护
|
|
17
|
+
2. 如为 REST API(无Cookie认证),确认使用 Bearer Token/JWT 认证后 CSRF 不适用
|
|
18
|
+
3. 设置 Cookie SameSite=Strict/Lax 作为额外防护
|
|
19
|
+
4. 添加 X-XSRF-TOKEN header 校验
|
|
20
|
+
languages:
|
|
21
|
+
- java
|
|
22
|
+
patterns:
|
|
23
|
+
- pattern-either:
|
|
24
|
+
- pattern: $SEC.http.csrf($X).disable()
|
|
25
|
+
- pattern: http.csrf($X).disable()
|
|
26
|
+
- pattern: $HTTP.csrf($X).disable()
|
|
27
|
+
metadata:
|
|
28
|
+
cwe: "CWE-352: Cross-Site Request Forgery (CSRF)"
|
|
29
|
+
severity: WARNING
|
|
30
|
+
precision: very-high
|
|
31
|
+
category: csrf
|
|
32
|
+
owasp: "A01:2021 - Broken Access Control"
|
|
33
|
+
references:
|
|
34
|
+
- "https://docs.spring.io/spring-security/reference/servlet/exploits/csrf.html"
|
|
35
|
+
|
|
36
|
+
# ZM-JAVA-CSRF-DEPTH-002: 自定义 Filter 未校验 Origin/Referer
|
|
37
|
+
- id: zm-java-csrf-depth-002
|
|
38
|
+
severity: WARNING
|
|
39
|
+
message: |
|
|
40
|
+
检测到自定义 Filter 或 OncePerRequestFilter 处理请求但未校验 Origin/Referer 头。
|
|
41
|
+
自定义 CSRF 防护 Filter 应校验请求来源,防止跨站请求伪造。
|
|
42
|
+
|
|
43
|
+
修复:
|
|
44
|
+
1. 在 doFilter 中校验 request.getHeader("Origin") 或 request.getHeader("Referer")
|
|
45
|
+
2. 白名单校验 Origin 域名
|
|
46
|
+
3. 对状态变更请求(POST/PUT/DELETE)强制校验 Origin
|
|
47
|
+
4. 使用 CorsUtils.isCorsRequest() 辅助判断
|
|
48
|
+
languages:
|
|
49
|
+
- java
|
|
50
|
+
patterns:
|
|
51
|
+
- pattern-either:
|
|
52
|
+
- pattern: |
|
|
53
|
+
public class $FILTER extends OncePerRequestFilter {
|
|
54
|
+
...
|
|
55
|
+
}
|
|
56
|
+
- pattern: |
|
|
57
|
+
public class $FILTER extends GenericFilterBean {
|
|
58
|
+
...
|
|
59
|
+
}
|
|
60
|
+
- pattern: |
|
|
61
|
+
public class $FILTER implements Filter {
|
|
62
|
+
...
|
|
63
|
+
}
|
|
64
|
+
- pattern-not: |
|
|
65
|
+
$REQ.getHeader("Origin")
|
|
66
|
+
- pattern-not: |
|
|
67
|
+
$REQ.getHeader("Referer")
|
|
68
|
+
- pattern-not: |
|
|
69
|
+
$REQ.getHeader("Sec-Fetch-Site")
|
|
70
|
+
metadata:
|
|
71
|
+
cwe: "CWE-352: Cross-Site Request Forgery (CSRF)"
|
|
72
|
+
severity: WARNING
|
|
73
|
+
precision: low
|
|
74
|
+
category: csrf
|
|
75
|
+
owasp: "A01:2021 - Broken Access Control"
|
|
76
|
+
references:
|
|
77
|
+
- "https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html"
|
|
78
|
+
|
|
79
|
+
# ZM-JAVA-CSRF-DEPTH-003: Cookie 缺少 SameSite 属性
|
|
80
|
+
- id: zm-java-csrf-depth-003
|
|
81
|
+
severity: WARNING
|
|
82
|
+
message: |
|
|
83
|
+
检测到 Servlet Cookie 或 Spring ResponseCookie 创建时未设置 SameSite 属性。
|
|
84
|
+
缺少 SameSite 属性使 Cookie 在所有跨站请求中携带,增加 CSRF 风险。
|
|
85
|
+
|
|
86
|
+
修复:
|
|
87
|
+
1. Spring: ResponseCookie.from(name, value).sameSite("Strict").build()
|
|
88
|
+
2. Servlet: 使用 setAttribute 或手动拼接 Set-Cookie header
|
|
89
|
+
3. 使用 Spring Session 的 CookieSerializer 设置:
|
|
90
|
+
cookieSerializer.setSameSite("Strict")
|
|
91
|
+
4. 生产环境同时设置 Secure=true (HTTPS only)
|
|
92
|
+
languages:
|
|
93
|
+
- java
|
|
94
|
+
pattern-either:
|
|
95
|
+
- pattern: new Cookie($NAME, $VALUE)
|
|
96
|
+
- pattern: ResponseCookie.from($NAME, $VALUE).build()
|
|
97
|
+
- pattern: $RESPONSE.addCookie($COOKIE)
|
|
98
|
+
- pattern: DefaultCookieSerializer()
|
|
99
|
+
- pattern: new DefaultCookieSerializer()
|
|
100
|
+
metadata:
|
|
101
|
+
cwe: "CWE-352: Cross-Site Request Forgery (CSRF)"
|
|
102
|
+
severity: WARNING
|
|
103
|
+
precision: low
|
|
104
|
+
category: csrf
|
|
105
|
+
owasp: "A01:2021 - Broken Access Control"
|
|
106
|
+
references:
|
|
107
|
+
- "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite"
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# CWE-352: Spring Security CSRF 禁用检测
|
|
2
|
+
rules:
|
|
3
|
+
- id: zm-java-csrf-01
|
|
4
|
+
severity: WARNING
|
|
5
|
+
message: SecurityConfig 中显式禁用 CSRF 保护(.csrf().disable()),允许跨站请求伪造攻击。
|
|
6
|
+
languages: [java]
|
|
7
|
+
pattern: $SECURITY.http.csrf().disable()
|
|
8
|
+
metadata: { cwe: "CWE-352", precision: very-high, category: config, owasp: "A01:2021 - Broken Access Control" }
|
|
9
|
+
|
|
10
|
+
- id: zm-java-csrf-02
|
|
11
|
+
severity: WARNING
|
|
12
|
+
message: SecurityFilterChain 中 csrf.disable() 禁用 CSRF 保护。
|
|
13
|
+
languages: [java]
|
|
14
|
+
pattern: http.csrf($X).disable()
|
|
15
|
+
metadata: { cwe: "CWE-352", precision: very-high, category: config, owasp: "A01:2021" }
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# CWE-501: Java 信任边界违反检测
|
|
2
|
+
# 逐码 ZhuMa V4.1 Sprint — Java 规则库
|
|
3
|
+
# 覆盖: getSession跨请求未验证、ThreadLocal存储用户数据
|
|
4
|
+
|
|
5
|
+
rules:
|
|
6
|
+
|
|
7
|
+
# ZM-JAVA-TB-001: HttpSession 跨请求信任未验证
|
|
8
|
+
- id: zm-java-tb-001
|
|
9
|
+
severity: WARNING
|
|
10
|
+
message: |
|
|
11
|
+
检测到从 HttpSession 中直接获取属性并用于后续操作,未验证属性值的有效性和完整性。
|
|
12
|
+
Session 数据虽存储在服务端,但若由客户端间接控制(如通过可控的 session ID 或反序列化),
|
|
13
|
+
攻击者可注入恶意数据。
|
|
14
|
+
|
|
15
|
+
违反信任边界的场景:
|
|
16
|
+
1. session.getAttribute("role") == "admin" → 信任客户端可控的session属性
|
|
17
|
+
2. session.getAttribute("userId") → 直接用于数据库查询(未从认证上下文重新获取)
|
|
18
|
+
3. 跨集群节点的session共享未做完整性校验
|
|
19
|
+
|
|
20
|
+
修复:
|
|
21
|
+
1. 使用认证令牌(JWT/Token)而非session属性存储权限决策
|
|
22
|
+
2. 每次关键操作前重新验证用户权限(查DB)
|
|
23
|
+
3. 对session中的敏感数据进行签名/HMAC校验
|
|
24
|
+
4. 使用 Spring Security SecurityContext 管理认证信息
|
|
25
|
+
languages:
|
|
26
|
+
- java
|
|
27
|
+
pattern-either:
|
|
28
|
+
- pattern: |
|
|
29
|
+
$SESSION.getAttribute("role")
|
|
30
|
+
- pattern: |
|
|
31
|
+
$SESSION.getAttribute("$KEY").equals("admin")
|
|
32
|
+
- pattern: |
|
|
33
|
+
$SESSION.getAttribute("$KEY").equals($ADMIN)
|
|
34
|
+
metadata:
|
|
35
|
+
cwe: "CWE-501: Trust Boundary Violation"
|
|
36
|
+
severity: WARNING
|
|
37
|
+
precision: medium
|
|
38
|
+
category: trust-boundary
|
|
39
|
+
likelihood: MEDIUM
|
|
40
|
+
impact: HIGH
|
|
41
|
+
owasp: "A04:2021 - Insecure Design"
|
|
42
|
+
references:
|
|
43
|
+
- "https://cwe.mitre.org/data/definitions/501.html"
|
|
44
|
+
|
|
45
|
+
# ZM-JAVA-TB-002: ThreadLocal 存储用户身份(跨线程污染风险)
|
|
46
|
+
- id: zm-java-tb-002
|
|
47
|
+
severity: WARNING
|
|
48
|
+
message: |
|
|
49
|
+
检测到 ThreadLocal 用于存储用户身份/会话数据。
|
|
50
|
+
ThreadLocal 的常见风险:
|
|
51
|
+
1. 线程池环境下未清理 → 后续请求继承前一个用户的ThreadLocal数据
|
|
52
|
+
2. 异步/响应式编程中线程切换 → 数据丢失或不正确
|
|
53
|
+
3. 内存泄漏 → ThreadLocal未在finally中remove()
|
|
54
|
+
|
|
55
|
+
修复:
|
|
56
|
+
1. 使用 Spring SecurityContextHolder (自动清理)
|
|
57
|
+
2. 在 finally 块中调用 threadLocal.remove()
|
|
58
|
+
3. 使用 Filter/Interceptor 在请求结束时统一清理
|
|
59
|
+
4. 考虑使用 RequestScope Bean 替代 ThreadLocal
|
|
60
|
+
5. 使用 TransmittableThreadLocal (支持线程池传递)
|
|
61
|
+
languages:
|
|
62
|
+
- java
|
|
63
|
+
pattern-either:
|
|
64
|
+
- pattern: |
|
|
65
|
+
$USER_HOLDER.set($SESSION.getAttribute($KEY))
|
|
66
|
+
- pattern: |
|
|
67
|
+
$TL.set($REQ.getSession().getAttribute($KEY))
|
|
68
|
+
- pattern: |
|
|
69
|
+
$CTX.set($USER)
|
|
70
|
+
- pattern: |
|
|
71
|
+
ThreadLocal<$TYPE> $NAME = new ThreadLocal<>();
|
|
72
|
+
- pattern: |
|
|
73
|
+
new ThreadLocal<$TYPE>()
|
|
74
|
+
- pattern: |
|
|
75
|
+
new InheritableThreadLocal()
|
|
76
|
+
metadata:
|
|
77
|
+
cwe: "CWE-501: Trust Boundary Violation"
|
|
78
|
+
severity: WARNING
|
|
79
|
+
precision: low
|
|
80
|
+
category: trust-boundary
|
|
81
|
+
likelihood: MEDIUM
|
|
82
|
+
impact: MEDIUM
|
|
83
|
+
owasp: "A04:2021 - Insecure Design"
|
|
84
|
+
references:
|
|
85
|
+
- "https://cwe.mitre.org/data/definitions/501.html"
|
|
86
|
+
|
|
87
|
+
# ZM-JAVA-TB-003: 客户端数据直接用于安全决策(trust boundary crossing)
|
|
88
|
+
- id: zm-java-tb-003
|
|
89
|
+
severity: HIGH
|
|
90
|
+
message: |
|
|
91
|
+
检测到 request.getParameter / request.getHeader 的值直接用于角色/权限判断。
|
|
92
|
+
客户端数据(请求参数/Header/Cookie)跨越信任边界进入服务端代码,
|
|
93
|
+
不应直接用于安全决策。
|
|
94
|
+
|
|
95
|
+
危险示例:
|
|
96
|
+
if ("admin".equals(request.getParameter("role"))) { ... }
|
|
97
|
+
if (request.getHeader("X-Auth-Role").equals("admin")) { ... }
|
|
98
|
+
|
|
99
|
+
修复:
|
|
100
|
+
1. 从服务端 Session/SecurityContext 获取用户角色
|
|
101
|
+
2. 从数据库重新加载用户权限信息
|
|
102
|
+
3. 使用 JWT token(签名验证后)提取角色信息
|
|
103
|
+
4. 禁止从请求参数/Header中读取角色/权限信息
|
|
104
|
+
languages:
|
|
105
|
+
- java
|
|
106
|
+
pattern-either:
|
|
107
|
+
- pattern: |
|
|
108
|
+
$REQ.getParameter("role")
|
|
109
|
+
- pattern: |
|
|
110
|
+
$REQ.getParameter("$ROLE")
|
|
111
|
+
- pattern: |
|
|
112
|
+
$REQ.getHeader("$ROLE")
|
|
113
|
+
- pattern: |
|
|
114
|
+
$REQ.getHeader("$AUTH")
|
|
115
|
+
metadata:
|
|
116
|
+
cwe: "CWE-501: Trust Boundary Violation"
|
|
117
|
+
severity: HIGH
|
|
118
|
+
precision: medium
|
|
119
|
+
category: trust-boundary
|
|
120
|
+
likelihood: HIGH
|
|
121
|
+
impact: HIGH
|
|
122
|
+
owasp: "A04:2021 - Insecure Design"
|
|
123
|
+
references:
|
|
124
|
+
- "https://cwe.mitre.org/data/definitions/501.html"
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# CWE-502 反序列化深度覆盖 (v2): 常见不安全反序列化库
|
|
2
|
+
# 原 cwe-502-insecure-deserialization.yaml — 仅Java原生ObjectInputStream
|
|
3
|
+
# 补: Kryo/Hessian/JNDI 反序列化入口
|
|
4
|
+
|
|
5
|
+
rules:
|
|
6
|
+
|
|
7
|
+
# ZM-JAVA-KRYO-001: Kryo 反序列化未设置 ClassResolver
|
|
8
|
+
- id: zm-java-kryo-001
|
|
9
|
+
severity: CRITICAL
|
|
10
|
+
message: |
|
|
11
|
+
Kryo 反序列化未限制可反序列化的类——攻击者可通过 gadget chain 执行任意代码。
|
|
12
|
+
使用 `Kryo.setClassLoader()` 或 `Kryo.setReferences(false)` 限制危险类加载。
|
|
13
|
+
推荐迁移到 Protobuf/JSON 等非原生反序列化方案。
|
|
14
|
+
languages:
|
|
15
|
+
- java
|
|
16
|
+
pattern-either:
|
|
17
|
+
- pattern: |
|
|
18
|
+
$KRYO = new Kryo();
|
|
19
|
+
...
|
|
20
|
+
$KRYO.readObject($INPUT, $CLS);
|
|
21
|
+
- pattern: |
|
|
22
|
+
$KRYO.readObject($INPUT, $CLS)
|
|
23
|
+
- pattern: |
|
|
24
|
+
new Kryo()
|
|
25
|
+
metadata:
|
|
26
|
+
cwe: "CWE-502: Deserialization of Untrusted Data"
|
|
27
|
+
owasp: "A08:2021 - Software and Data Integrity Failures"
|
|
28
|
+
precision: high
|
|
29
|
+
tags: [deserialization, kryo, rce]
|
|
30
|
+
references:
|
|
31
|
+
- https://github.com/EsotericSoftware/kryo
|
|
32
|
+
|
|
33
|
+
# ZM-JAVA-HESSIAN-001: Hessian 反序列化入口检测
|
|
34
|
+
- id: zm-java-hessian-001
|
|
35
|
+
severity: CRITICAL
|
|
36
|
+
message: |
|
|
37
|
+
HessianInput / Hessian2Input 直接反序列化外部输入——Hessian 已知多种 gadget chain。
|
|
38
|
+
使用 Hessian 前校验输入来源可信,或迁移到 gRPC/Spring Remoting with basic auth。
|
|
39
|
+
languages:
|
|
40
|
+
- java
|
|
41
|
+
pattern-either:
|
|
42
|
+
- pattern: |
|
|
43
|
+
$HIN = new HessianInput($STREAM);
|
|
44
|
+
...
|
|
45
|
+
$HIN.readObject();
|
|
46
|
+
- pattern: |
|
|
47
|
+
$HIN = new Hessian2Input($STREAM);
|
|
48
|
+
...
|
|
49
|
+
$HIN.readObject();
|
|
50
|
+
- pattern: |
|
|
51
|
+
$HIN.readObject()
|
|
52
|
+
metadata:
|
|
53
|
+
cwe: "CWE-502: Deserialization of Untrusted Data"
|
|
54
|
+
owasp: "A08:2021 - Software and Data Integrity Failures"
|
|
55
|
+
precision: high
|
|
56
|
+
tags: [deserialization, hessian, rce]
|
|
57
|
+
references:
|
|
58
|
+
- https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html
|
|
59
|
+
|
|
60
|
+
# ZM-JAVA-JNDI-LOOKUP-001: JNDI lookup 使用用户可控字符串
|
|
61
|
+
- id: zm-java-jndi-lookup-001
|
|
62
|
+
severity: CRITICAL
|
|
63
|
+
message: |
|
|
64
|
+
JNDI lookup(initial) 使用用户可控 URI — 可触发 JNDI 注入攻击。
|
|
65
|
+
这是 Log4Shell (CVE-2021-44228) 的关键 sink。升级 JDK (>= 8u191) 并禁用远程类加载。
|
|
66
|
+
languages:
|
|
67
|
+
- java
|
|
68
|
+
pattern-either:
|
|
69
|
+
- pattern: |
|
|
70
|
+
$CTX = new InitialContext();
|
|
71
|
+
...
|
|
72
|
+
$CTX.lookup($INPUT);
|
|
73
|
+
- pattern: |
|
|
74
|
+
InitialContext.doLookup($INPUT)
|
|
75
|
+
metadata:
|
|
76
|
+
cwe: "CWE-502: Deserialization of Untrusted Data"
|
|
77
|
+
owasp: "A08:2021 - Software and Data Integrity Failures"
|
|
78
|
+
precision: very-high
|
|
79
|
+
tags: [deserialization, jndi, log4shell, rce]
|
|
80
|
+
references:
|
|
81
|
+
- https://www.cvedetails.com/cve/CVE-2021-44228/
|
|
82
|
+
|
|
83
|
+
# ZM-JAVA-JACKSON-UNSAFE-001: Jackson ObjectMapper 启用 defaultTyping
|
|
84
|
+
- id: zm-java-jackson-unsafe-001
|
|
85
|
+
severity: CRITICAL
|
|
86
|
+
message: |
|
|
87
|
+
ObjectMapper 启用 defaultTyping / enableDefaultTyping — 存在多态反序列化 RCE 风险。
|
|
88
|
+
此配置允许攻击者通过 @class 字段指定任意类反序列化。
|
|
89
|
+
关闭 defaultTyping 并使用 @JsonTypeInfo 显式注册允许的子类型。
|
|
90
|
+
languages:
|
|
91
|
+
- java
|
|
92
|
+
pattern-either:
|
|
93
|
+
- pattern: |
|
|
94
|
+
$MAPPER.enableDefaultTyping()
|
|
95
|
+
- pattern: |
|
|
96
|
+
$MAPPER.enableDefaultTyping($X)
|
|
97
|
+
- pattern: |
|
|
98
|
+
ObjectMapper().enableDefaultTyping()
|
|
99
|
+
- pattern: |
|
|
100
|
+
new ObjectMapper().enableDefaultTyping()
|
|
101
|
+
- pattern: |
|
|
102
|
+
$MAPPER.activateDefaultTyping($PF)
|
|
103
|
+
metadata:
|
|
104
|
+
cwe: "CWE-502: Deserialization of Untrusted Data"
|
|
105
|
+
owasp: "A08:2021 - Software and Data Integrity Failures"
|
|
106
|
+
precision: very-high
|
|
107
|
+
tags: [deserialization, jackson, rce]
|
|
108
|
+
references:
|
|
109
|
+
- https://cowtowncoder.medium.com/on-jackson-cves-dont-panic-here-is-what-you-need-to-know-54cd0d6e8062
|
|
110
|
+
|
|
111
|
+
# ZM-JAVA-JAVA-SERIAL-001: ObjectInputStream + readObject (增强, 补充原有cwe502规则)
|
|
112
|
+
- id: zm-java-serial-001
|
|
113
|
+
severity: CRITICAL
|
|
114
|
+
message: |
|
|
115
|
+
ObjectInputStream.readObject() 直接反序列化可能存在不安全输入。
|
|
116
|
+
使用 ValidatingObjectInputStream (Apache Commons IO) 限制允许反序列化的类白名单。
|
|
117
|
+
languages:
|
|
118
|
+
- java
|
|
119
|
+
pattern-either:
|
|
120
|
+
- pattern: new ObjectInputStream($INPUT)
|
|
121
|
+
- pattern: $OIS = new ObjectInputStream($INPUT)
|
|
122
|
+
metadata:
|
|
123
|
+
cwe: "CWE-502: Deserialization of Untrusted Data"
|
|
124
|
+
owasp: "A08:2021 - Software and Data Integrity Failures"
|
|
125
|
+
precision: high
|
|
126
|
+
tags: [deserialization, objectinputstream, rce]
|
|
127
|
+
references:
|
|
128
|
+
- https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# CWE-502: FastJSON AutoType 不安全反序列化检测
|
|
2
|
+
# 逐码 ZhuMa V4.1 — 通用规则库
|
|
3
|
+
# 检测: JSON.parseObject() 且未设置 SafeMode 或 ParserConfig AutoType 配置不当
|
|
4
|
+
|
|
5
|
+
rules:
|
|
6
|
+
|
|
7
|
+
# ZM-JAVA-FJ-001: FastJSON parseObject 未开启 SafeMode
|
|
8
|
+
- id: zm-java-fj-001
|
|
9
|
+
severity: ERROR
|
|
10
|
+
message: |
|
|
11
|
+
检测到 FastJSON JSON.parseObject() 调用,未显式启用 SafeMode。
|
|
12
|
+
FastJSON < 1.2.83 默认 AutoType 支持可导致任意类反序列化,攻击者可通过 @type 字段
|
|
13
|
+
指定任意类触发 RCE。已公开 gadget 包括: JdbcRowSetImpl、TemplatesImpl、BasicDataSource 等。
|
|
14
|
+
修复方案:
|
|
15
|
+
1. 升级 FastJSON 至 1.2.83+ 或 2.0.25+
|
|
16
|
+
2. 显式启用 SafeMode: ParserConfig.getGlobalInstance().setSafeMode(true)
|
|
17
|
+
3. 若必须使用 AutoType,配置严格白名单: ParserConfig.getGlobalInstance().addAccept("com.example.")
|
|
18
|
+
4. 迁移至 Jackson/Gson (默认不支持任意类型反序列化)
|
|
19
|
+
参考:
|
|
20
|
+
- CVE-2022-25845 (FastJSON AutoType RCE)
|
|
21
|
+
- https://github.com/alibaba/fastjson/wiki/enable_autotype
|
|
22
|
+
languages:
|
|
23
|
+
- java
|
|
24
|
+
patterns:
|
|
25
|
+
- pattern-inside: |
|
|
26
|
+
import com.alibaba.fastjson.JSON;
|
|
27
|
+
...
|
|
28
|
+
- pattern-either:
|
|
29
|
+
- pattern: |
|
|
30
|
+
JSON.parseObject($INPUT)
|
|
31
|
+
- pattern: |
|
|
32
|
+
JSON.parseObject($INPUT, ...)
|
|
33
|
+
- pattern: |
|
|
34
|
+
JSON.parse($INPUT)
|
|
35
|
+
- pattern: |
|
|
36
|
+
JSON.parse($INPUT, ...)
|
|
37
|
+
- pattern: |
|
|
38
|
+
JSON.parseArray($INPUT)
|
|
39
|
+
- pattern: |
|
|
40
|
+
JSON.parseArray($INPUT, ...)
|
|
41
|
+
metadata:
|
|
42
|
+
cwe: "CWE-502: Deserialization of Untrusted Data"
|
|
43
|
+
severity: ERROR
|
|
44
|
+
precision: high
|
|
45
|
+
category: deserialization
|
|
46
|
+
likelihood: HIGH
|
|
47
|
+
impact: CRITICAL
|
|
48
|
+
owasp: "A08:2021 - Software and Data Integrity Failures"
|
|
49
|
+
references:
|
|
50
|
+
- "https://nvd.nist.gov/vuln/detail/CVE-2022-25845"
|
|
51
|
+
- "https://github.com/alibaba/fastjson/wiki/security_update"
|
|
52
|
+
|
|
53
|
+
# ZM-JAVA-FJ-002: FastJSON AutoType 显式开启 (高危)
|
|
54
|
+
- id: zm-java-fj-002
|
|
55
|
+
severity: ERROR
|
|
56
|
+
message: |
|
|
57
|
+
检测到 FastJSON 显式启用了 AutoTypeSupport。
|
|
58
|
+
开启 AutoType 后,攻击者可通过 @type 字段指定任意类触发反序列化 gadget 链。
|
|
59
|
+
应立即禁用 AutoType 并启用 SafeMode。
|
|
60
|
+
修复方案:
|
|
61
|
+
1. 移除 autoTypeSupport=true 配置
|
|
62
|
+
2. 启用 SafeMode: ParserConfig.getGlobalInstance().setSafeMode(true)
|
|
63
|
+
3. 仅在必须时使用 addAccept() 白名单
|
|
64
|
+
languages:
|
|
65
|
+
- java
|
|
66
|
+
pattern-either:
|
|
67
|
+
- pattern: |
|
|
68
|
+
ParserConfig.getGlobalInstance().setAutoTypeSupport(true)
|
|
69
|
+
- pattern: |
|
|
70
|
+
$CONFIG.setAutoTypeSupport(true)
|
|
71
|
+
- pattern: |
|
|
72
|
+
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
|
|
73
|
+
metadata:
|
|
74
|
+
cwe: "CWE-502: Deserialization of Untrusted Data"
|
|
75
|
+
severity: ERROR
|
|
76
|
+
precision: very-high
|
|
77
|
+
category: deserialization
|
|
78
|
+
likelihood: HIGH
|
|
79
|
+
impact: CRITICAL
|
|
80
|
+
owasp: "A08:2021 - Software and Data Integrity Failures"
|
|
81
|
+
|
|
82
|
+
# ZM-JAVA-FJ-003: FastJSON @type 反序列化 + 未配置白名单
|
|
83
|
+
- id: zm-java-fj-003
|
|
84
|
+
severity: ERROR
|
|
85
|
+
message: |
|
|
86
|
+
检测到 FastJSON 使用 JSON.parseObject() 解析可能含 @type 字段的 JSON 输入。
|
|
87
|
+
若输入来自用户且未启用 SafeMode,攻击者可在 JSON 中注入 {"@type":"com.sun.rowset.JdbcRowSetImpl",...}
|
|
88
|
+
实现 JNDI 注入 RCE。
|
|
89
|
+
修复方案:
|
|
90
|
+
1. 启用 SafeMode: ParserConfig.getGlobalInstance().setSafeMode(true)
|
|
91
|
+
2. 在 JSON 解析前过滤/移除 @type 字段
|
|
92
|
+
3. 升级至 FastJSON 2.0.25+ (默认安全模式)
|
|
93
|
+
languages:
|
|
94
|
+
- java
|
|
95
|
+
pattern-either:
|
|
96
|
+
- pattern: |
|
|
97
|
+
JSON.parseObject($REQ.getParameter(...))
|
|
98
|
+
- pattern: |
|
|
99
|
+
JSON.parse($REQ.getParameter(...))
|
|
100
|
+
- pattern: |
|
|
101
|
+
JSON.parseObject($REQ.getParameter(...), $CLASS)
|
|
102
|
+
- pattern: |
|
|
103
|
+
JSON.parseArray($REQ.getParameter(...), $CLASS)
|
|
104
|
+
metadata:
|
|
105
|
+
cwe: "CWE-502: Deserialization of Untrusted Data"
|
|
106
|
+
severity: ERROR
|
|
107
|
+
precision: high
|
|
108
|
+
category: deserialization
|
|
109
|
+
likelihood: HIGH
|
|
110
|
+
impact: CRITICAL
|
|
111
|
+
owasp: "A08:2021 - Software and Data Integrity Failures"
|
|
112
|
+
|
|
113
|
+
# ZM-JAVA-FJ-004: FastJSON2 parseObject 未开启安全配置
|
|
114
|
+
- id: zm-java-fj-004
|
|
115
|
+
severity: HIGH
|
|
116
|
+
message: |
|
|
117
|
+
检测到 FastJSON2 JSON.parseObject() 调用。FastJSON2 1.x 默认关闭 AutoType,
|
|
118
|
+
但若通过配置开启,仍存在反序列化风险。
|
|
119
|
+
修复方案:
|
|
120
|
+
1. 确保使用 FastJSON2 2.0.25+ 版本 (默认安全)
|
|
121
|
+
2. 不显式开启 AutoType
|
|
122
|
+
3. 使用 JSONReader.Feature.SupportAutoType 时配合白名单
|
|
123
|
+
languages:
|
|
124
|
+
- java
|
|
125
|
+
pattern-either:
|
|
126
|
+
- pattern: |
|
|
127
|
+
com.alibaba.fastjson2.JSON.parseObject($INPUT)
|
|
128
|
+
- pattern: |
|
|
129
|
+
com.alibaba.fastjson2.JSON.parse($INPUT)
|
|
130
|
+
metadata:
|
|
131
|
+
cwe: "CWE-502: Deserialization of Untrusted Data"
|
|
132
|
+
severity: HIGH
|
|
133
|
+
precision: high
|
|
134
|
+
category: deserialization
|
|
135
|
+
likelihood: MEDIUM
|
|
136
|
+
impact: CRITICAL
|
|
137
|
+
owasp: "A08:2021 - Software and Data Integrity Failures"
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# CWE-502: Java 反序列化 Gadget 链检测
|
|
2
|
+
# 逐码 ZhuMa V4.1 — 通用规则库
|
|
3
|
+
# 检测: ObjectInputStream.readObject() 且 classpath 含已知危险 gadget 库
|
|
4
|
+
|
|
5
|
+
rules:
|
|
6
|
+
|
|
7
|
+
# ZM-JAVA-DS-GADGET-001: ObjectInputStream + Commons-Collections
|
|
8
|
+
- id: zm-java-ds-gadget-001
|
|
9
|
+
severity: ERROR
|
|
10
|
+
message: |
|
|
11
|
+
检测到 ObjectInputStream.readObject() 与 Apache Commons Collections 同时使用。
|
|
12
|
+
Commons Collections 3.x/4.x 含已公开的反序列化 Gadget 链(如 InvokerTransformer、ChainedTransformer),
|
|
13
|
+
攻击者可通过构造恶意序列化对象实现远程代码执行(RCE)。
|
|
14
|
+
修复方案:
|
|
15
|
+
1. 升级至 Commons Collections 4.4.6+/3.2.3+ 版本(修复了不安全反序列化)
|
|
16
|
+
2. 使用 ValidatingObjectInputStream 限制可反序列化类型
|
|
17
|
+
3. 替换为 JSON/Protobuf 等安全序列化方案
|
|
18
|
+
参考:
|
|
19
|
+
- CVE-2015-6420 (Apache Commons Collections)
|
|
20
|
+
- ysoserial CommonsCollections1-7
|
|
21
|
+
languages:
|
|
22
|
+
- java
|
|
23
|
+
patterns:
|
|
24
|
+
- pattern-either:
|
|
25
|
+
- pattern: |
|
|
26
|
+
new ObjectInputStream(...).readObject();
|
|
27
|
+
- pattern: |
|
|
28
|
+
$OIS = new ObjectInputStream(...);
|
|
29
|
+
...
|
|
30
|
+
$OIS.readObject();
|
|
31
|
+
- pattern-either:
|
|
32
|
+
- pattern: |
|
|
33
|
+
import org.apache.commons.collections4.*;
|
|
34
|
+
...
|
|
35
|
+
- pattern: |
|
|
36
|
+
import org.apache.commons.collections.*;
|
|
37
|
+
...
|
|
38
|
+
- pattern: |
|
|
39
|
+
import org.apache.commons.collections4.Transformer;
|
|
40
|
+
...
|
|
41
|
+
- pattern: |
|
|
42
|
+
import org.apache.commons.collections.Transformer;
|
|
43
|
+
...
|
|
44
|
+
metadata:
|
|
45
|
+
cwe: "CWE-502: Deserialization of Untrusted Data"
|
|
46
|
+
severity: ERROR
|
|
47
|
+
precision: medium
|
|
48
|
+
category: deserialization
|
|
49
|
+
likelihood: HIGH
|
|
50
|
+
impact: CRITICAL
|
|
51
|
+
owasp: "A08:2021 - Software and Data Integrity Failures"
|
|
52
|
+
references:
|
|
53
|
+
- "https://nvd.nist.gov/vuln/detail/CVE-2015-6420"
|
|
54
|
+
- "https://github.com/frohoff/ysoserial"
|
|
55
|
+
|
|
56
|
+
# ZM-JAVA-DS-GADGET-002: ObjectInputStream + BeanShell
|
|
57
|
+
- id: zm-java-ds-gadget-002
|
|
58
|
+
severity: ERROR
|
|
59
|
+
message: |
|
|
60
|
+
检测到 ObjectInputStream.readObject() 与 BeanShell 同时使用。
|
|
61
|
+
BeanShell 的 Interpreter 可通过 PriorityComparator gadget 触发任意代码执行。
|
|
62
|
+
攻击者可通过构造恶意序列化 BeanShell 对象实现 RCE。
|
|
63
|
+
修复方案:
|
|
64
|
+
1. 移除 BeanShell 依赖或替换为安全的表达式引擎
|
|
65
|
+
2. 使用 ValidatingObjectInputStream 限制反序列化类型
|
|
66
|
+
3. 使用 JSON/Protobuf 替代 Java 原生序列化
|
|
67
|
+
参考: ysoserial BeanShell1
|
|
68
|
+
languages:
|
|
69
|
+
- java
|
|
70
|
+
patterns:
|
|
71
|
+
- pattern-either:
|
|
72
|
+
- pattern: |
|
|
73
|
+
new ObjectInputStream(...).readObject();
|
|
74
|
+
- pattern: |
|
|
75
|
+
$OIS = new ObjectInputStream(...);
|
|
76
|
+
...
|
|
77
|
+
$OIS.readObject();
|
|
78
|
+
- pattern: |
|
|
79
|
+
import bsh.*;
|
|
80
|
+
...
|
|
81
|
+
metadata:
|
|
82
|
+
cwe: "CWE-502: Deserialization of Untrusted Data"
|
|
83
|
+
severity: ERROR
|
|
84
|
+
precision: medium
|
|
85
|
+
category: deserialization
|
|
86
|
+
likelihood: MEDIUM
|
|
87
|
+
impact: CRITICAL
|
|
88
|
+
owasp: "A08:2021 - Software and Data Integrity Failures"
|
|
89
|
+
references:
|
|
90
|
+
- "https://github.com/frohoff/ysoserial"
|
|
91
|
+
|
|
92
|
+
# ZM-JAVA-DS-GADGET-003: ObjectInputStream + Spring Beans
|
|
93
|
+
- id: zm-java-ds-gadget-003
|
|
94
|
+
severity: ERROR
|
|
95
|
+
message: |
|
|
96
|
+
检测到 ObjectInputStream.readObject() 与 Spring Beans 同时使用。
|
|
97
|
+
可利用 Spring BeanWrapperImpl / MethodInvokeTypeProvider 构造反序列化 gadget 链。
|
|
98
|
+
修复方案:
|
|
99
|
+
1. 使用 ValidatingObjectInputStream 限制反序列化类型白名单
|
|
100
|
+
2. 避免对不可信数据进行 Java 原生反序列化
|
|
101
|
+
3. 使用 Jackson/Gson + 类型白名单或 Protobuf
|
|
102
|
+
languages:
|
|
103
|
+
- java
|
|
104
|
+
patterns:
|
|
105
|
+
- pattern-either:
|
|
106
|
+
- pattern: |
|
|
107
|
+
new ObjectInputStream(...).readObject();
|
|
108
|
+
- pattern: |
|
|
109
|
+
$OIS = new ObjectInputStream(...);
|
|
110
|
+
...
|
|
111
|
+
$OIS.readObject();
|
|
112
|
+
- pattern-either:
|
|
113
|
+
- pattern: |
|
|
114
|
+
import org.springframework.beans.*;
|
|
115
|
+
...
|
|
116
|
+
- pattern: |
|
|
117
|
+
import org.springframework.beans.factory.*;
|
|
118
|
+
...
|
|
119
|
+
metadata:
|
|
120
|
+
cwe: "CWE-502: Deserialization of Untrusted Data"
|
|
121
|
+
severity: ERROR
|
|
122
|
+
precision: medium
|
|
123
|
+
category: deserialization
|
|
124
|
+
likelihood: MEDIUM
|
|
125
|
+
impact: CRITICAL
|
|
126
|
+
owasp: "A08:2021 - Software and Data Integrity Failures"
|
|
127
|
+
|
|
128
|
+
# ZM-JAVA-DS-GADGET-004: ObjectInputStream + JNDI 可被利用
|
|
129
|
+
- id: zm-java-ds-gadget-004
|
|
130
|
+
severity: ERROR
|
|
131
|
+
message: |
|
|
132
|
+
检测到 ObjectInputStream.readObject() 与 JNDI 查找同一文件中出现。
|
|
133
|
+
JNDI 注入常结合反序列化 gadget 实现 RCE(如 CVE-2021-44228 Log4Shell 变种)。
|
|
134
|
+
修复方案:
|
|
135
|
+
1. 禁用远程 JNDI 查找: -Dcom.sun.jndi.ldap.object.trustURLCodebase=false
|
|
136
|
+
2. JDK 升级至 8u191+/11.0.1+/17+ (默认禁用远程 codebase)
|
|
137
|
+
3. 避免对不可信数据进行反序列化,使用白名单机制
|
|
138
|
+
languages:
|
|
139
|
+
- java
|
|
140
|
+
patterns:
|
|
141
|
+
- pattern-inside: |
|
|
142
|
+
import javax.naming.*;
|
|
143
|
+
...
|
|
144
|
+
- pattern-either:
|
|
145
|
+
- pattern: |
|
|
146
|
+
new ObjectInputStream(...).readObject();
|
|
147
|
+
- pattern: |
|
|
148
|
+
$OIS = new ObjectInputStream(...);
|
|
149
|
+
...
|
|
150
|
+
$OIS.readObject();
|
|
151
|
+
metadata:
|
|
152
|
+
cwe: "CWE-502: Deserialization of Untrusted Data"
|
|
153
|
+
severity: ERROR
|
|
154
|
+
precision: low
|
|
155
|
+
category: deserialization
|
|
156
|
+
likelihood: MEDIUM
|
|
157
|
+
impact: CRITICAL
|
|
158
|
+
owasp: "A08:2021 - Software and Data Integrity Failures"
|