@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,31 @@
|
|
|
1
|
+
# CWE-95: Function 构造函数代码注入检测规则
|
|
2
|
+
# 逐码 ZhuMa V4.1 Sprint 1 — JS/TS 通用规则库
|
|
3
|
+
|
|
4
|
+
rules:
|
|
5
|
+
|
|
6
|
+
# ZM-JS-CI-003: new Function() 动态构造可执行代码
|
|
7
|
+
- id: zm-js-ci-003
|
|
8
|
+
severity: WARNING
|
|
9
|
+
message: |
|
|
10
|
+
检测到使用 Function 构造函数动态创建函数。
|
|
11
|
+
new Function(arg) 会将字符串参数编译为可执行代码,行为类似 eval(),
|
|
12
|
+
存在代码注入风险。
|
|
13
|
+
|
|
14
|
+
修复建议:
|
|
15
|
+
1. 禁止使用 Function 构造函数处理用户输入
|
|
16
|
+
2. 替代方案: 使用闭包、高阶函数或策略模式替代动态代码生成
|
|
17
|
+
3. 如需动态执行,使用沙箱环境(vm2 / isolated-vm / WebAssembly)
|
|
18
|
+
languages:
|
|
19
|
+
- javascript
|
|
20
|
+
- typescript
|
|
21
|
+
pattern-either:
|
|
22
|
+
- pattern: new Function(...)
|
|
23
|
+
- pattern: Function(...)
|
|
24
|
+
metadata:
|
|
25
|
+
cwe: "CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')"
|
|
26
|
+
owasp: "A03:2021 - Injection"
|
|
27
|
+
category: code-injection
|
|
28
|
+
precision: high
|
|
29
|
+
references:
|
|
30
|
+
- "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function"
|
|
31
|
+
- "https://owasp.org/www-community/attacks/Code_Injection"
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# CWE-22: Python 路径穿越检测
|
|
2
|
+
# 逐码 ZhuMa V4.1 — Python 通用规则库
|
|
3
|
+
# 检测: os.path.join(userInput) / open(userInput) / Path(userInput) / tarfile.extractall 用户输入路径穿越
|
|
4
|
+
|
|
5
|
+
rules:
|
|
6
|
+
|
|
7
|
+
# ZM-PY-PT-01: os.path.join() / open() 参数来自 request
|
|
8
|
+
- id: zm-py-path-traversal-001
|
|
9
|
+
severity: ERROR
|
|
10
|
+
message: |
|
|
11
|
+
检测到 os.path.join() / open() 参数来自 HTTP 请求。
|
|
12
|
+
攻击者可构造 ../ 遍历目录读取任意文件(如 /etc/passwd 或配置文件)。
|
|
13
|
+
修复: 使用 os.path.realpath() 规范化路径后校验前缀;禁止直接拼接用户输入到文件路径。
|
|
14
|
+
languages:
|
|
15
|
+
- python
|
|
16
|
+
pattern-either:
|
|
17
|
+
- pattern: open(request.args.get(...), ...)
|
|
18
|
+
- pattern: open(request.form.get(...), ...)
|
|
19
|
+
- pattern: open(request.values.get(...), ...)
|
|
20
|
+
- pattern: open(request.data, ...)
|
|
21
|
+
- pattern: os.path.join($BASE, request.args.get(...))
|
|
22
|
+
- pattern: os.path.join($BASE, request.form.get(...))
|
|
23
|
+
- pattern: os.path.join($BASE, request.values.get(...))
|
|
24
|
+
- pattern: os.path.join(request.args.get(...), ...)
|
|
25
|
+
- pattern: os.path.join(request.form.get(...), ...)
|
|
26
|
+
- pattern: os.path.join(request.values.get(...), ...)
|
|
27
|
+
- pattern: open($BASE + request.args.get(...), ...)
|
|
28
|
+
- pattern: open($BASE + request.form.get(...), ...)
|
|
29
|
+
- pattern: open(f"...{request.args.get(...)}...", ...)
|
|
30
|
+
- pattern: open(f"...{request.form.get(...)}...", ...)
|
|
31
|
+
metadata:
|
|
32
|
+
cwe: "CWE-22: Improper Limitation of a Pathname to a Restricted Directory (Path Traversal)"
|
|
33
|
+
severity: ERROR
|
|
34
|
+
precision: high
|
|
35
|
+
category: path-traversal
|
|
36
|
+
likelihood: HIGH
|
|
37
|
+
impact: CRITICAL
|
|
38
|
+
owasp: "A01:2021 - Broken Access Control"
|
|
39
|
+
|
|
40
|
+
# ZM-PY-PT-02: pathlib.Path() 参数来自 request
|
|
41
|
+
- id: zm-py-path-traversal-002
|
|
42
|
+
severity: ERROR
|
|
43
|
+
message: |
|
|
44
|
+
检测到 pathlib.Path() 参数来自 HTTP 请求。
|
|
45
|
+
攻击者可通过 Path(userInput).read_text() 读取任意文件。
|
|
46
|
+
修复: 校验路径前缀;使用白名单限制可访问目录。
|
|
47
|
+
languages:
|
|
48
|
+
- python
|
|
49
|
+
pattern-either:
|
|
50
|
+
- pattern: Path(request.args.get(...))
|
|
51
|
+
- pattern: Path(request.form.get(...))
|
|
52
|
+
- pattern: Path(request.values.get(...))
|
|
53
|
+
- pattern: Path(request.data)
|
|
54
|
+
- pattern: pathlib.Path(request.args.get(...))
|
|
55
|
+
- pattern: pathlib.Path(request.form.get(...))
|
|
56
|
+
- pattern: pathlib.Path(request.values.get(...))
|
|
57
|
+
- pattern: pathlib.Path(request.data)
|
|
58
|
+
metadata:
|
|
59
|
+
cwe: "CWE-22: Improper Limitation of a Pathname to a Restricted Directory (Path Traversal)"
|
|
60
|
+
severity: ERROR
|
|
61
|
+
precision: high
|
|
62
|
+
category: path-traversal
|
|
63
|
+
likelihood: HIGH
|
|
64
|
+
impact: CRITICAL
|
|
65
|
+
owasp: "A01:2021 - Broken Access Control"
|
|
66
|
+
|
|
67
|
+
# ZM-PY-PT-03: tarfile.extractall 未校验路径
|
|
68
|
+
- id: zm-py-path-traversal-003
|
|
69
|
+
severity: WARNING
|
|
70
|
+
message: |
|
|
71
|
+
检测到 tarfile.extractall() 解压用户上传的 tar 包,可能触发 Zip Slip 路径穿越。
|
|
72
|
+
攻击者可在 tar 包中嵌入包含 ../ 的文件名,解压时覆盖系统文件。
|
|
73
|
+
修复: 对每个成员调用 os.path.realpath() 校验路径在目标目录内;使用 tarfile.extractall(members=filtered)。
|
|
74
|
+
languages:
|
|
75
|
+
- python
|
|
76
|
+
pattern-either:
|
|
77
|
+
- pattern: $T.extractall(...)
|
|
78
|
+
- pattern: tarfile.open(...).extractall(...)
|
|
79
|
+
metadata:
|
|
80
|
+
cwe: "CWE-22: Improper Limitation of a Pathname to a Restricted Directory (Path Traversal)"
|
|
81
|
+
severity: WARNING
|
|
82
|
+
precision: very-high
|
|
83
|
+
category: path-traversal
|
|
84
|
+
likelihood: MEDIUM
|
|
85
|
+
impact: HIGH
|
|
86
|
+
owasp: "A01:2021 - Broken Access Control"
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# CWE-327: Python 弱加密算法检测
|
|
2
|
+
# 逐码 ZhuMa V4.1 — Python 通用规则库
|
|
3
|
+
# 检测: hashlib.md5 / hashlib.sha1 / Crypto.Cipher.DES / AES-ECB 模式
|
|
4
|
+
|
|
5
|
+
rules:
|
|
6
|
+
|
|
7
|
+
# ZM-PY-WCR-01: hashlib.md5 / hashlib.sha1 弱哈希
|
|
8
|
+
- id: zm-py-weak-crypto-001
|
|
9
|
+
severity: WARNING
|
|
10
|
+
message: |
|
|
11
|
+
检测到使用 hashlib.md5() / hashlib.sha1() 弱哈希算法。
|
|
12
|
+
MD5 和 SHA-1 已被证明存在碰撞攻击,不应用于安全场景(密码存储/数字签名/完整性校验)。
|
|
13
|
+
修复: 密码存储使用 bcrypt/scrypt/argon2;完整性校验使用 hashlib.sha256() 或 hashlib.sha512()。
|
|
14
|
+
languages:
|
|
15
|
+
- python
|
|
16
|
+
pattern-either:
|
|
17
|
+
- pattern: hashlib.md5(...)
|
|
18
|
+
- pattern: hashlib.sha1(...)
|
|
19
|
+
- pattern: hashlib.md5()
|
|
20
|
+
- pattern: hashlib.sha1()
|
|
21
|
+
metadata:
|
|
22
|
+
cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
|
|
23
|
+
severity: WARNING
|
|
24
|
+
precision: very-high
|
|
25
|
+
category: weak-crypto
|
|
26
|
+
likelihood: HIGH
|
|
27
|
+
impact: HIGH
|
|
28
|
+
owasp: "A02:2021 - Cryptographic Failures"
|
|
29
|
+
|
|
30
|
+
# ZM-PY-WCR-02: Crypto.Cipher.DES / Blowfish 弱对称加密
|
|
31
|
+
- id: zm-py-weak-crypto-002
|
|
32
|
+
severity: ERROR
|
|
33
|
+
message: |
|
|
34
|
+
检测到使用 Crypto.Cipher.DES / Blowfish 弱对称加密算法。
|
|
35
|
+
DES 密钥仅 56 位可被暴力破解;Blowfish 64 位块大小存在 Sweet32 攻击风险。
|
|
36
|
+
修复: 使用 Crypto.Cipher.AES (GCM 模式) 或 ChaCha20-Poly1305 替代。
|
|
37
|
+
languages:
|
|
38
|
+
- python
|
|
39
|
+
pattern-either:
|
|
40
|
+
- pattern: Crypto.Cipher.DES.new(...)
|
|
41
|
+
- pattern: Crypto.Cipher.DES3.new(...)
|
|
42
|
+
- pattern: Crypto.Cipher.Blowfish.new(...)
|
|
43
|
+
- pattern: Crypto.Cipher.ARC2.new(...)
|
|
44
|
+
- pattern: Crypto.Cipher.ARC4.new(...)
|
|
45
|
+
- pattern: Cryptodome.Cipher.DES.new(...)
|
|
46
|
+
- pattern: Cryptodome.Cipher.DES3.new(...)
|
|
47
|
+
- pattern: Cryptodome.Cipher.Blowfish.new(...)
|
|
48
|
+
- pattern: Cryptodome.Cipher.ARC4.new(...)
|
|
49
|
+
metadata:
|
|
50
|
+
cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
|
|
51
|
+
severity: ERROR
|
|
52
|
+
precision: very-high
|
|
53
|
+
category: weak-crypto
|
|
54
|
+
likelihood: MEDIUM
|
|
55
|
+
impact: CRITICAL
|
|
56
|
+
owasp: "A02:2021 - Cryptographic Failures"
|
|
57
|
+
|
|
58
|
+
# ZM-PY-WCR-03: AES ECB 模式(不安全块加密模式)
|
|
59
|
+
- id: zm-py-weak-crypto-003
|
|
60
|
+
severity: ERROR
|
|
61
|
+
message: |
|
|
62
|
+
检测到 AES 使用 ECB(电子密码本)模式加密。
|
|
63
|
+
ECB 模式相同明文块产生相同密文块,可被模式分析攻击还原明文。
|
|
64
|
+
修复: 使用 AES-GCM(带认证加密)或 AES-CBC + HMAC 替代 ECB 模式。
|
|
65
|
+
languages:
|
|
66
|
+
- python
|
|
67
|
+
pattern-either:
|
|
68
|
+
- pattern: AES.new($KEY, AES.MODE_ECB)
|
|
69
|
+
- pattern: AES.new($KEY, AES.MODE_ECB, ...)
|
|
70
|
+
- pattern: Crypto.Cipher.AES.new($KEY, Crypto.Cipher.AES.MODE_ECB)
|
|
71
|
+
- pattern: Crypto.Cipher.AES.new($KEY, Crypto.Cipher.AES.MODE_ECB, ...)
|
|
72
|
+
metadata:
|
|
73
|
+
cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
|
|
74
|
+
severity: ERROR
|
|
75
|
+
precision: very-high
|
|
76
|
+
category: weak-crypto
|
|
77
|
+
likelihood: MEDIUM
|
|
78
|
+
impact: CRITICAL
|
|
79
|
+
owasp: "A02:2021 - Cryptographic Failures"
|
|
80
|
+
|
|
81
|
+
# ZM-PY-WCR-04: random 模块用于安全场景
|
|
82
|
+
- id: zm-py-weak-crypto-004
|
|
83
|
+
severity: WARNING
|
|
84
|
+
message: |
|
|
85
|
+
检测到使用 random 模块生成安全相关值(token/session ID/密码/密钥)。
|
|
86
|
+
random 模块使用 Mersenne Twister 伪随机算法,可被预测。
|
|
87
|
+
修复: 使用 secrets 模块 (Python 3.6+) 或 os.urandom() 生成密码学安全随机数。
|
|
88
|
+
languages:
|
|
89
|
+
- python
|
|
90
|
+
pattern-either:
|
|
91
|
+
- pattern: random.randint(..., ...)
|
|
92
|
+
- pattern: random.choice(...)
|
|
93
|
+
- pattern: random.random()
|
|
94
|
+
- pattern: random.randrange(..., ...)
|
|
95
|
+
- pattern: random.getrandbits(...)
|
|
96
|
+
metadata:
|
|
97
|
+
cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm"
|
|
98
|
+
severity: WARNING
|
|
99
|
+
precision: very-high
|
|
100
|
+
category: weak-crypto
|
|
101
|
+
likelihood: MEDIUM
|
|
102
|
+
impact: HIGH
|
|
103
|
+
owasp: "A02:2021 - Cryptographic Failures"
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# CWE-502: Python Pickle/UnsafeLoader 反序列化 RCE 检测
|
|
2
|
+
# 逐码 ZhuMa V4.1 — Python 通用规则库
|
|
3
|
+
# 检测: pickle.loads / yaml.load(UnsafeLoader) / cPickle 用户输入反序列化
|
|
4
|
+
|
|
5
|
+
rules:
|
|
6
|
+
|
|
7
|
+
# ZM-PY-PICKLE-01: pickle.loads() 参数来自 request
|
|
8
|
+
- id: zm-py-pickle-001
|
|
9
|
+
severity: ERROR
|
|
10
|
+
message: |
|
|
11
|
+
检测到 pickle.loads() 参数来自 HTTP 请求。
|
|
12
|
+
pickle 反序列化用户可控数据可触发任意代码执行(RCE)。
|
|
13
|
+
修复: 禁止反序列化用户输入;使用 JSON 等安全格式替代 pickle。
|
|
14
|
+
languages:
|
|
15
|
+
- python
|
|
16
|
+
pattern-either:
|
|
17
|
+
- pattern: pickle.loads(request.args.get(...))
|
|
18
|
+
- pattern: pickle.loads(request.form.get(...))
|
|
19
|
+
- pattern: pickle.loads(request.values.get(...))
|
|
20
|
+
- pattern: pickle.loads(request.data)
|
|
21
|
+
- pattern: pickle.loads(request.get_json().get(...))
|
|
22
|
+
- pattern: pickle.loads(request.json.get(...))
|
|
23
|
+
- pattern: pickle.loads(request.get_data())
|
|
24
|
+
- pattern: pickle.load(request.args.get(...))
|
|
25
|
+
- pattern: pickle.load(request.form.get(...))
|
|
26
|
+
- pattern: pickle.load(request.data)
|
|
27
|
+
metadata:
|
|
28
|
+
cwe: "CWE-502: Deserialization of Untrusted Data"
|
|
29
|
+
severity: ERROR
|
|
30
|
+
precision: high
|
|
31
|
+
category: deserialization
|
|
32
|
+
likelihood: MEDIUM
|
|
33
|
+
impact: CRITICAL
|
|
34
|
+
owasp: "A08:2021 - Software and Data Integrity Failures"
|
|
35
|
+
|
|
36
|
+
# ZM-PY-PICKLE-02: yaml.load() 使用 UnsafeLoader
|
|
37
|
+
- id: zm-py-pickle-002
|
|
38
|
+
severity: ERROR
|
|
39
|
+
message: |
|
|
40
|
+
检测到 yaml.load() 使用 UnsafeLoader/Loader 且数据来自 HTTP 请求。
|
|
41
|
+
PyYAML 的 Loader 可构造 !!python/object 标签实现 RCE。
|
|
42
|
+
修复: 使用 yaml.safe_load() 替代 yaml.load();或使用 FullLoader 仅限标准类型。
|
|
43
|
+
languages:
|
|
44
|
+
- python
|
|
45
|
+
pattern-either:
|
|
46
|
+
- pattern: yaml.load(request.args.get(...), Loader=yaml.Loader)
|
|
47
|
+
- pattern: yaml.load(request.form.get(...), Loader=yaml.Loader)
|
|
48
|
+
- pattern: yaml.load(request.values.get(...), Loader=yaml.Loader)
|
|
49
|
+
- pattern: yaml.load(request.data, Loader=yaml.Loader)
|
|
50
|
+
- pattern: yaml.load(request.args.get(...), yaml.Loader)
|
|
51
|
+
- pattern: yaml.load(request.form.get(...), yaml.Loader)
|
|
52
|
+
- pattern: yaml.load(request.data, yaml.Loader)
|
|
53
|
+
- pattern: yaml.load(request.args.get(...), Loader=yaml.UnsafeLoader)
|
|
54
|
+
- pattern: yaml.load(request.form.get(...), Loader=yaml.UnsafeLoader)
|
|
55
|
+
- pattern: yaml.load(request.data, Loader=yaml.UnsafeLoader)
|
|
56
|
+
metadata:
|
|
57
|
+
cwe: "CWE-502: Deserialization of Untrusted Data"
|
|
58
|
+
severity: ERROR
|
|
59
|
+
precision: high
|
|
60
|
+
category: deserialization
|
|
61
|
+
likelihood: MEDIUM
|
|
62
|
+
impact: CRITICAL
|
|
63
|
+
owasp: "A08:2021 - Software and Data Integrity Failures"
|
|
64
|
+
|
|
65
|
+
# ZM-PY-PICKLE-03: cPickle/_pickle 反序列化用户输入
|
|
66
|
+
- id: zm-py-pickle-003
|
|
67
|
+
severity: ERROR
|
|
68
|
+
message: |
|
|
69
|
+
检测到 cPickle/_pickle.loads() 参数来自 HTTP 请求。
|
|
70
|
+
cPickle 是 C 实现的 pickle 模块,反序列化用户数据可导致 RCE。
|
|
71
|
+
修复: 使用 JSON/MessagePack 替代;禁止反序列化用户输入。
|
|
72
|
+
languages:
|
|
73
|
+
- python
|
|
74
|
+
pattern-either:
|
|
75
|
+
- pattern: cPickle.loads(request.args.get(...))
|
|
76
|
+
- pattern: cPickle.loads(request.form.get(...))
|
|
77
|
+
- pattern: cPickle.loads(request.values.get(...))
|
|
78
|
+
- pattern: cPickle.loads(request.data)
|
|
79
|
+
- pattern: cPickle.load(request.args.get(...))
|
|
80
|
+
- pattern: cPickle.load(request.form.get(...))
|
|
81
|
+
- pattern: cPickle.load(request.data)
|
|
82
|
+
- pattern: _pickle.loads(request.args.get(...))
|
|
83
|
+
- pattern: _pickle.loads(request.form.get(...))
|
|
84
|
+
- pattern: _pickle.loads(request.data)
|
|
85
|
+
metadata:
|
|
86
|
+
cwe: "CWE-502: Deserialization of Untrusted Data"
|
|
87
|
+
severity: ERROR
|
|
88
|
+
precision: high
|
|
89
|
+
category: deserialization
|
|
90
|
+
likelihood: MEDIUM
|
|
91
|
+
impact: CRITICAL
|
|
92
|
+
owasp: "A08:2021 - Software and Data Integrity Failures"
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# CWE-611: Python XML 外部实体注入 (XXE) 检测
|
|
2
|
+
# 逐码 ZhuMa V4.1 — Python 通用规则库
|
|
3
|
+
# 检测: lxml.etree.parse(userInput) 未禁用 resolve_entities / xml.sax.parse / defusedxml 未使用
|
|
4
|
+
|
|
5
|
+
rules:
|
|
6
|
+
|
|
7
|
+
# ZM-PY-XXE-01: lxml.etree.parse() 用户输入未禁用 resolve_entities
|
|
8
|
+
- id: zm-py-xxe-001
|
|
9
|
+
severity: ERROR
|
|
10
|
+
message: |
|
|
11
|
+
检测到 lxml.etree.parse() / fromstring() 解析来自 HTTP 请求的 XML 未禁用实体解析。
|
|
12
|
+
攻击者可构造 XXE payload 读取本地文件(/etc/passwd)、SSRF 内网探测或 DoS(Billion Laughs)。
|
|
13
|
+
修复: 使用 defusedxml 替代标准 XML 解析;或 lxml 设置 resolve_entities=False, no_network=True。
|
|
14
|
+
languages:
|
|
15
|
+
- python
|
|
16
|
+
pattern-either:
|
|
17
|
+
- pattern: lxml.etree.parse(request.args.get(...))
|
|
18
|
+
- pattern: lxml.etree.parse(request.form.get(...))
|
|
19
|
+
- pattern: lxml.etree.parse(request.values.get(...))
|
|
20
|
+
- pattern: lxml.etree.parse(request.data)
|
|
21
|
+
- pattern: lxml.etree.fromstring(request.args.get(...))
|
|
22
|
+
- pattern: lxml.etree.fromstring(request.form.get(...))
|
|
23
|
+
- pattern: lxml.etree.fromstring(request.values.get(...))
|
|
24
|
+
- pattern: lxml.etree.fromstring(request.data)
|
|
25
|
+
- pattern: lxml.etree.XML(request.args.get(...))
|
|
26
|
+
- pattern: lxml.etree.XML(request.form.get(...))
|
|
27
|
+
- pattern: lxml.etree.XML(request.values.get(...))
|
|
28
|
+
- pattern: lxml.etree.XML(request.data)
|
|
29
|
+
- pattern: lxml.etree.iterparse(request.args.get(...))
|
|
30
|
+
- pattern: lxml.etree.iterparse(request.form.get(...))
|
|
31
|
+
metadata:
|
|
32
|
+
cwe: "CWE-611: Improper Restriction of XML External Entity Reference"
|
|
33
|
+
severity: ERROR
|
|
34
|
+
precision: high
|
|
35
|
+
category: xxe
|
|
36
|
+
likelihood: HIGH
|
|
37
|
+
impact: CRITICAL
|
|
38
|
+
owasp: "A05:2021 - Security Misconfiguration"
|
|
39
|
+
|
|
40
|
+
# ZM-PY-XXE-02: xml.etree.ElementTree / xml.sax / xml.dom 解析用户输入
|
|
41
|
+
- id: zm-py-xxe-002
|
|
42
|
+
severity: ERROR
|
|
43
|
+
message: |
|
|
44
|
+
检测到标准库 xml 模块(ElementTree / sax / dom / parsers)解析来自 HTTP 请求的 XML。
|
|
45
|
+
Python 标准 XML 解析器默认启用外部实体解析,存在 XXE 漏洞。
|
|
46
|
+
修复: 使用 defusedxml.ElementTree / defusedxml.sax / defusedxml.minidom 替代标准库。
|
|
47
|
+
languages:
|
|
48
|
+
- python
|
|
49
|
+
pattern-either:
|
|
50
|
+
- pattern: xml.etree.ElementTree.parse(request.args.get(...))
|
|
51
|
+
- pattern: xml.etree.ElementTree.parse(request.form.get(...))
|
|
52
|
+
- pattern: xml.etree.ElementTree.parse(request.data)
|
|
53
|
+
- pattern: xml.etree.ElementTree.fromstring(request.args.get(...))
|
|
54
|
+
- pattern: xml.etree.ElementTree.fromstring(request.form.get(...))
|
|
55
|
+
- pattern: xml.etree.ElementTree.fromstring(request.data)
|
|
56
|
+
- pattern: xml.etree.ElementTree.XML(request.args.get(...))
|
|
57
|
+
- pattern: xml.etree.ElementTree.XML(request.form.get(...))
|
|
58
|
+
- pattern: xml.etree.ElementTree.XML(request.data)
|
|
59
|
+
- pattern: xml.sax.parseString(request.args.get(...), ...)
|
|
60
|
+
- pattern: xml.sax.parseString(request.form.get(...), ...)
|
|
61
|
+
- pattern: xml.sax.parseString(request.data, ...)
|
|
62
|
+
- pattern: xml.sax.parse(request.args.get(...), ...)
|
|
63
|
+
- pattern: xml.sax.parse(request.form.get(...), ...)
|
|
64
|
+
- pattern: xml.dom.minidom.parse(request.args.get(...))
|
|
65
|
+
- pattern: xml.dom.minidom.parse(request.form.get(...))
|
|
66
|
+
- pattern: xml.dom.minidom.parseString(request.args.get(...))
|
|
67
|
+
- pattern: xml.dom.minidom.parseString(request.form.get(...))
|
|
68
|
+
- pattern: xml.dom.pulldom.parse(request.args.get(...))
|
|
69
|
+
- pattern: xml.dom.pulldom.parse(request.form.get(...))
|
|
70
|
+
metadata:
|
|
71
|
+
cwe: "CWE-611: Improper Restriction of XML External Entity Reference"
|
|
72
|
+
severity: ERROR
|
|
73
|
+
precision: high
|
|
74
|
+
category: xxe
|
|
75
|
+
likelihood: HIGH
|
|
76
|
+
impact: CRITICAL
|
|
77
|
+
owasp: "A05:2021 - Security Misconfiguration"
|
|
78
|
+
|
|
79
|
+
# ZM-PY-XXE-03: lxml.etree.parse 使用解析器但未禁用 resolve_entities
|
|
80
|
+
- id: zm-py-xxe-003
|
|
81
|
+
severity: WARNING
|
|
82
|
+
message: |
|
|
83
|
+
检测到 lxml.etree.parse() 创建了自定义解析器但可能未禁用 resolve_entities。
|
|
84
|
+
lxml 默认解析器启用实体解析,需显式设置 resolve_entities=False。
|
|
85
|
+
修复: 使用 etree.XMLParser(resolve_entities=False, no_network=True) 创建安全解析器。
|
|
86
|
+
languages:
|
|
87
|
+
- python
|
|
88
|
+
pattern-either:
|
|
89
|
+
- pattern: etree.XMLParser()
|
|
90
|
+
- pattern: etree.XMLParser(..., load_dtd=True, ...)
|
|
91
|
+
- pattern: etree.XMLParser(..., dtd_validation=True, ...)
|
|
92
|
+
- pattern: etree.iterparse($STREAM, events=...)
|
|
93
|
+
metadata:
|
|
94
|
+
cwe: "CWE-611: Improper Restriction of XML External Entity Reference"
|
|
95
|
+
severity: WARNING
|
|
96
|
+
precision: medium
|
|
97
|
+
category: xxe
|
|
98
|
+
likelihood: MEDIUM
|
|
99
|
+
impact: HIGH
|
|
100
|
+
owasp: "A05:2021 - Security Misconfiguration"
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# CWE-78: Python 命令注入检测
|
|
2
|
+
# 逐码 ZhuMa V4.1 — Python 通用规则库
|
|
3
|
+
# 检测: os.system / os.popen / subprocess.call(shell=True) / subprocess.Popen(shell=True) 用户输入注入
|
|
4
|
+
|
|
5
|
+
rules:
|
|
6
|
+
|
|
7
|
+
# ZM-PY-CMD-01: os.system() / os.popen() 参数来自 request
|
|
8
|
+
- id: zm-py-command-injection-001
|
|
9
|
+
severity: ERROR
|
|
10
|
+
message: |
|
|
11
|
+
检测到 os.system() / os.popen() 参数来自 HTTP 请求。
|
|
12
|
+
攻击者可注入恶意命令实现任意代码执行(RCE)。
|
|
13
|
+
修复: 使用 subprocess.run([cmd, arg1, arg2]) 参数数组形式,禁止 shell 拼接用户输入。
|
|
14
|
+
languages:
|
|
15
|
+
- python
|
|
16
|
+
pattern-either:
|
|
17
|
+
- pattern: os.system(request.args.get(...))
|
|
18
|
+
- pattern: os.system(request.form.get(...))
|
|
19
|
+
- pattern: os.system(request.values.get(...))
|
|
20
|
+
- pattern: os.system(request.data)
|
|
21
|
+
- pattern: os.system($CMD + request.args.get(...))
|
|
22
|
+
- pattern: os.system($CMD + request.form.get(...))
|
|
23
|
+
- pattern: os.system(f"...{request.args.get(...)}...")
|
|
24
|
+
- pattern: os.system(f"...{request.form.get(...)}...")
|
|
25
|
+
- pattern: os.popen(request.args.get(...))
|
|
26
|
+
- pattern: os.popen(request.form.get(...))
|
|
27
|
+
- pattern: os.popen(request.values.get(...))
|
|
28
|
+
- pattern: os.popen(request.data)
|
|
29
|
+
- pattern: os.popen($CMD + request.args.get(...))
|
|
30
|
+
- pattern: os.popen($CMD + request.form.get(...))
|
|
31
|
+
- pattern: os.popen(f"...{request.args.get(...)}...")
|
|
32
|
+
- pattern: os.popen(f"...{request.form.get(...)}...")
|
|
33
|
+
metadata:
|
|
34
|
+
cwe: "CWE-78: Improper Neutralization of Special Elements used in an OS Command (OS Command Injection)"
|
|
35
|
+
severity: ERROR
|
|
36
|
+
precision: high
|
|
37
|
+
category: command-injection
|
|
38
|
+
likelihood: HIGH
|
|
39
|
+
impact: CRITICAL
|
|
40
|
+
owasp: "A03:2021 - Injection"
|
|
41
|
+
|
|
42
|
+
# ZM-PY-CMD-02: subprocess 系列 shell=True + 用户输入
|
|
43
|
+
- id: zm-py-command-injection-002
|
|
44
|
+
severity: ERROR
|
|
45
|
+
message: |
|
|
46
|
+
检测到 subprocess.call/run/Popen 使用 shell=True 且参数来自 HTTP 请求。
|
|
47
|
+
shell=True 时字符串参数经 shell 解析,攻击者可注入任意命令。
|
|
48
|
+
修复: 移除 shell=True;使用 args=['cmd', 'arg1', 'arg2'] 参数数组形式。
|
|
49
|
+
languages:
|
|
50
|
+
- python
|
|
51
|
+
pattern-either:
|
|
52
|
+
- pattern: subprocess.call(request.args.get(...), shell=True)
|
|
53
|
+
- pattern: subprocess.call(request.form.get(...), shell=True)
|
|
54
|
+
- pattern: subprocess.call(request.values.get(...), shell=True)
|
|
55
|
+
- pattern: subprocess.call($CMD + request.args.get(...), shell=True)
|
|
56
|
+
- pattern: subprocess.call($CMD + request.form.get(...), shell=True)
|
|
57
|
+
- pattern: subprocess.call(f"...{request.args.get(...)}...", shell=True)
|
|
58
|
+
- pattern: subprocess.Popen(request.args.get(...), shell=True)
|
|
59
|
+
- pattern: subprocess.Popen(request.form.get(...), shell=True)
|
|
60
|
+
- pattern: subprocess.Popen(request.values.get(...), shell=True)
|
|
61
|
+
- pattern: subprocess.Popen($CMD + request.args.get(...), shell=True)
|
|
62
|
+
- pattern: subprocess.Popen($CMD + request.form.get(...), shell=True)
|
|
63
|
+
- pattern: subprocess.Popen(f"...{request.args.get(...)}...", shell=True)
|
|
64
|
+
- pattern: subprocess.run(request.args.get(...), shell=True)
|
|
65
|
+
- pattern: subprocess.run(request.form.get(...), shell=True)
|
|
66
|
+
- pattern: subprocess.run($CMD + request.args.get(...), shell=True)
|
|
67
|
+
- pattern: subprocess.run($CMD + request.form.get(...), shell=True)
|
|
68
|
+
- pattern: subprocess.run(f"...{request.args.get(...)}...", shell=True)
|
|
69
|
+
metadata:
|
|
70
|
+
cwe: "CWE-78: Improper Neutralization of Special Elements used in an OS Command (OS Command Injection)"
|
|
71
|
+
severity: ERROR
|
|
72
|
+
precision: high
|
|
73
|
+
category: command-injection
|
|
74
|
+
likelihood: HIGH
|
|
75
|
+
impact: CRITICAL
|
|
76
|
+
owasp: "A03:2021 - Injection"
|
|
77
|
+
|
|
78
|
+
# ZM-PY-CMD-03: shell=True 赋值为变量 + 用户输入拼接
|
|
79
|
+
- id: zm-py-command-injection-003
|
|
80
|
+
severity: WARNING
|
|
81
|
+
message: |
|
|
82
|
+
检测到命令字符串由用户输入拼接后传入 subprocess 执行(shell=True)。
|
|
83
|
+
通过变量传递后执行同样存在命令注入风险。
|
|
84
|
+
修复: 使用 args=['cmd', 'arg1'] 数组传参,不使用 shell=True。
|
|
85
|
+
languages:
|
|
86
|
+
- python
|
|
87
|
+
pattern: |
|
|
88
|
+
$CMD = $STRING + request.$ATTR.get(...)
|
|
89
|
+
...
|
|
90
|
+
subprocess.$FUNC($CMD, shell=True)
|
|
91
|
+
metadata:
|
|
92
|
+
cwe: "CWE-78: Improper Neutralization of Special Elements used in an OS Command (OS Command Injection)"
|
|
93
|
+
severity: WARNING
|
|
94
|
+
precision: medium
|
|
95
|
+
category: command-injection
|
|
96
|
+
likelihood: MEDIUM
|
|
97
|
+
impact: CRITICAL
|
|
98
|
+
owasp: "A03:2021 - Injection"
|
|
99
|
+
|
|
100
|
+
# ZM-PY-CMD-04: commands.getoutput / commands.getstatusoutput 遗留危险函数
|
|
101
|
+
- id: zm-py-command-injection-004
|
|
102
|
+
severity: ERROR
|
|
103
|
+
message: |
|
|
104
|
+
检测到 commands.getoutput() / getstatusoutput() 参数来自 HTTP 请求。
|
|
105
|
+
该模块在 Python 3 中已弃用但仍存在于 Python 2 遗留代码中,存在命令注入风险。
|
|
106
|
+
修复: 迁移至 subprocess.run(['cmd', 'arg']) 参数数组形式。
|
|
107
|
+
languages:
|
|
108
|
+
- python
|
|
109
|
+
pattern-either:
|
|
110
|
+
- pattern: commands.getoutput(request.args.get(...))
|
|
111
|
+
- pattern: commands.getoutput(request.form.get(...))
|
|
112
|
+
- pattern: commands.getstatusoutput(request.args.get(...))
|
|
113
|
+
- pattern: commands.getstatusoutput(request.form.get(...))
|
|
114
|
+
metadata:
|
|
115
|
+
cwe: "CWE-78: Improper Neutralization of Special Elements used in an OS Command (OS Command Injection)"
|
|
116
|
+
severity: ERROR
|
|
117
|
+
precision: high
|
|
118
|
+
category: command-injection
|
|
119
|
+
likelihood: MEDIUM
|
|
120
|
+
impact: CRITICAL
|
|
121
|
+
owasp: "A03:2021 - Injection"
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# CWE-79: Django/Flask XSS 跨站脚本检测
|
|
2
|
+
# 逐码 ZhuMa V4.1 — Python 通用规则库
|
|
3
|
+
# 检测: mark_safe / render_template + userInput / HttpResponse(userInput) / json.dumps+isSafe
|
|
4
|
+
|
|
5
|
+
rules:
|
|
6
|
+
|
|
7
|
+
# ZM-PY-XSS-01: mark_safe / SafeString 包装用户输入
|
|
8
|
+
- id: zm-py-xss-001
|
|
9
|
+
severity: ERROR
|
|
10
|
+
message: |
|
|
11
|
+
检测到 django.utils.safestring.mark_safe() 包装来自 HTTP 请求的用户输入。
|
|
12
|
+
mark_safe() 会绕过 Django 自动 HTML 转义,导致 XSS 攻击。
|
|
13
|
+
修复: 移除 mark_safe() 包装使用默认自动转义;如确需 HTML 渲染使用 bleach 库白名单过滤。
|
|
14
|
+
languages:
|
|
15
|
+
- python
|
|
16
|
+
pattern-either:
|
|
17
|
+
- pattern: mark_safe(request.args.get(...))
|
|
18
|
+
- pattern: mark_safe(request.form.get(...))
|
|
19
|
+
- pattern: mark_safe(request.values.get(...))
|
|
20
|
+
- pattern: mark_safe(request.POST.get(...))
|
|
21
|
+
- pattern: mark_safe(request.GET.get(...))
|
|
22
|
+
- pattern: mark_safe(request.data)
|
|
23
|
+
- pattern: django.utils.safestring.mark_safe(request.args.get(...))
|
|
24
|
+
- pattern: django.utils.safestring.mark_safe(request.form.get(...))
|
|
25
|
+
- pattern: django.utils.safestring.mark_safe(request.POST.get(...))
|
|
26
|
+
- pattern: django.utils.safestring.mark_safe(request.GET.get(...))
|
|
27
|
+
- pattern: SafeString(request.args.get(...))
|
|
28
|
+
- pattern: SafeString(request.form.get(...))
|
|
29
|
+
- pattern: SafeString(request.POST.get(...))
|
|
30
|
+
- pattern: SafeText(request.args.get(...))
|
|
31
|
+
- pattern: SafeText(request.form.get(...))
|
|
32
|
+
metadata:
|
|
33
|
+
cwe: "CWE-79: Improper Neutralization of Input During Web Page Generation (Cross-site Scripting)"
|
|
34
|
+
severity: ERROR
|
|
35
|
+
precision: high
|
|
36
|
+
category: xss
|
|
37
|
+
likelihood: HIGH
|
|
38
|
+
impact: HIGH
|
|
39
|
+
owasp: "A03:2021 - Injection"
|
|
40
|
+
|
|
41
|
+
# ZM-PY-XSS-02: HttpResponse() / render() 直接输出用户输入
|
|
42
|
+
- id: zm-py-xss-002
|
|
43
|
+
severity: WARNING
|
|
44
|
+
message: |
|
|
45
|
+
检测到 HttpResponse() 直接写入用户输入,或 render() 模板变量直接嵌入用户输入。
|
|
46
|
+
Django 默认自动转义模板变量,但 HttpResponse 直接输出不会转义。
|
|
47
|
+
修复: HttpResponse 中使用 html.escape() 转义;render() 中避免使用 |safe 过滤器。
|
|
48
|
+
languages:
|
|
49
|
+
- python
|
|
50
|
+
pattern-either:
|
|
51
|
+
- pattern: HttpResponse(request.args.get(...))
|
|
52
|
+
- pattern: HttpResponse(request.form.get(...))
|
|
53
|
+
- pattern: HttpResponse(request.POST.get(...))
|
|
54
|
+
- pattern: HttpResponse(request.GET.get(...))
|
|
55
|
+
- pattern: HttpResponse(request.data)
|
|
56
|
+
- pattern: HttpResponse(f"...{request.args.get(...)}...")
|
|
57
|
+
- pattern: HttpResponse(f"...{request.form.get(...)}...")
|
|
58
|
+
- pattern: HttpResponse($STR + request.args.get(...))
|
|
59
|
+
- pattern: HttpResponse($STR + request.form.get(...))
|
|
60
|
+
- pattern: django.http.HttpResponse(request.args.get(...))
|
|
61
|
+
- pattern: django.http.HttpResponse(request.form.get(...))
|
|
62
|
+
- pattern: django.http.HttpResponse(request.POST.get(...))
|
|
63
|
+
- pattern: django.http.HttpResponse(request.GET.get(...))
|
|
64
|
+
metadata:
|
|
65
|
+
cwe: "CWE-79: Improper Neutralization of Input During Web Page Generation (Cross-site Scripting)"
|
|
66
|
+
severity: WARNING
|
|
67
|
+
precision: medium
|
|
68
|
+
category: xss
|
|
69
|
+
likelihood: MEDIUM
|
|
70
|
+
impact: HIGH
|
|
71
|
+
owasp: "A03:2021 - Injection"
|
|
72
|
+
|
|
73
|
+
# ZM-PY-XSS-03: render_template 变量中含用户输入未转义
|
|
74
|
+
- id: zm-py-xss-003
|
|
75
|
+
severity: WARNING
|
|
76
|
+
message: |
|
|
77
|
+
检测到 render_template() 模板变量直接来自 HTTP 请求。
|
|
78
|
+
Jinja2 默认自动转义 HTML,但若模板中使用了 |safe 过滤器或 {% autoescape false %},则存在 XSS 风险。
|
|
79
|
+
修复: 避免模板中使用 |safe 过滤器标记用户输入;使用 bleach 库做白名单 HTML 清理。
|
|
80
|
+
languages:
|
|
81
|
+
- python
|
|
82
|
+
pattern-either:
|
|
83
|
+
- pattern: flask.render_template($TEMPLATE, $VAR=request.args.get(...))
|
|
84
|
+
- pattern: flask.render_template($TEMPLATE, $VAR=request.form.get(...))
|
|
85
|
+
- pattern: flask.render_template($TEMPLATE, $VAR=request.values.get(...))
|
|
86
|
+
- pattern: render_template($TEMPLATE, $VAR=request.args.get(...))
|
|
87
|
+
- pattern: render_template($TEMPLATE, $VAR=request.form.get(...))
|
|
88
|
+
- pattern: render_template($TEMPLATE, $VAR=request.values.get(...))
|
|
89
|
+
- pattern: 'django.shortcuts.render(request, $TEMPLATE, {$VAR: request.GET.get(...)})'
|
|
90
|
+
- pattern: 'django.shortcuts.render(request, $TEMPLATE, {$VAR: request.POST.get(...)})'
|
|
91
|
+
metadata:
|
|
92
|
+
cwe: "CWE-79: Improper Neutralization of Input During Web Page Generation (Cross-site Scripting)"
|
|
93
|
+
severity: WARNING
|
|
94
|
+
precision: medium
|
|
95
|
+
category: xss
|
|
96
|
+
likelihood: MEDIUM
|
|
97
|
+
impact: HIGH
|
|
98
|
+
owasp: "A03:2021 - Injection"
|
|
99
|
+
|
|
100
|
+
# ZM-PY-XSS-04: JsonResponse 不安全的 JSON 序列化
|
|
101
|
+
- id: zm-py-xss-004
|
|
102
|
+
severity: WARNING
|
|
103
|
+
message: |
|
|
104
|
+
检测到 JsonResponse / json.dumps 输出用户输入,且未正确设置 Content-Type 或已禁用转义。
|
|
105
|
+
Django JsonResponse 默认 safe=True 仅允许 dict;若 safe=False 传入含 HTML 的用户输入可导致 DOM XSS。
|
|
106
|
+
修复: 对用户输入做 HTML 转义后再放入 JSON;避免 safe=False 传入非 dict 类型。
|
|
107
|
+
languages:
|
|
108
|
+
- python
|
|
109
|
+
pattern-either:
|
|
110
|
+
- pattern: 'JsonResponse({"$KEY": request.args.get(...)}, safe=False)'
|
|
111
|
+
- pattern: 'JsonResponse({"$KEY": request.form.get(...)}, safe=False)'
|
|
112
|
+
- pattern: 'JsonResponse({"$KEY": request.POST.get(...)}, safe=False)'
|
|
113
|
+
- pattern: 'JsonResponse({"$KEY": request.GET.get(...)}, safe=False)'
|
|
114
|
+
- pattern: 'json.dumps({"$KEY": request.args.get(...)})'
|
|
115
|
+
- pattern: 'json.dumps({"$KEY": request.form.get(...)})'
|
|
116
|
+
metadata:
|
|
117
|
+
cwe: "CWE-79: Improper Neutralization of Input During Web Page Generation (Cross-site Scripting)"
|
|
118
|
+
severity: WARNING
|
|
119
|
+
precision: medium
|
|
120
|
+
category: xss
|
|
121
|
+
likelihood: MEDIUM
|
|
122
|
+
impact: MEDIUM
|
|
123
|
+
owasp: "A03:2021 - Injection"
|