@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,85 @@
|
|
|
1
|
+
# CWE-94: SpEL Injection — deeper Spring expression variants
|
|
2
|
+
# ZhuMa V4.1 — complement zm-java-cwe94-spel.yaml
|
|
3
|
+
|
|
4
|
+
rules:
|
|
5
|
+
|
|
6
|
+
# ZM-JAVA-SPEL-DEEP-001: EvaluationContext.setVariable() + user input
|
|
7
|
+
- id: zm-java-spel-deep-001
|
|
8
|
+
severity: ERROR
|
|
9
|
+
message: |
|
|
10
|
+
EvaluationContext.setVariable() receives user-supplied value which is then evaluated via getValue().
|
|
11
|
+
Even with SimpleEvaluationContext, attacker-controlled SpEL expressions can cause DoS or unexpected behavior.
|
|
12
|
+
Fix: sanitize variable values; never pass raw user input as variable value to SpEL evaluation.
|
|
13
|
+
languages:
|
|
14
|
+
- java
|
|
15
|
+
pattern-either:
|
|
16
|
+
- pattern: |
|
|
17
|
+
$CTX.setVariable($NAME, $REQ.getParameter(...));
|
|
18
|
+
...
|
|
19
|
+
$PARSER.parseExpression($EXPR).getValue($CTX);
|
|
20
|
+
- pattern: |
|
|
21
|
+
$CTX.setVariable($NAME, $REQ.getHeader(...));
|
|
22
|
+
...
|
|
23
|
+
$PARSER.parseExpression($EXPR).getValue($CTX);
|
|
24
|
+
- pattern: |
|
|
25
|
+
$PARSER.parseExpression($EXPR).setVariable($NAME, $REQ.getParameter(...)).getValue();
|
|
26
|
+
metadata:
|
|
27
|
+
cwe: "CWE-94: Improper Control of Generation of Code (Code Injection)"
|
|
28
|
+
severity: ERROR
|
|
29
|
+
precision: medium
|
|
30
|
+
category: code-injection
|
|
31
|
+
likelihood: HIGH
|
|
32
|
+
impact: CRITICAL
|
|
33
|
+
owasp: "A03:2021 - Injection"
|
|
34
|
+
|
|
35
|
+
# ZM-JAVA-SPEL-DEEP-002: ExpressionParser with TemplateParserContext (template mode)
|
|
36
|
+
- id: zm-java-spel-deep-002
|
|
37
|
+
severity: HIGH
|
|
38
|
+
message: |
|
|
39
|
+
SpEL expression with TemplateParserContext (mixed template+expression) uses user input.
|
|
40
|
+
Attackers can embed #{T(java.lang.Runtime).exec("cmd")} inside template strings.
|
|
41
|
+
Fix: disable template mode for user input; use fixed template strings only.
|
|
42
|
+
languages:
|
|
43
|
+
- java
|
|
44
|
+
pattern-either:
|
|
45
|
+
- pattern: |
|
|
46
|
+
$PARSER.parseExpression($REQ.getParameter(...), new TemplateParserContext())
|
|
47
|
+
- pattern: |
|
|
48
|
+
$PARSER.parseExpression($REQ.getParameter(...), new TemplateParserContext()).getValue()
|
|
49
|
+
- pattern: |
|
|
50
|
+
$PARSER.parseExpression($REQ.getHeader(...), new TemplateParserContext())
|
|
51
|
+
metadata:
|
|
52
|
+
cwe: "CWE-94: Improper Control of Generation of Code (Code Injection)"
|
|
53
|
+
severity: HIGH
|
|
54
|
+
precision: high
|
|
55
|
+
category: code-injection
|
|
56
|
+
likelihood: MEDIUM
|
|
57
|
+
impact: CRITICAL
|
|
58
|
+
owasp: "A03:2021 - Injection"
|
|
59
|
+
|
|
60
|
+
# ZM-JAVA-SPEL-DEEP-003: SpEL expression from request body or attribute
|
|
61
|
+
- id: zm-java-spel-deep-003
|
|
62
|
+
severity: ERROR
|
|
63
|
+
message: |
|
|
64
|
+
SpelExpressionParser.parseExpression() with request body/attribute — attacker injects SpEL via JSON/XML body.
|
|
65
|
+
This is the Spring Cloud Function SpEL injection pattern (CVE-2022-22963).
|
|
66
|
+
Fix: never evaluate SpEL expressions from HTTP request body; use SimpleEvaluationContext if needed.
|
|
67
|
+
languages:
|
|
68
|
+
- java
|
|
69
|
+
pattern-either:
|
|
70
|
+
- pattern: |
|
|
71
|
+
new SpelExpressionParser().parseExpression($REQ.getReader().readLine()).getValue()
|
|
72
|
+
- pattern: |
|
|
73
|
+
new SpelExpressionParser().parseExpression($REQ.getInputStream()).getValue()
|
|
74
|
+
- pattern: |
|
|
75
|
+
new SpelExpressionParser().parseExpression($REQ.getParameter(...)).getValue($CTX)
|
|
76
|
+
metadata:
|
|
77
|
+
cwe: "CWE-94: Improper Control of Generation of Code (Code Injection)"
|
|
78
|
+
severity: ERROR
|
|
79
|
+
precision: high
|
|
80
|
+
category: code-injection
|
|
81
|
+
likelihood: HIGH
|
|
82
|
+
impact: CRITICAL
|
|
83
|
+
owasp: "A03:2021 - Injection"
|
|
84
|
+
references:
|
|
85
|
+
- "https://nvd.nist.gov/vuln/detail/CVE-2022-22963"
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# CWE-94: Spring Expression Language (SpEL) 表达式注入检测
|
|
2
|
+
# 逐码 ZhuMa V4.1 — 通用规则库
|
|
3
|
+
# 检测: SpelExpressionParser.parseExpression() 且参数来自 HTTP request
|
|
4
|
+
|
|
5
|
+
rules:
|
|
6
|
+
|
|
7
|
+
# ZM-JAVA-SPEL-001: SpEL parseExpression() 用户可控
|
|
8
|
+
- id: zm-java-spel-001
|
|
9
|
+
severity: ERROR
|
|
10
|
+
message: |
|
|
11
|
+
检测到 SpelExpressionParser.parseExpression() 的参数可能来自 HTTP 请求(用户可控)。
|
|
12
|
+
SpEL 表达式可调用任意 Java 方法、访问系统属性、执行命令。
|
|
13
|
+
攻击者可通过注入 SpEL 表达式实现远程代码执行(RCE)。
|
|
14
|
+
修复方案:
|
|
15
|
+
1. 禁止将用户输入直接传入 parseExpression()
|
|
16
|
+
2. 使用 SimpleEvaluationContext 替代 StandardEvaluationContext(限制表达式能力)
|
|
17
|
+
3. 对用户输入使用白名单校验或预定义表达式映射
|
|
18
|
+
4. 使用非表达式逻辑实现业务需求
|
|
19
|
+
参考: CVE-2022-22963 (Spring Cloud Function SpEL RCE)
|
|
20
|
+
languages:
|
|
21
|
+
- java
|
|
22
|
+
patterns:
|
|
23
|
+
- pattern-either:
|
|
24
|
+
- pattern: |
|
|
25
|
+
new SpelExpressionParser().parseExpression($REQ.getParameter(...));
|
|
26
|
+
- pattern: |
|
|
27
|
+
new SpelExpressionParser().parseExpression($REQ.getHeader(...));
|
|
28
|
+
- pattern: |
|
|
29
|
+
new SpelExpressionParser().parseExpression($REQ.getParameter(...)).getValue(...);
|
|
30
|
+
- pattern: |
|
|
31
|
+
new SpelExpressionParser().parseExpression($REQ.getHeader(...)).getValue(...);
|
|
32
|
+
- pattern: |
|
|
33
|
+
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
|
34
|
+
...
|
|
35
|
+
metadata:
|
|
36
|
+
cwe: "CWE-94: Improper Control of Generation of Code (Code Injection)"
|
|
37
|
+
severity: ERROR
|
|
38
|
+
precision: high
|
|
39
|
+
category: code-injection
|
|
40
|
+
likelihood: HIGH
|
|
41
|
+
impact: CRITICAL
|
|
42
|
+
owasp: "A03:2021 - Injection"
|
|
43
|
+
references:
|
|
44
|
+
- "https://nvd.nist.gov/vuln/detail/CVE-2022-22963"
|
|
45
|
+
- "https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/expression/spel/standard/SpelExpressionParser.html"
|
|
46
|
+
|
|
47
|
+
# ZM-JAVA-SPEL-002: SpEL parseExpression() 拼接变量 (可疑)
|
|
48
|
+
- id: zm-java-spel-002
|
|
49
|
+
severity: ERROR
|
|
50
|
+
message: |
|
|
51
|
+
检测到 SpelExpressionParser.parseExpression() 的参数可能由变量拼接构成。
|
|
52
|
+
若该变量来自 HTTP 请求参数,攻击者可注入 SpEL 表达式实现 RCE。
|
|
53
|
+
修复方案:
|
|
54
|
+
1. 确认变量来源是否为用户可控,若来自 request 则必须立即修复
|
|
55
|
+
2. 使用 SimpleEvaluationContext + 白名单限制表达式能力
|
|
56
|
+
3. 对表达式内容做严格的正则/白名单过滤
|
|
57
|
+
languages:
|
|
58
|
+
- java
|
|
59
|
+
pattern-either:
|
|
60
|
+
- pattern: |
|
|
61
|
+
new SpelExpressionParser().parseExpression($EXPR);
|
|
62
|
+
...
|
|
63
|
+
$EXPR = $REQ.getParameter(...);
|
|
64
|
+
...
|
|
65
|
+
- pattern: |
|
|
66
|
+
$EXPR = $REQ.getParameter(...);
|
|
67
|
+
...
|
|
68
|
+
new SpelExpressionParser().parseExpression($EXPR);
|
|
69
|
+
...
|
|
70
|
+
- pattern: |
|
|
71
|
+
$EXPR = $REQ.getHeader(...);
|
|
72
|
+
...
|
|
73
|
+
new SpelExpressionParser().parseExpression($EXPR);
|
|
74
|
+
...
|
|
75
|
+
metadata:
|
|
76
|
+
cwe: "CWE-94: Improper Control of Generation of Code (Code Injection)"
|
|
77
|
+
severity: ERROR
|
|
78
|
+
precision: medium
|
|
79
|
+
category: code-injection
|
|
80
|
+
likelihood: MEDIUM
|
|
81
|
+
impact: CRITICAL
|
|
82
|
+
owasp: "A03:2021 - Injection"
|
|
83
|
+
|
|
84
|
+
# ZM-JAVA-SPEL-003: ExpressionParser.parseExpression() 通用匹配
|
|
85
|
+
- id: zm-java-spel-003
|
|
86
|
+
severity: HIGH
|
|
87
|
+
message: |
|
|
88
|
+
检测到 ExpressionParser.parseExpression() 调用,参数可能是用户可控的 HTTP 参数。
|
|
89
|
+
SpEL 表达式注入可导致任意代码执行。
|
|
90
|
+
修复方案:
|
|
91
|
+
1. 禁止将用户输入传入表达式解析器
|
|
92
|
+
2. 使用 SimpleEvaluationContext 替代默认上下文
|
|
93
|
+
3. 对输入进行白名单校验
|
|
94
|
+
languages:
|
|
95
|
+
- java
|
|
96
|
+
patterns:
|
|
97
|
+
- pattern-either:
|
|
98
|
+
- pattern: |
|
|
99
|
+
$PARSER.parseExpression($REQ.getParameter(...))
|
|
100
|
+
- pattern: |
|
|
101
|
+
$PARSER.parseExpression($REQ.getHeader(...))
|
|
102
|
+
- pattern-inside: |
|
|
103
|
+
import org.springframework.expression.ExpressionParser;
|
|
104
|
+
...
|
|
105
|
+
metadata:
|
|
106
|
+
cwe: "CWE-94: Improper Control of Generation of Code (Code Injection)"
|
|
107
|
+
severity: HIGH
|
|
108
|
+
precision: high
|
|
109
|
+
category: code-injection
|
|
110
|
+
likelihood: HIGH
|
|
111
|
+
impact: CRITICAL
|
|
112
|
+
owasp: "A03:2021 - Injection"
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# CWE-94: Java SSTI 模板注入检测
|
|
2
|
+
rules:
|
|
3
|
+
- id: zm-java-ssti-01
|
|
4
|
+
severity: ERROR
|
|
5
|
+
message: Thymeleaf processTemplate() 参数用户可控,可导致服务端模板注入(SSTI) RCE。
|
|
6
|
+
languages: [java]
|
|
7
|
+
pattern: $CTX.processTemplate($REQ.getParameter($PARAM), ...)
|
|
8
|
+
metadata: { cwe: "CWE-94", precision: high, category: code-injection, owasp: "A03:2021 - Injection" }
|
|
9
|
+
|
|
10
|
+
- id: zm-java-ssti-02
|
|
11
|
+
severity: ERROR
|
|
12
|
+
message: FreeMarker Template.process() 参数来自用户输入,可导致SSTI RCE。
|
|
13
|
+
languages: [java]
|
|
14
|
+
pattern: $TEMPLATE.process($REQ.getParameter($PARAM), ...)
|
|
15
|
+
metadata: { cwe: "CWE-94", precision: high, category: code-injection, owasp: "A03:2021 - Injection" }
|
|
16
|
+
|
|
17
|
+
- id: zm-java-ssti-03
|
|
18
|
+
severity: ERROR
|
|
19
|
+
message: Velocity evaluate() 用户输入可导致SSTI RCE。
|
|
20
|
+
languages: [java]
|
|
21
|
+
pattern: Velocity.evaluate($CTX, $WRITER, $LOG, $REQ.getParameter($PARAM))
|
|
22
|
+
metadata: { cwe: "CWE-94", precision: high, category: code-injection, owasp: "A03:2021 - Injection" }
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# CWE-942: Java CORS 通配符配置缺陷
|
|
2
|
+
rules:
|
|
3
|
+
- id: zm-java-cors-01
|
|
4
|
+
severity: WARNING
|
|
5
|
+
message: '@CrossOrigin(origins="*") 允许任意域跨域访问,可能导致CSRF/数据泄露。'
|
|
6
|
+
languages: [java]
|
|
7
|
+
pattern: '@CrossOrigin(origins = "*")'
|
|
8
|
+
metadata: { cwe: "CWE-942", precision: very-high, category: config, owasp: "A05:2021 - Security Misconfiguration" }
|
|
9
|
+
|
|
10
|
+
- id: zm-java-cors-02
|
|
11
|
+
severity: WARNING
|
|
12
|
+
message: CorsConfiguration.addAllowedOrigin("*") 通配符允许任意域跨域。
|
|
13
|
+
languages: [java]
|
|
14
|
+
pattern: $CONFIG.addAllowedOrigin("*")
|
|
15
|
+
metadata: { cwe: "CWE-942", precision: very-high, category: config, owasp: "A05:2021" }
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# CWE-1321: 原型链污染检测规则
|
|
2
|
+
# 逐码 ZhuMa V4.1 Sprint 1 — JS/TS 通用规则库
|
|
3
|
+
|
|
4
|
+
rules:
|
|
5
|
+
|
|
6
|
+
- id: zm-js-pp-001
|
|
7
|
+
severity: ERROR
|
|
8
|
+
message: |
|
|
9
|
+
检测到将用户可控数据(req.body / req.query / req.params)通过动态键赋值
|
|
10
|
+
到对象嵌套属性,可能导致原型链污染。
|
|
11
|
+
修复: 1.Object.create(null)创建无原型对象 2.过滤__proto__/constructor/prototype键名
|
|
12
|
+
3.使用Map替代普通对象 4.检查lodash.merge版本(<4.17.12存在漏洞)
|
|
13
|
+
languages:
|
|
14
|
+
- javascript
|
|
15
|
+
- typescript
|
|
16
|
+
pattern-either:
|
|
17
|
+
- pattern: |
|
|
18
|
+
$OBJ[$REQ.body] = $VAL
|
|
19
|
+
- pattern: |
|
|
20
|
+
$OBJ[$REQ.query] = $VAL
|
|
21
|
+
- pattern: |
|
|
22
|
+
$OBJ[$REQ.params] = $VAL
|
|
23
|
+
- pattern: |
|
|
24
|
+
$OBJ[$KEY] = $REQ.body
|
|
25
|
+
- pattern: |
|
|
26
|
+
$OBJ[$KEY] = $REQ.query
|
|
27
|
+
- pattern: |
|
|
28
|
+
$OBJ[$KEY] = $REQ.params
|
|
29
|
+
metadata:
|
|
30
|
+
cwe: "CWE-1321"
|
|
31
|
+
severity: ERROR
|
|
32
|
+
precision: medium
|
|
33
|
+
category: code-injection
|
|
34
|
+
owasp: "A08:2021 - Software and Data Integrity Failures"
|
|
35
|
+
|
|
36
|
+
- id: zm-js-pp-002
|
|
37
|
+
severity: ERROR
|
|
38
|
+
message: |
|
|
39
|
+
检测到对 __proto__ 或 constructor.prototype 的直接赋值操作。
|
|
40
|
+
这是原型链污染的典型模式。
|
|
41
|
+
修复: 1.禁止对__proto__和constructor.prototype赋值 2.冻结原型: Object.freeze(Object.prototype)
|
|
42
|
+
languages:
|
|
43
|
+
- javascript
|
|
44
|
+
- typescript
|
|
45
|
+
pattern-either:
|
|
46
|
+
- pattern: |
|
|
47
|
+
$OBJ.__proto__ = $VAL
|
|
48
|
+
- pattern: |
|
|
49
|
+
$OBJ['__proto__'] = $VAL
|
|
50
|
+
- pattern: |
|
|
51
|
+
$OBJ.constructor.prototype = $VAL
|
|
52
|
+
- pattern: |
|
|
53
|
+
$OBJ.constructor.prototype.$PROP = $VAL
|
|
54
|
+
- pattern: |
|
|
55
|
+
$OBJ.__proto__.$PROP = $VAL
|
|
56
|
+
metadata:
|
|
57
|
+
cwe: "CWE-1321"
|
|
58
|
+
severity: ERROR
|
|
59
|
+
precision: very-high
|
|
60
|
+
category: code-injection
|
|
61
|
+
owasp: "A08:2021"
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# CWE-200: Node.js 敏感信息泄露检测规则
|
|
2
|
+
# 逐码 ZhuMa V4.1 Sprint 2 — JS/TS 规则库
|
|
3
|
+
# 覆盖: Error stack trace 返回、console.log 含密码、helmet 未配置、res.json(err) 内网信息
|
|
4
|
+
|
|
5
|
+
rules:
|
|
6
|
+
|
|
7
|
+
# ZM-JS-INFO-001: 错误处理中直接返回 error stack trace
|
|
8
|
+
- id: zm-js-info-001
|
|
9
|
+
severity: WARNING
|
|
10
|
+
message: |
|
|
11
|
+
检测到HTTP响应中直接返回 error.stack / err (可能未脱敏)。
|
|
12
|
+
泄露服务器路径/依赖版本等信息。
|
|
13
|
+
修复: 生产环境返回通用错误 res.send({ error: 'Internal Server Error' })。
|
|
14
|
+
languages:
|
|
15
|
+
- javascript
|
|
16
|
+
- typescript
|
|
17
|
+
patterns:
|
|
18
|
+
- pattern-either:
|
|
19
|
+
- pattern: $RES.send($ERR.stack)
|
|
20
|
+
- pattern: $RES.json($ERR.stack)
|
|
21
|
+
- pattern-not: |
|
|
22
|
+
...;
|
|
23
|
+
$RES.send({...});
|
|
24
|
+
metadata:
|
|
25
|
+
cwe: "CWE-200: Exposure of Sensitive Information to an Unauthorized Actor"
|
|
26
|
+
owasp: "A04:2021 - Insecure Design"
|
|
27
|
+
category: info-disclosure
|
|
28
|
+
precision: high
|
|
29
|
+
references:
|
|
30
|
+
- "https://cheatsheetseries.owasp.org/cheatsheets/Error_Handling_Cheat_Sheet.html"
|
|
31
|
+
|
|
32
|
+
# ZM-JS-INFO-002: console.log 输出敏感信息
|
|
33
|
+
- id: zm-js-info-002
|
|
34
|
+
severity: WARNING
|
|
35
|
+
message: |
|
|
36
|
+
检测到 console.log 可能输出了 password / token / secret 等敏感字段。
|
|
37
|
+
生产环境日志可能被持久化存储,造成凭据泄露。
|
|
38
|
+
修复: 使用日志脱敏库(pino.redact)或生产环境禁用 console 输出。
|
|
39
|
+
languages:
|
|
40
|
+
- javascript
|
|
41
|
+
- typescript
|
|
42
|
+
patterns:
|
|
43
|
+
- pattern: console.$FUNC(...)
|
|
44
|
+
- metavariable-regex:
|
|
45
|
+
metavariable: $FUNC
|
|
46
|
+
regex: ^(log|error|warn)$
|
|
47
|
+
- pattern: |
|
|
48
|
+
console.$FUNC($OBJ.$FIELD, ...)
|
|
49
|
+
- metavariable-regex:
|
|
50
|
+
metavariable: $FIELD
|
|
51
|
+
regex: ^(password|passwd|token|secret|apiKey|api_key|credential|accessKey|access_key|privateKey|private_key)$
|
|
52
|
+
metadata:
|
|
53
|
+
cwe: "CWE-200: Exposure of Sensitive Information to an Unauthorized Actor"
|
|
54
|
+
owasp: "A04:2021 - Insecure Design"
|
|
55
|
+
category: info-disclosure
|
|
56
|
+
precision: high
|
|
57
|
+
references:
|
|
58
|
+
- "https://cwe.mitre.org/data/definitions/532.html"
|
|
59
|
+
|
|
60
|
+
# ZM-JS-INFO-003: Helmet 安全头未配置 / 缺失
|
|
61
|
+
- id: zm-js-info-003
|
|
62
|
+
severity: WARNING
|
|
63
|
+
message: |
|
|
64
|
+
检测到 Express 应用可能未启用 helmet 安全头中间件。
|
|
65
|
+
缺少安全响应头可能导致信息泄露 (X-Powered-By 暴露技术栈)、
|
|
66
|
+
点击劫持 (X-Frame-Options)、MIME sniffing 等风险。
|
|
67
|
+
|
|
68
|
+
修复:
|
|
69
|
+
1. app.use(helmet()) — 启用默认安全头
|
|
70
|
+
2. 至少手动设置:
|
|
71
|
+
- X-Content-Type-Options: nosniff
|
|
72
|
+
- X-Frame-Options: DENY
|
|
73
|
+
- X-XSS-Protection: 0 (已废弃,但保留)
|
|
74
|
+
- Referrer-Policy: no-referrer
|
|
75
|
+
- Strict-Transport-Security: max-age=31536000
|
|
76
|
+
- 移除 X-Powered-By 头: app.disable('x-powered-by')
|
|
77
|
+
3. helmet.contentSecurityPolicy() 配置CSP防止XSS
|
|
78
|
+
languages:
|
|
79
|
+
- javascript
|
|
80
|
+
- typescript
|
|
81
|
+
pattern-either:
|
|
82
|
+
- pattern: |
|
|
83
|
+
const express = require('express')
|
|
84
|
+
...
|
|
85
|
+
const app = express()
|
|
86
|
+
# 检测 express() 调用但无 helmet
|
|
87
|
+
- pattern: $APP.listen(...)
|
|
88
|
+
metadata:
|
|
89
|
+
cwe: "CWE-200: Exposure of Sensitive Information to an Unauthorized Actor"
|
|
90
|
+
owasp: "A05:2021 - Security Misconfiguration"
|
|
91
|
+
category: info-disclosure
|
|
92
|
+
precision: low
|
|
93
|
+
references:
|
|
94
|
+
- "https://helmetjs.github.io/"
|
|
95
|
+
- "https://expressjs.com/en/advanced/best-practice-security.html"
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# CWE-22: Node.js 文件系统路径穿越深度检测
|
|
2
|
+
# 逐码 ZhuMa V4.1 Sprint — JS/TS 规则库
|
|
3
|
+
# 覆盖: fs.readFile/writeFile + userInput 路径拼接
|
|
4
|
+
|
|
5
|
+
rules:
|
|
6
|
+
|
|
7
|
+
# ZM-JS-PT-FS-001: fs.readFile / readFileSync 用户输入路径
|
|
8
|
+
- id: zm-js-pt-fs-001
|
|
9
|
+
severity: ERROR
|
|
10
|
+
message: |
|
|
11
|
+
检测到 fs.readFile / fs.readFileSync / fs.createReadStream 使用用户可控的路径参数。
|
|
12
|
+
攻击者可输入 ../../etc/passwd 或 /proc/self/environ 等路径穿越读取任意文件。
|
|
13
|
+
|
|
14
|
+
修复:
|
|
15
|
+
1. 使用 path.resolve + path.normalize 规范化路径后,验证是否在允许的基础目录内:
|
|
16
|
+
const safePath = path.resolve(baseDir, path.normalize(userInput))
|
|
17
|
+
if (!safePath.startsWith(path.resolve(baseDir))) { throw new Error('Path traversal detected') }
|
|
18
|
+
2. 使用 path.basename() 仅提取文件名,丢弃路径部分
|
|
19
|
+
3. 对用户输入的文件名做白名单校验
|
|
20
|
+
4. 将文件存储在非Web可访问目录中
|
|
21
|
+
languages:
|
|
22
|
+
- javascript
|
|
23
|
+
- typescript
|
|
24
|
+
pattern-either:
|
|
25
|
+
- pattern: fs.readFile($REQ.query.$PARAM, ...)
|
|
26
|
+
- pattern: fs.readFile($REQ.params.$PARAM, ...)
|
|
27
|
+
- pattern: fs.readFile($REQ.body.$PARAM, ...)
|
|
28
|
+
- pattern: fs.readFileSync($REQ.query.$PARAM, ...)
|
|
29
|
+
- pattern: fs.readFileSync($REQ.params.$PARAM, ...)
|
|
30
|
+
- pattern: fs.readFileSync($REQ.body.$PARAM, ...)
|
|
31
|
+
- pattern: fs.createReadStream($REQ.query.$PARAM, ...)
|
|
32
|
+
- pattern: fs.createReadStream($REQ.params.$PARAM, ...)
|
|
33
|
+
- pattern: fs.createReadStream($REQ.body.$PARAM, ...)
|
|
34
|
+
- pattern: fsPromises.readFile($REQ.query.$PARAM, ...)
|
|
35
|
+
- pattern: fsPromises.readFile($REQ.params.$PARAM, ...)
|
|
36
|
+
- pattern: fsPromises.readFile($REQ.body.$PARAM, ...)
|
|
37
|
+
metadata:
|
|
38
|
+
cwe: "CWE-22: Improper Limitation of a Pathname to a Restricted Directory (Path Traversal)"
|
|
39
|
+
owasp: "A01:2021 - Broken Access Control"
|
|
40
|
+
category: path-traversal
|
|
41
|
+
precision: high
|
|
42
|
+
confidence: high
|
|
43
|
+
references:
|
|
44
|
+
- "https://owasp.org/www-community/attacks/Path_Traversal"
|
|
45
|
+
|
|
46
|
+
# ZM-JS-PT-FS-002: fs.writeFile / writeFileSync 用户输入路径写入
|
|
47
|
+
- id: zm-js-pt-fs-002
|
|
48
|
+
severity: ERROR
|
|
49
|
+
message: |
|
|
50
|
+
检测到 fs.writeFile / fs.writeFileSync / fs.createWriteStream 使用用户可控的路径参数。
|
|
51
|
+
攻击者可写入任意路径文件,覆盖配置文件、植入webshell,或向系统目录写入恶意文件。
|
|
52
|
+
|
|
53
|
+
修复:
|
|
54
|
+
1. 规范化路径并验证在允许的基础目录内
|
|
55
|
+
2. 限制文件扩展名白名单(如仅 .txt .log)
|
|
56
|
+
3. 对用户输入的文件名做严格的白名单校验
|
|
57
|
+
4. 使用随机文件名(uuid)而非用户提供文件名
|
|
58
|
+
languages:
|
|
59
|
+
- javascript
|
|
60
|
+
- typescript
|
|
61
|
+
pattern-either:
|
|
62
|
+
- pattern: fs.writeFile($REQ.query.$PARAM, ...)
|
|
63
|
+
- pattern: fs.writeFile($REQ.params.$PARAM, ...)
|
|
64
|
+
- pattern: fs.writeFile($REQ.body.$PARAM, ...)
|
|
65
|
+
- pattern: fs.writeFileSync($REQ.query.$PARAM, ...)
|
|
66
|
+
- pattern: fs.writeFileSync($REQ.params.$PARAM, ...)
|
|
67
|
+
- pattern: fs.writeFileSync($REQ.body.$PARAM, ...)
|
|
68
|
+
- pattern: fs.createWriteStream($REQ.query.$PARAM, ...)
|
|
69
|
+
- pattern: fs.createWriteStream($REQ.params.$PARAM, ...)
|
|
70
|
+
- pattern: fs.createWriteStream($REQ.body.$PARAM, ...)
|
|
71
|
+
- pattern: fsPromises.writeFile($REQ.query.$PARAM, ...)
|
|
72
|
+
- pattern: fsPromises.writeFile($REQ.params.$PARAM, ...)
|
|
73
|
+
- pattern: fsPromises.writeFile($REQ.body.$PARAM, ...)
|
|
74
|
+
metadata:
|
|
75
|
+
cwe: "CWE-22: Improper Limitation of a Pathname to a Restricted Directory (Path Traversal)"
|
|
76
|
+
owasp: "A01:2021 - Broken Access Control"
|
|
77
|
+
category: path-traversal
|
|
78
|
+
precision: high
|
|
79
|
+
confidence: high
|
|
80
|
+
references:
|
|
81
|
+
- "https://owasp.org/www-community/attacks/Path_Traversal"
|
|
82
|
+
|
|
83
|
+
# ZM-JS-PT-FS-003: 路径拼接 + fs操作 (低精度,需人工确认)
|
|
84
|
+
- id: zm-js-pt-fs-003
|
|
85
|
+
severity: WARNING
|
|
86
|
+
message: |
|
|
87
|
+
检测到路径拼接后传入 fs 文件操作,需确认拼接变量是否来自用户输入。
|
|
88
|
+
若拼接变量可控,存在路径穿越风险。
|
|
89
|
+
|
|
90
|
+
修复:
|
|
91
|
+
1. 追踪变量来源,确认是否为用户输入
|
|
92
|
+
2. 使用 path.resolve + path.normalize 规范化
|
|
93
|
+
3. 验证结果路径的基础目录前缀
|
|
94
|
+
languages:
|
|
95
|
+
- javascript
|
|
96
|
+
- typescript
|
|
97
|
+
pattern-either:
|
|
98
|
+
- pattern: fs.readFile($DIR + $INPUT, ...)
|
|
99
|
+
- pattern: fs.readFileSync($DIR + $INPUT, ...)
|
|
100
|
+
- pattern: fs.writeFile($DIR + $INPUT, ...)
|
|
101
|
+
- pattern: fs.writeFileSync($DIR + $INPUT, ...)
|
|
102
|
+
- pattern: fs.createReadStream($DIR + $INPUT, ...)
|
|
103
|
+
- pattern: fs.createWriteStream($DIR + $INPUT, ...)
|
|
104
|
+
- pattern: fsPromises.readFile($DIR + $INPUT, ...)
|
|
105
|
+
- pattern: fsPromises.writeFile($DIR + $INPUT, ...)
|
|
106
|
+
metadata:
|
|
107
|
+
cwe: "CWE-22: Improper Limitation of a Pathname to a Restricted Directory (Path Traversal)"
|
|
108
|
+
owasp: "A01:2021 - Broken Access Control"
|
|
109
|
+
category: path-traversal
|
|
110
|
+
precision: low
|
|
111
|
+
confidence: medium
|
|
112
|
+
references:
|
|
113
|
+
- "https://owasp.org/www-community/attacks/Path_Traversal"
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# CWE-22: Node.js 路径穿越检测规则
|
|
2
|
+
# 逐码 ZhuMa V4.1 Sprint 2 — FPR 优化版
|
|
3
|
+
# 变更: zm-js-pt-001 拆为两版——高精度(用户输入源) + 低精度(通用路径拼接)
|
|
4
|
+
# 原因: path.join($INPUT) 匹配到 fs.readdirSync 结果等非用户输入,FPR=100%
|
|
5
|
+
|
|
6
|
+
rules:
|
|
7
|
+
|
|
8
|
+
# ZM-JS-PT-001: fs.readFile + req.query/params/body 直接导致路径穿越 (高精度)
|
|
9
|
+
- id: zm-js-pt-001
|
|
10
|
+
severity: ERROR
|
|
11
|
+
message: |
|
|
12
|
+
fs 读取操作使用 req.query/req.params/req.body 直接拼接路径,确认用户可控输入。
|
|
13
|
+
攻击者可注入 ../ 穿越目录读取任意文件。
|
|
14
|
+
|
|
15
|
+
修复:
|
|
16
|
+
1. path.normalize() + 路径前缀白名单校验
|
|
17
|
+
2. 禁止用户输入直接拼入文件路径
|
|
18
|
+
3. express.static 设置 dotfiles: 'deny'
|
|
19
|
+
languages:
|
|
20
|
+
- javascript
|
|
21
|
+
- typescript
|
|
22
|
+
pattern-either:
|
|
23
|
+
- pattern: |
|
|
24
|
+
fs.readFile($REQ.query.$PARAM, ...)
|
|
25
|
+
- pattern: |
|
|
26
|
+
fs.readFileSync($REQ.query.$PARAM, ...)
|
|
27
|
+
- pattern: |
|
|
28
|
+
fs.readFile($REQ.params.$PARAM, ...)
|
|
29
|
+
- pattern: |
|
|
30
|
+
fs.readFileSync($REQ.params.$PARAM, ...)
|
|
31
|
+
- pattern: |
|
|
32
|
+
fs.readFile($REQ.body.$PARAM, ...)
|
|
33
|
+
- pattern: |
|
|
34
|
+
fs.readFileSync($REQ.body.$PARAM, ...)
|
|
35
|
+
- pattern: |
|
|
36
|
+
fs.createReadStream($REQ.query.$PARAM)
|
|
37
|
+
- pattern: |
|
|
38
|
+
fs.createReadStream($REQ.params.$PARAM)
|
|
39
|
+
- pattern: |
|
|
40
|
+
fs.createReadStream($REQ.body.$PARAM)
|
|
41
|
+
- pattern: |
|
|
42
|
+
fs.readFile(path.resolve($ROOT, $REQ.query.$PARAM), ...)
|
|
43
|
+
- pattern: |
|
|
44
|
+
fs.readFileSync(path.resolve($ROOT, $REQ.query.$PARAM), ...)
|
|
45
|
+
- pattern: |
|
|
46
|
+
fs.readFile(path.join($ROOT, $REQ.query.$PARAM), ...)
|
|
47
|
+
- pattern: |
|
|
48
|
+
fs.readFileSync(path.join($ROOT, $REQ.query.$PARAM), ...)
|
|
49
|
+
metadata:
|
|
50
|
+
cwe: "CWE-22: Path Traversal"
|
|
51
|
+
owasp: "A01:2021 - Broken Access Control"
|
|
52
|
+
category: path-traversal
|
|
53
|
+
precision: high
|
|
54
|
+
references:
|
|
55
|
+
- "https://owasp.org/www-community/attacks/Path_Traversal"
|
|
56
|
+
|
|
57
|
+
# ZM-JS-PT-003: fs.readFile + 任意变量路径拼接 (低精度,需人工复核)
|
|
58
|
+
- id: zm-js-pt-003
|
|
59
|
+
severity: WARNING
|
|
60
|
+
message: |
|
|
61
|
+
fs 读取操作使用了动态路径拼接,可能是路径穿越风险(也可能是安全的内部文件读取)。
|
|
62
|
+
需人工确认变量来源是否为用户可控输入。
|
|
63
|
+
|
|
64
|
+
修复:
|
|
65
|
+
1. 如果变量来自 req.query/params/body,必须做路径前缀白名单校验
|
|
66
|
+
2. 如果是 fs.readdirSync 结果(同目录遍历),忽略本规则
|
|
67
|
+
3. 使用 path.normalize() 规范化后验证前缀在允许目录内
|
|
68
|
+
languages:
|
|
69
|
+
- javascript
|
|
70
|
+
- typescript
|
|
71
|
+
pattern-either:
|
|
72
|
+
- pattern: |
|
|
73
|
+
fs.readFile(path.resolve($ROOT, $INPUT), ...)
|
|
74
|
+
- pattern: |
|
|
75
|
+
fs.readFileSync(path.resolve($ROOT, $INPUT), ...)
|
|
76
|
+
- pattern: |
|
|
77
|
+
fs.readFile(path.join($INPUT, ...), ...)
|
|
78
|
+
- pattern: |
|
|
79
|
+
fs.readFileSync(path.join($INPUT, ...), ...)
|
|
80
|
+
- pattern: |
|
|
81
|
+
fs.createReadStream(path.join($INPUT, ...))
|
|
82
|
+
- pattern: |
|
|
83
|
+
fs.createReadStream(path.resolve($ROOT, $INPUT))
|
|
84
|
+
metadata:
|
|
85
|
+
cwe: "CWE-22: Path Traversal"
|
|
86
|
+
owasp: "A01:2021 - Broken Access Control"
|
|
87
|
+
category: path-traversal
|
|
88
|
+
precision: low
|
|
89
|
+
references:
|
|
90
|
+
- "https://owasp.org/www-community/attacks/Path_Traversal"
|
|
91
|
+
|
|
92
|
+
# ZM-JS-PT-002: express.static 未设置 root 选项
|
|
93
|
+
- id: zm-js-pt-002
|
|
94
|
+
severity: WARNING
|
|
95
|
+
message: |
|
|
96
|
+
express.static() 未设置 root 或将用户输入用于目录路径,可能导致路径穿越。
|
|
97
|
+
修复: 设置 root 选项 + dotfiles: 'deny'
|
|
98
|
+
languages:
|
|
99
|
+
- javascript
|
|
100
|
+
- typescript
|
|
101
|
+
patterns:
|
|
102
|
+
- pattern-either:
|
|
103
|
+
- pattern: $APP.use(express.static($USER_INPUT))
|
|
104
|
+
- pattern: $APP.use(express.static($USER_INPUT, ...))
|
|
105
|
+
metadata:
|
|
106
|
+
cwe: "CWE-22: Path Traversal"
|
|
107
|
+
owasp: "A01:2021 - Broken Access Control"
|
|
108
|
+
category: path-traversal
|
|
109
|
+
precision: medium
|
|
110
|
+
references:
|
|
111
|
+
- "https://expressjs.com/en/4x/api.html#express.static"
|