@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,91 @@
|
|
|
1
|
+
# CWE-502: JNDI Injection (Log4Shell-like vectors)
|
|
2
|
+
# ZhuMa V4.1 — JNDI lookup from untrusted input
|
|
3
|
+
|
|
4
|
+
rules:
|
|
5
|
+
|
|
6
|
+
# ZM-JAVA-JNDI-001: InitialContext.lookup() with user-controlled name
|
|
7
|
+
- id: zm-java-jndi-001
|
|
8
|
+
severity: ERROR
|
|
9
|
+
message: |
|
|
10
|
+
InitialContext.lookup() receives HTTP request parameter — JNDI injection.
|
|
11
|
+
Attacker supplies ldap://evil.com/Exploit for remote class loading (same vector as Log4Shell).
|
|
12
|
+
Fix: 1) Never pass user input to lookup() 2) Whitelist allowed JNDI names 3) Set com.sun.jndi.ldap.object.trustURLCodebase=false
|
|
13
|
+
languages:
|
|
14
|
+
- java
|
|
15
|
+
pattern-either:
|
|
16
|
+
- pattern: |
|
|
17
|
+
new InitialContext().lookup($REQ.getParameter(...))
|
|
18
|
+
- pattern: |
|
|
19
|
+
new InitialContext().lookup($REQ.getHeader(...))
|
|
20
|
+
- pattern: |
|
|
21
|
+
new InitialContext().lookup($REQ.getAttribute(...))
|
|
22
|
+
- pattern: |
|
|
23
|
+
new InitialContext().lookup($REQ.getParameter(...));
|
|
24
|
+
- pattern: |
|
|
25
|
+
new InitialContext().lookup($REQ.getHeader(...));
|
|
26
|
+
- pattern: |
|
|
27
|
+
new InitialContext().lookup($REQ.getAttribute(...));
|
|
28
|
+
metadata:
|
|
29
|
+
cwe: "CWE-502: Deserialization of Untrusted Data"
|
|
30
|
+
severity: ERROR
|
|
31
|
+
precision: high
|
|
32
|
+
category: jndi-injection
|
|
33
|
+
likelihood: HIGH
|
|
34
|
+
impact: CRITICAL
|
|
35
|
+
owasp: "A03:2021 - Injection"
|
|
36
|
+
references:
|
|
37
|
+
- "https://nvd.nist.gov/vuln/detail/CVE-2021-44228"
|
|
38
|
+
- "https://owasp.org/www-project-top-ten/2017/A8_2017-Insecure_Deserialization"
|
|
39
|
+
|
|
40
|
+
# ZM-JAVA-JNDI-002: Context.lookup() with concatenated user input
|
|
41
|
+
- id: zm-java-jndi-002
|
|
42
|
+
severity: ERROR
|
|
43
|
+
message: |
|
|
44
|
+
Context.lookup() name string concatenates user-supplied HTTP parameter — JNDI injection.
|
|
45
|
+
Even partial user control of JNDI name enables ldap:// RCE via remote codebase loading.
|
|
46
|
+
Fix: Do NOT concatenate user input into JNDI names; use hardcoded lookup strings only.
|
|
47
|
+
languages:
|
|
48
|
+
- java
|
|
49
|
+
pattern-either:
|
|
50
|
+
- pattern: |
|
|
51
|
+
$CTX.lookup($STR + $REQ.getParameter(...))
|
|
52
|
+
- pattern: |
|
|
53
|
+
$CTX.lookup($STR + $REQ.getHeader(...))
|
|
54
|
+
- pattern: |
|
|
55
|
+
$CTX.lookup($REQ.getParameter(...) + $STR)
|
|
56
|
+
metadata:
|
|
57
|
+
cwe: "CWE-502: Deserialization of Untrusted Data"
|
|
58
|
+
severity: ERROR
|
|
59
|
+
precision: medium
|
|
60
|
+
category: jndi-injection
|
|
61
|
+
likelihood: HIGH
|
|
62
|
+
impact: CRITICAL
|
|
63
|
+
owasp: "A03:2021 - Injection"
|
|
64
|
+
references:
|
|
65
|
+
- "https://nvd.nist.gov/vuln/detail/CVE-2021-44228"
|
|
66
|
+
|
|
67
|
+
# ZM-JAVA-JNDI-003: JndiTemplate/JndiLocatorDelegate lookup with user input (Spring)
|
|
68
|
+
- id: zm-java-jndi-003
|
|
69
|
+
severity: ERROR
|
|
70
|
+
message: |
|
|
71
|
+
Spring JndiTemplate.lookup() receives user-supplied input — JNDI injection.
|
|
72
|
+
Use JndiObjectFactoryBean with hardcoded JNDI names; never pass dynamic user data.
|
|
73
|
+
languages:
|
|
74
|
+
- java
|
|
75
|
+
pattern-either:
|
|
76
|
+
- pattern: |
|
|
77
|
+
new JndiTemplate().lookup($REQ.getParameter(...))
|
|
78
|
+
- pattern: |
|
|
79
|
+
$JT.lookup($REQ.getParameter(...))
|
|
80
|
+
- pattern: |
|
|
81
|
+
new JndiTemplate().lookup($REQ.getParameter(...));
|
|
82
|
+
- pattern: |
|
|
83
|
+
new JndiLocatorDelegate().lookup($REQ.getParameter(...))
|
|
84
|
+
metadata:
|
|
85
|
+
cwe: "CWE-502: Deserialization of Untrusted Data"
|
|
86
|
+
severity: ERROR
|
|
87
|
+
precision: high
|
|
88
|
+
category: jndi-injection
|
|
89
|
+
likelihood: HIGH
|
|
90
|
+
impact: CRITICAL
|
|
91
|
+
owasp: "A03:2021 - Injection"
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# CWE-502: Apache Shiro RememberMe 反序列化检测
|
|
2
|
+
# 逐码 ZhuMa V4.1 — 通用规则库
|
|
3
|
+
# 检测: CookieRememberMeManager 且 AES 密钥硬编码 / 使用默认密钥
|
|
4
|
+
|
|
5
|
+
rules:
|
|
6
|
+
|
|
7
|
+
# ZM-JAVA-SHIRO-001: Shiro RememberMe 硬编码 AES 密钥
|
|
8
|
+
- id: zm-java-shiro-001
|
|
9
|
+
severity: ERROR
|
|
10
|
+
message: |
|
|
11
|
+
检测到 Apache Shiro CookieRememberMeManager 使用了硬编码的 AES 加密密钥。
|
|
12
|
+
若使用已知的默认密钥(如 kPH+bIxk5D2deZiIxcaaaA==),攻击者可伪造 RememberMe Cookie
|
|
13
|
+
实现反序列化 RCE(如 CommonsBeanutils + TemplatesImpl gadget 链)。
|
|
14
|
+
攻击链: 伪造 RememberMe Cookie → Base64解码 → AES解密 → 反序列化 → RCE
|
|
15
|
+
修复方案:
|
|
16
|
+
1. 使用随机生成的强 AES 密钥: KeyGenerator.getInstance("AES").generateKey()
|
|
17
|
+
2. 不要从配置文件/代码中硬编码密钥,使用环境变量或密钥管理服务
|
|
18
|
+
3. 升级 Shiro 至 1.13.0+ (默认启用更安全的反序列化过滤)
|
|
19
|
+
4. 替换默认密钥,确保每个部署实例使用不同密钥
|
|
20
|
+
参考:
|
|
21
|
+
- CVE-2016-4437 (Shiro RememberMe 反序列化 RCE)
|
|
22
|
+
- Shiro 默认密钥: kPH+bIxk5D2deZiIxcaaaA==
|
|
23
|
+
languages:
|
|
24
|
+
- java
|
|
25
|
+
pattern-either:
|
|
26
|
+
- pattern: |
|
|
27
|
+
new CookieRememberMeManager().setCipherKey(Base64.decode($KEY));
|
|
28
|
+
- pattern: |
|
|
29
|
+
$MGR.setCipherKey(Base64.decode($KEY));
|
|
30
|
+
- pattern: |
|
|
31
|
+
CookieRememberMeManager $MGR = new CookieRememberMeManager();
|
|
32
|
+
...
|
|
33
|
+
$MGR.setCipherKey($KEY);
|
|
34
|
+
- pattern: |
|
|
35
|
+
new CookieRememberMeManager()
|
|
36
|
+
metadata:
|
|
37
|
+
cwe: "CWE-502: Deserialization of Untrusted Data"
|
|
38
|
+
severity: ERROR
|
|
39
|
+
precision: high
|
|
40
|
+
category: deserialization
|
|
41
|
+
likelihood: HIGH
|
|
42
|
+
impact: CRITICAL
|
|
43
|
+
owasp: "A08:2021 - Software and Data Integrity Failures"
|
|
44
|
+
references:
|
|
45
|
+
- "https://nvd.nist.gov/vuln/detail/CVE-2016-4437"
|
|
46
|
+
- "https://shiro.apache.org/security-reports.html"
|
|
47
|
+
|
|
48
|
+
# ZM-JAVA-SHIRO-002: Shiro 默认 AES 密钥检测
|
|
49
|
+
- id: zm-java-shiro-002
|
|
50
|
+
severity: ERROR
|
|
51
|
+
message: |
|
|
52
|
+
检测到 Apache Shiro 使用了已知的默认 AES 密钥(Base64 编码字符串)。
|
|
53
|
+
该密钥为 Shiro 硬编码默认值,广泛公开,攻击者可直接用于伪造 RememberMe Cookie。
|
|
54
|
+
修复方案:
|
|
55
|
+
1. 立即替换为随机生成的密钥
|
|
56
|
+
2. 使用 KeyGenerator 生成新密钥,通过环境变量/密钥管理服务注入
|
|
57
|
+
3. 每个部署环境使用独立密钥
|
|
58
|
+
4. 如不需要 RememberMe 功能,禁用 CookieRememberMeManager
|
|
59
|
+
languages:
|
|
60
|
+
- java
|
|
61
|
+
pattern-either:
|
|
62
|
+
- pattern: |
|
|
63
|
+
$MGR.setCipherKey(Base64.decode("kPH+bIxk5D2deZiIxcaaaA=="))
|
|
64
|
+
- pattern: |
|
|
65
|
+
$MGR.setCipherKey(Base64.decode("kPH+bIxk5D2deZiIxcaaaA=="));
|
|
66
|
+
- pattern: |
|
|
67
|
+
$MGR.setCipherKey("kPH+bIxk5D2deZiIxcaaaA==".getBytes())
|
|
68
|
+
- pattern: |
|
|
69
|
+
setCipherKey(Base64.decode("kPH+bIxk5D2deZiIxcaaaA=="))
|
|
70
|
+
metadata:
|
|
71
|
+
cwe: "CWE-502: Deserialization of Untrusted Data"
|
|
72
|
+
severity: ERROR
|
|
73
|
+
precision: very-high
|
|
74
|
+
category: deserialization
|
|
75
|
+
likelihood: VERY_HIGH
|
|
76
|
+
impact: CRITICAL
|
|
77
|
+
owasp: "A08:2021 - Software and Data Integrity Failures"
|
|
78
|
+
references:
|
|
79
|
+
- "https://nvd.nist.gov/vuln/detail/CVE-2016-4437"
|
|
80
|
+
|
|
81
|
+
# ZM-JAVA-SHIRO-003: Shiro RememberMeManager 无 re-encryption 密钥
|
|
82
|
+
- id: zm-java-shiro-003
|
|
83
|
+
severity: ERROR
|
|
84
|
+
message: |
|
|
85
|
+
检测到 Apache Shiro CookieRememberMeManager 实例化但未设置自定义密钥。
|
|
86
|
+
若使用默认密钥,攻击者可伪造 RememberMe Cookie 实现反序列化 RCE。
|
|
87
|
+
修复方案:
|
|
88
|
+
1. 显式设置随机 AES 密钥: setCipherKey(KeyGenerator.getInstance("AES").generateKey().getEncoded())
|
|
89
|
+
2. 密钥从安全配置源加载,禁止硬编码
|
|
90
|
+
3. 部署时自动生成实例级密钥并持久化
|
|
91
|
+
languages:
|
|
92
|
+
- java
|
|
93
|
+
patterns:
|
|
94
|
+
- pattern-inside: |
|
|
95
|
+
import org.apache.shiro.mgt.AbstractRememberMeManager;
|
|
96
|
+
...
|
|
97
|
+
- pattern: |
|
|
98
|
+
new CookieRememberMeManager()
|
|
99
|
+
metadata:
|
|
100
|
+
cwe: "CWE-502: Deserialization of Untrusted Data"
|
|
101
|
+
severity: ERROR
|
|
102
|
+
precision: high
|
|
103
|
+
category: deserialization
|
|
104
|
+
likelihood: HIGH
|
|
105
|
+
impact: CRITICAL
|
|
106
|
+
owasp: "A08:2021 - Software and Data Integrity Failures"
|
|
107
|
+
references:
|
|
108
|
+
- "https://nvd.nist.gov/vuln/detail/CVE-2016-4437"
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# CWE-601: URL Redirection — Spring-specific open redirect
|
|
2
|
+
# ZhuMa V4.1 — detection for redirect-to-user-input patterns
|
|
3
|
+
|
|
4
|
+
rules:
|
|
5
|
+
|
|
6
|
+
# ZM-JAVA-REDIRECT-001: "redirect:" prefix + user-controlled URL
|
|
7
|
+
- id: zm-java-redirect-001
|
|
8
|
+
severity: MEDIUM
|
|
9
|
+
message: |
|
|
10
|
+
Spring MVC "redirect:" prefix concatenated with HTTP parameter - open redirect to attacker URL.
|
|
11
|
+
Phishers use open redirects to make malicious links appear trusted (e.g. example.com/redirect?url=evil.com).
|
|
12
|
+
Fix: validate redirect target against domain whitelist or use relative redirects only.
|
|
13
|
+
languages:
|
|
14
|
+
- java
|
|
15
|
+
pattern-either:
|
|
16
|
+
- pattern: |
|
|
17
|
+
$PREFIX = "redirect:";
|
|
18
|
+
...
|
|
19
|
+
return $PREFIX + $REQ.getParameter(...);
|
|
20
|
+
- pattern: |
|
|
21
|
+
return $STR + $REQ.getParameter(...);
|
|
22
|
+
- pattern: |
|
|
23
|
+
$R = $STR + $REQ.getParameter(...);
|
|
24
|
+
metadata:
|
|
25
|
+
cwe: "CWE-601: URL Redirection to Untrusted Site (Open Redirect)"
|
|
26
|
+
severity: MEDIUM
|
|
27
|
+
precision: medium
|
|
28
|
+
category: url-redirect
|
|
29
|
+
likelihood: MEDIUM
|
|
30
|
+
impact: MEDIUM
|
|
31
|
+
owasp: "A01:2021 - Broken Access Control"
|
|
32
|
+
|
|
33
|
+
# ZM-JAVA-REDIRECT-002: HttpServletResponse.sendRedirect() with user input
|
|
34
|
+
- id: zm-java-redirect-002
|
|
35
|
+
severity: MEDIUM
|
|
36
|
+
message: |
|
|
37
|
+
HttpServletResponse.sendRedirect() receives user-supplied URL — open redirect.
|
|
38
|
+
Attackers craft phishing URLs like /login?redirect=https://evil.com to steal credentials.
|
|
39
|
+
Fix: validate against safelist of allowed destinations; prefer relative paths.
|
|
40
|
+
languages:
|
|
41
|
+
- java
|
|
42
|
+
pattern-either:
|
|
43
|
+
- pattern: |
|
|
44
|
+
$RESP.sendRedirect($REQ.getParameter(...))
|
|
45
|
+
- pattern: |
|
|
46
|
+
$RESP.sendRedirect($REQ.getHeader(...))
|
|
47
|
+
- pattern: |
|
|
48
|
+
$RESP.sendRedirect($PREFIX + $REQ.getParameter(...))
|
|
49
|
+
- pattern: |
|
|
50
|
+
response.sendRedirect($REQ.getParameter(...))
|
|
51
|
+
metadata:
|
|
52
|
+
cwe: "CWE-601: URL Redirection to Untrusted Site (Open Redirect)"
|
|
53
|
+
severity: MEDIUM
|
|
54
|
+
precision: high
|
|
55
|
+
category: url-redirect
|
|
56
|
+
likelihood: MEDIUM
|
|
57
|
+
impact: MEDIUM
|
|
58
|
+
owasp: "A01:2021 - Broken Access Control"
|
|
59
|
+
|
|
60
|
+
# ZM-JAVA-REDIRECT-003: ModelAndView / RedirectView with user-controlled URL
|
|
61
|
+
- id: zm-java-redirect-003
|
|
62
|
+
severity: MEDIUM
|
|
63
|
+
message: |
|
|
64
|
+
Spring ModelAndView or RedirectView constructed with user-supplied redirect URL.
|
|
65
|
+
Open redirects enable phishing and social engineering attacks.
|
|
66
|
+
Fix: use a redirect strategy that validates target hosts; or redirect to a fixed landing page.
|
|
67
|
+
languages:
|
|
68
|
+
- java
|
|
69
|
+
pattern-either:
|
|
70
|
+
- pattern: |
|
|
71
|
+
new ModelAndView("redirect:" + $REQ.getParameter(...))
|
|
72
|
+
- pattern: |
|
|
73
|
+
new RedirectView($REQ.getParameter(...))
|
|
74
|
+
- pattern: |
|
|
75
|
+
new RedirectView($REQ.getParameter(...), true)
|
|
76
|
+
- pattern: |
|
|
77
|
+
new RedirectView($PREFIX + $REQ.getParameter(...))
|
|
78
|
+
metadata:
|
|
79
|
+
cwe: "CWE-601: URL Redirection to Untrusted Site (Open Redirect)"
|
|
80
|
+
severity: MEDIUM
|
|
81
|
+
precision: high
|
|
82
|
+
category: url-redirect
|
|
83
|
+
likelihood: MEDIUM
|
|
84
|
+
impact: MEDIUM
|
|
85
|
+
owasp: "A01:2021 - Broken Access Control"
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# CWE-611: XXE 增强检测 — TransformerFactory / Validator / SAXBuilder
|
|
2
|
+
# 逐码 ZhuMa V4.1 — 通用规则库
|
|
3
|
+
# 覆盖 xm-java-xxe 未覆盖的 Sinks
|
|
4
|
+
|
|
5
|
+
rules:
|
|
6
|
+
|
|
7
|
+
# ZM-JAVA-XXE-E01: TransformerFactory.newTransformer(StreamSource) 未配置 secure-processing
|
|
8
|
+
- id: zm-java-xxe-e01
|
|
9
|
+
severity: ERROR
|
|
10
|
+
message: |
|
|
11
|
+
TransformerFactory.newTransformer() 使用 StreamSource 解析 XML,
|
|
12
|
+
未设置 FEATURE_SECURE_PROCESSING 或禁用外部实体。
|
|
13
|
+
攻击者可通过外部实体注入读取本地文件、发起 SSRF。
|
|
14
|
+
修复: tf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true)
|
|
15
|
+
languages:
|
|
16
|
+
- java
|
|
17
|
+
pattern-either:
|
|
18
|
+
- pattern: |
|
|
19
|
+
$TF.newTransformer(new StreamSource($REQ.getInputStream()))
|
|
20
|
+
- pattern: |
|
|
21
|
+
$TF.newTransformer(new StreamSource($REQ.getReader()))
|
|
22
|
+
- pattern: |
|
|
23
|
+
$TF.newTransformer(new StreamSource($REQ.getParameter($PARAM)))
|
|
24
|
+
metadata:
|
|
25
|
+
cwe: "CWE-611: Improper Restriction of XML External Entity Reference"
|
|
26
|
+
severity: ERROR
|
|
27
|
+
precision: high
|
|
28
|
+
category: xxe
|
|
29
|
+
likelihood: HIGH
|
|
30
|
+
impact: CRITICAL
|
|
31
|
+
owasp: "A03:2021 - Injection"
|
|
32
|
+
|
|
33
|
+
# ZM-JAVA-XXE-E02: Validator.validate(StreamSource) 用户输入
|
|
34
|
+
- id: zm-java-xxe-e02
|
|
35
|
+
severity: ERROR
|
|
36
|
+
message: |
|
|
37
|
+
Validator.validate() 使用 StreamSource 且 Source 来自用户输入。
|
|
38
|
+
Validator 默认未禁用外部实体,攻击者可注入 XXE。
|
|
39
|
+
修复: 设置 XMLConstants.ACCESS_EXTERNAL_DTD/Schema 为空字符串
|
|
40
|
+
languages:
|
|
41
|
+
- java
|
|
42
|
+
pattern-either:
|
|
43
|
+
- pattern: |
|
|
44
|
+
$VAL.validate(new StreamSource($REQ.getInputStream()))
|
|
45
|
+
- pattern: |
|
|
46
|
+
$VAL.validate(new StreamSource($REQ.getReader()))
|
|
47
|
+
- pattern: |
|
|
48
|
+
$VAL.validate(new StreamSource($REQ.getParameter($PARAM)))
|
|
49
|
+
metadata:
|
|
50
|
+
cwe: "CWE-611: Improper Restriction of XML External Entity Reference"
|
|
51
|
+
severity: ERROR
|
|
52
|
+
precision: high
|
|
53
|
+
category: xxe
|
|
54
|
+
likelihood: HIGH
|
|
55
|
+
impact: CRITICAL
|
|
56
|
+
owasp: "A03:2021 - Injection"
|
|
57
|
+
|
|
58
|
+
# ZM-JAVA-XXE-E03: SAXBuilder (JDOM) + 用户输入
|
|
59
|
+
- id: zm-java-xxe-e03
|
|
60
|
+
severity: ERROR
|
|
61
|
+
message: |
|
|
62
|
+
JDOM SAXBuilder.build() 解析用户输入 XML,未禁用外部实体。
|
|
63
|
+
SAXBuilder 默认启用 DTD 和外部实体解析。
|
|
64
|
+
修复: builder.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true)
|
|
65
|
+
languages:
|
|
66
|
+
- java
|
|
67
|
+
patterns:
|
|
68
|
+
- pattern-inside: |
|
|
69
|
+
import org.jdom2.input.SAXBuilder;
|
|
70
|
+
...
|
|
71
|
+
- pattern: |
|
|
72
|
+
$SB.build($REQ.getInputStream())
|
|
73
|
+
metadata:
|
|
74
|
+
cwe: "CWE-611: Improper Restriction of XML External Entity Reference"
|
|
75
|
+
severity: ERROR
|
|
76
|
+
precision: high
|
|
77
|
+
category: xxe
|
|
78
|
+
likelihood: HIGH
|
|
79
|
+
impact: CRITICAL
|
|
80
|
+
owasp: "A03:2021 - Injection"
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# CWE-611: XXE — DocumentBuilderFactory / SAXParser / XMLInputFactory
|
|
2
|
+
# ZhuMa V4.1 — complementary to zm-java-cwe611-xxe-enhanced.yaml
|
|
3
|
+
|
|
4
|
+
rules:
|
|
5
|
+
|
|
6
|
+
# ZM-JAVA-XXE-DBF-001: DocumentBuilderFactory + user XML without secure processing
|
|
7
|
+
- id: zm-java-xxe-dbf-001
|
|
8
|
+
severity: ERROR
|
|
9
|
+
message: |
|
|
10
|
+
DocumentBuilderFactory.parse() receives untrusted XML input without disabling external entities.
|
|
11
|
+
Attacker can read local files (file:///etc/passwd) or perform SSRF via XXE.
|
|
12
|
+
Fix: dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true) and dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true)
|
|
13
|
+
languages:
|
|
14
|
+
- java
|
|
15
|
+
pattern-either:
|
|
16
|
+
- pattern: |
|
|
17
|
+
$DBF.newDocumentBuilder().parse($REQ.getInputStream())
|
|
18
|
+
- pattern: |
|
|
19
|
+
$DBF.newDocumentBuilder().parse($REQ.getReader())
|
|
20
|
+
- pattern: |
|
|
21
|
+
$DBF.newDocumentBuilder().parse($SRC);
|
|
22
|
+
...
|
|
23
|
+
$SRC = new InputSource($REQ.getInputStream());
|
|
24
|
+
- pattern: |
|
|
25
|
+
DocumentBuilderFactory.newInstance().newDocumentBuilder().parse($REQ.getInputStream())
|
|
26
|
+
metadata:
|
|
27
|
+
cwe: "CWE-611: Improper Restriction of XML External Entity Reference"
|
|
28
|
+
severity: ERROR
|
|
29
|
+
precision: high
|
|
30
|
+
category: xxe
|
|
31
|
+
likelihood: HIGH
|
|
32
|
+
impact: CRITICAL
|
|
33
|
+
owasp: "A03:2021 - Injection"
|
|
34
|
+
|
|
35
|
+
# ZM-JAVA-XXE-SAX-001: SAXParser + user XML without disabling DTD
|
|
36
|
+
- id: zm-java-xxe-sax-001
|
|
37
|
+
severity: ERROR
|
|
38
|
+
message: |
|
|
39
|
+
SAXParser.parse() receives untrusted XML — DTD/external entities enabled by default.
|
|
40
|
+
Fix: spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) and spf.setFeature("http://xml.org/sax/features/external-general-entities", false)
|
|
41
|
+
languages:
|
|
42
|
+
- java
|
|
43
|
+
pattern-either:
|
|
44
|
+
- pattern: |
|
|
45
|
+
$SAX.parse($REQ.getInputStream(), $HANDLER)
|
|
46
|
+
- pattern: |
|
|
47
|
+
$SAX.parse(new InputSource($REQ.getInputStream()))
|
|
48
|
+
- pattern: |
|
|
49
|
+
$SAX.parse(new InputSource($REQ.getReader()))
|
|
50
|
+
- pattern: |
|
|
51
|
+
SAXParserFactory.newInstance().newSAXParser().parse($REQ.getInputStream(), $H)
|
|
52
|
+
metadata:
|
|
53
|
+
cwe: "CWE-611: Improper Restriction of XML External Entity Reference"
|
|
54
|
+
severity: ERROR
|
|
55
|
+
precision: high
|
|
56
|
+
category: xxe
|
|
57
|
+
likelihood: HIGH
|
|
58
|
+
impact: CRITICAL
|
|
59
|
+
owasp: "A03:2021 - Injection"
|
|
60
|
+
|
|
61
|
+
# ZM-JAVA-XXE-STAX-001: XMLInputFactory + user XML without external entity restriction
|
|
62
|
+
- id: zm-java-xxe-stax-001
|
|
63
|
+
severity: ERROR
|
|
64
|
+
message: |
|
|
65
|
+
StAX XMLInputFactory creates reader from user XML — external entities enabled by default.
|
|
66
|
+
Fix: factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false) and factory.setProperty(XMLInputFactory.SUPPORT_DTD, false)
|
|
67
|
+
languages:
|
|
68
|
+
- java
|
|
69
|
+
pattern-either:
|
|
70
|
+
- pattern: |
|
|
71
|
+
$FACTORY.createXMLStreamReader($REQ.getInputStream())
|
|
72
|
+
- pattern: |
|
|
73
|
+
$FACTORY.createXMLEventReader($REQ.getInputStream())
|
|
74
|
+
- pattern: |
|
|
75
|
+
XMLInputFactory.newInstance().createXMLStreamReader($REQ.getInputStream())
|
|
76
|
+
- pattern: |
|
|
77
|
+
XMLInputFactory.newInstance().createXMLEventReader($REQ.getInputStream())
|
|
78
|
+
metadata:
|
|
79
|
+
cwe: "CWE-611: Improper Restriction of XML External Entity Reference"
|
|
80
|
+
severity: ERROR
|
|
81
|
+
precision: high
|
|
82
|
+
category: xxe
|
|
83
|
+
likelihood: HIGH
|
|
84
|
+
impact: CRITICAL
|
|
85
|
+
owasp: "A03:2021 - Injection"
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# CWE-639: 不安全的直接对象引用 (IDOR) 检测
|
|
2
|
+
# 逐码 ZhuMa V4.1 — 通用规则库
|
|
3
|
+
|
|
4
|
+
rules:
|
|
5
|
+
|
|
6
|
+
- id: zm-java-idor-001
|
|
7
|
+
severity: WARNING
|
|
8
|
+
message: |
|
|
9
|
+
REST Controller 从 @PathVariable 获取资源 ID 直接查询,
|
|
10
|
+
未发现 @PreAuthorize 注解或资源所有权校验。
|
|
11
|
+
修复方案:
|
|
12
|
+
1. 添加 @PreAuthorize 验证用户权限
|
|
13
|
+
2. 查询时关联当前用户: WHERE id = :id AND user_id = :currentUserId
|
|
14
|
+
3. 使用 UUID 替代自增 ID
|
|
15
|
+
languages:
|
|
16
|
+
- java
|
|
17
|
+
patterns:
|
|
18
|
+
- pattern-either:
|
|
19
|
+
- pattern: |
|
|
20
|
+
@GetMapping(...)
|
|
21
|
+
public $RET $METHOD(@PathVariable $IDTYPE $ID) {
|
|
22
|
+
...
|
|
23
|
+
$DAO.findById($ID);
|
|
24
|
+
...
|
|
25
|
+
}
|
|
26
|
+
- pattern: |
|
|
27
|
+
@PutMapping(...)
|
|
28
|
+
public $RET $METHOD(@PathVariable $IDTYPE $ID) {
|
|
29
|
+
...
|
|
30
|
+
$DAO.findById($ID);
|
|
31
|
+
...
|
|
32
|
+
}
|
|
33
|
+
- pattern: |
|
|
34
|
+
@DeleteMapping(...)
|
|
35
|
+
public $RET $METHOD(@PathVariable $IDTYPE $ID) {
|
|
36
|
+
...
|
|
37
|
+
$DAO.deleteById($ID);
|
|
38
|
+
...
|
|
39
|
+
}
|
|
40
|
+
- pattern-not: |
|
|
41
|
+
@PreAuthorize($X)
|
|
42
|
+
metadata:
|
|
43
|
+
cwe: "CWE-639"
|
|
44
|
+
severity: WARNING
|
|
45
|
+
precision: medium
|
|
46
|
+
category: auth
|
|
47
|
+
likelihood: HIGH
|
|
48
|
+
impact: HIGH
|
|
49
|
+
owasp: "A01:2021 - Broken Access Control"
|
|
50
|
+
|
|
51
|
+
- id: zm-java-idor-002
|
|
52
|
+
severity: WARNING
|
|
53
|
+
message: |
|
|
54
|
+
Controller 中路径变量 ID 直接传入数据访问层查询,
|
|
55
|
+
未发现将当前用户身份作为查询条件的代码。
|
|
56
|
+
修复方案:
|
|
57
|
+
1. DAO 层添加用户关联: findBy*AndUserId(id, currentUserId)
|
|
58
|
+
2. 使用 @PostAuthorize 校验返回对象所有权
|
|
59
|
+
languages:
|
|
60
|
+
- java
|
|
61
|
+
patterns:
|
|
62
|
+
- pattern-either:
|
|
63
|
+
- pattern: |
|
|
64
|
+
@$MAPPING(...)
|
|
65
|
+
public $RET $METHOD(@PathVariable("$IDNAME") $IDTYPE $IDVAR, ...) {
|
|
66
|
+
...
|
|
67
|
+
$DAO.$FINDBY($IDVAR);
|
|
68
|
+
...
|
|
69
|
+
}
|
|
70
|
+
- pattern: |
|
|
71
|
+
@$MAPPING(...)
|
|
72
|
+
public $RET $METHOD(@PathVariable("$IDNAME") $IDTYPE $IDVAR, ...) {
|
|
73
|
+
...
|
|
74
|
+
$REPO.$FINDBY($IDVAR);
|
|
75
|
+
...
|
|
76
|
+
}
|
|
77
|
+
- pattern-not: |
|
|
78
|
+
@PreAuthorize($X)
|
|
79
|
+
metadata:
|
|
80
|
+
cwe: "CWE-639"
|
|
81
|
+
severity: WARNING
|
|
82
|
+
precision: low
|
|
83
|
+
category: auth
|
|
84
|
+
likelihood: HIGH
|
|
85
|
+
impact: MEDIUM
|
|
86
|
+
owasp: "A01:2021 - Broken Access Control"
|
|
87
|
+
|
|
88
|
+
- id: zm-java-idor-003
|
|
89
|
+
severity: WARNING
|
|
90
|
+
message: |
|
|
91
|
+
Controller 从 @RequestParam 获取资源 ID 直接查询数据库,无 @PreAuthorize 保护。
|
|
92
|
+
修复方案:
|
|
93
|
+
1. 添加 @PreAuthorize 验证
|
|
94
|
+
2. 查询结果关联当前用户身份
|
|
95
|
+
3. 不一致则返回 403
|
|
96
|
+
languages:
|
|
97
|
+
- java
|
|
98
|
+
patterns:
|
|
99
|
+
- pattern-either:
|
|
100
|
+
- pattern: |
|
|
101
|
+
@$MAPPING(...)
|
|
102
|
+
public $RET $METHOD(@RequestParam("$IDNAME") $IDTYPE $IDVAR, ...) {
|
|
103
|
+
...
|
|
104
|
+
$DAO.findById($IDVAR);
|
|
105
|
+
...
|
|
106
|
+
}
|
|
107
|
+
- pattern: |
|
|
108
|
+
@$MAPPING(...)
|
|
109
|
+
public $RET $METHOD(@RequestParam("$IDNAME") $IDTYPE $IDVAR, ...) {
|
|
110
|
+
...
|
|
111
|
+
$REPO.findById($IDVAR);
|
|
112
|
+
...
|
|
113
|
+
}
|
|
114
|
+
- pattern-not: |
|
|
115
|
+
@PreAuthorize($X)
|
|
116
|
+
metadata:
|
|
117
|
+
cwe: "CWE-639"
|
|
118
|
+
severity: WARNING
|
|
119
|
+
precision: medium
|
|
120
|
+
category: auth
|
|
121
|
+
likelihood: HIGH
|
|
122
|
+
impact: HIGH
|
|
123
|
+
owasp: "A01:2021 - Broken Access Control"
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# CWE-79 XSS 全量 sink 覆盖 (v2): Spring MVC Response 写入所有变体
|
|
2
|
+
|
|
3
|
+
rules:
|
|
4
|
+
|
|
5
|
+
# ZM-JAVA-XSS-RESPONSE-001: HttpServletResponse.getWriter 直接输出用户输入
|
|
6
|
+
- id: zm-java-xss-response-001
|
|
7
|
+
severity: MEDIUM
|
|
8
|
+
message: |
|
|
9
|
+
HttpServletResponse.getWriter().print/write 直接输出用户输入,无 HTML 编码。
|
|
10
|
+
在输出到响应流前对用户数据进行 OWASP Encoder 或 Spring HtmlUtils.htmlEscape 编码。
|
|
11
|
+
languages:
|
|
12
|
+
- java
|
|
13
|
+
pattern-either:
|
|
14
|
+
- pattern: $RESP.getWriter().print($INPUT);
|
|
15
|
+
- pattern: $RESP.getWriter().write($INPUT);
|
|
16
|
+
- pattern: $RESP.getWriter().println($INPUT);
|
|
17
|
+
- pattern: $RESP.getOutputStream().print($INPUT);
|
|
18
|
+
metadata:
|
|
19
|
+
cwe: "CWE-79: Cross-site Scripting (XSS)"
|
|
20
|
+
owasp: "A03:2021 - Injection"
|
|
21
|
+
precision: high
|
|
22
|
+
tags: [xss, servlet, response]
|
|
23
|
+
|
|
24
|
+
# ZM-JAVA-XSS-MODELANDVIEW-001: ModelAndView 中添加未转义的用户输入
|
|
25
|
+
- id: zm-java-xss-mv-001
|
|
26
|
+
severity: MEDIUM
|
|
27
|
+
message: |
|
|
28
|
+
ModelAndView.addObject 添加用户输入 — 如果 JSP 模板中未使用 c:out 或 ${fn:escapeXml()},
|
|
29
|
+
可能导致存储型 XSS。确认对应 JSP/Thymeleaf 模板有输出编码。
|
|
30
|
+
languages:
|
|
31
|
+
- java
|
|
32
|
+
pattern: |
|
|
33
|
+
$MV.addObject($KEY, $INPUT);
|
|
34
|
+
...
|
|
35
|
+
return $MV;
|
|
36
|
+
metadata:
|
|
37
|
+
cwe: "CWE-79: Cross-site Scripting (XSS)"
|
|
38
|
+
owasp: "A03:2021 - Injection"
|
|
39
|
+
precision: medium
|
|
40
|
+
tags: [xss, modelandview, stored-xss]
|
|
41
|
+
|
|
42
|
+
# ZM-JAVA-XSS-HEADER-001: 响应头注入 (CRLF 注入)
|
|
43
|
+
- id: zm-java-xss-header-001
|
|
44
|
+
severity: LOW
|
|
45
|
+
message: |
|
|
46
|
+
resp.setHeader/addHeader 使用用户可控的值 — 可能导致 HTTP 响应头注入 (CRLF Injection)。
|
|
47
|
+
对用户值中的 \r\n 做过滤或编码,同时移除不可打印字符。
|
|
48
|
+
languages:
|
|
49
|
+
- java
|
|
50
|
+
pattern-either:
|
|
51
|
+
- pattern: $RESP.setHeader($NAME, $INPUT);
|
|
52
|
+
- pattern: $RESP.addHeader($NAME, $INPUT);
|
|
53
|
+
metadata:
|
|
54
|
+
cwe: "CWE-79: Cross-site Scripting (XSS)"
|
|
55
|
+
owasp: "A03:2021 - Injection"
|
|
56
|
+
precision: low
|
|
57
|
+
tags: [xss, header-injection, crlf]
|
|
58
|
+
|
|
59
|
+
# ZM-JAVA-XSS-FORMAT-001: String.format 拼接用户输入到HTML模板
|
|
60
|
+
- id: zm-java-xss-format-001
|
|
61
|
+
severity: MEDIUM
|
|
62
|
+
message: |
|
|
63
|
+
String.format 将用户输入直接拼入 HTML 片段 — 产生 XSS。
|
|
64
|
+
使用参数化模板(Thymeleaf th:text / JSP c:out)替代 Java 字符串拼接。
|
|
65
|
+
languages:
|
|
66
|
+
- java
|
|
67
|
+
pattern-either:
|
|
68
|
+
- pattern: String.format("<$TAG>$CONTENT</$TAG>", $X, ...)
|
|
69
|
+
- pattern: |
|
|
70
|
+
String.format("...<...%s...>...", $X, ...)
|
|
71
|
+
metadata:
|
|
72
|
+
cwe: "CWE-79: Cross-site Scripting (XSS)"
|
|
73
|
+
owasp: "A03:2021 - Injection"
|
|
74
|
+
precision: medium
|
|
75
|
+
tags: [xss, string-format, html-injection]
|
|
76
|
+
|
|
77
|
+
# ZM-JAVA-XSS-SPRING-ESCAPE-001: 显式使用 springHtmlEscape=false
|
|
78
|
+
- id: zm-java-xss-escape-001
|
|
79
|
+
severity: MEDIUM
|
|
80
|
+
message: |
|
|
81
|
+
HtmlEscape 设置为 false 或 defaultHtmlEscape = false — 禁用自动 HTML 转义。
|
|
82
|
+
启用 defaultHtmlEscape 或逐页设置 `spring:htmlEscape="true"`。
|
|
83
|
+
languages:
|
|
84
|
+
- java
|
|
85
|
+
pattern-either:
|
|
86
|
+
- pattern: |
|
|
87
|
+
htmlEscape = false
|
|
88
|
+
- pattern: |
|
|
89
|
+
setHtmlEscape(false)
|
|
90
|
+
- pattern: |
|
|
91
|
+
defaultHtmlEscape = false
|
|
92
|
+
- pattern: |
|
|
93
|
+
setDefaultHtmlEscape(false)
|
|
94
|
+
metadata:
|
|
95
|
+
cwe: "CWE-79: Cross-site Scripting (XSS)"
|
|
96
|
+
owasp: "A03:2021 - Injection"
|
|
97
|
+
precision: very-high
|
|
98
|
+
tags: [xss, spring, html-escape]
|