codelaw-rules-security-python 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. codelaw_rules_security_python/LICENSE +23 -0
  2. codelaw_rules_security_python/NOTICE +19 -0
  3. codelaw_rules_security_python/README.md +239 -0
  4. codelaw_rules_security_python/codelaw-pack.toml +6 -0
  5. codelaw_rules_security_python/corpus.toml +65 -0
  6. codelaw_rules_security_python/data/sources/django.json +17 -0
  7. codelaw_rules_security_python/data/sources/fastapi.json +10 -0
  8. codelaw_rules_security_python/data/sources/flask.json +14 -0
  9. codelaw_rules_security_python/presets/sec-py/recommended.toml +60 -0
  10. codelaw_rules_security_python/presets/sec-py/strict.toml +8 -0
  11. codelaw_rules_security_python/rules/sec-py/cookie-flags.cases.md +61 -0
  12. codelaw_rules_security_python/rules/sec-py/cookie-flags.md +95 -0
  13. codelaw_rules_security_python/rules/sec-py/django-settings.cases.md +61 -0
  14. codelaw_rules_security_python/rules/sec-py/django-settings.md +68 -0
  15. codelaw_rules_security_python/rules/sec-py/fastapi-cors.cases.md +31 -0
  16. codelaw_rules_security_python/rules/sec-py/fastapi-cors.md +46 -0
  17. codelaw_rules_security_python/rules/sec-py/flask-debug.cases.md +31 -0
  18. codelaw_rules_security_python/rules/sec-py/flask-debug.md +59 -0
  19. codelaw_rules_security_python/rules/sec-py/flask-settings.cases.md +51 -0
  20. codelaw_rules_security_python/rules/sec-py/flask-settings.md +84 -0
  21. codelaw_rules_security_python/rules/sec-py/hf-pin-revision.cases.md +51 -0
  22. codelaw_rules_security_python/rules/sec-py/hf-pin-revision.md +58 -0
  23. codelaw_rules_security_python/rules/sec-py/jinja-autoescape.cases.md +62 -0
  24. codelaw_rules_security_python/rules/sec-py/jinja-autoescape.md +80 -0
  25. codelaw_rules_security_python/rules/sec-py/logging-listen.cases.md +31 -0
  26. codelaw_rules_security_python/rules/sec-py/logging-listen.md +47 -0
  27. codelaw_rules_security_python/rules/sec-py/ml-unsafe-load.cases.md +61 -0
  28. codelaw_rules_security_python/rules/sec-py/ml-unsafe-load.md +68 -0
  29. codelaw_rules_security_python/rules/sec-py/no-assert-for-auth.cases.md +31 -0
  30. codelaw_rules_security_python/rules/sec-py/no-assert-for-auth.md +51 -0
  31. codelaw_rules_security_python/rules/sec-py/no-bind-all-interfaces.cases.md +41 -0
  32. codelaw_rules_security_python/rules/sec-py/no-bind-all-interfaces.md +75 -0
  33. codelaw_rules_security_python/rules/sec-py/no-cleartext-http.cases.md +41 -0
  34. codelaw_rules_security_python/rules/sec-py/no-cleartext-http.md +56 -0
  35. codelaw_rules_security_python/rules/sec-py/no-csrf-exempt.cases.md +49 -0
  36. codelaw_rules_security_python/rules/sec-py/no-csrf-exempt.md +47 -0
  37. codelaw_rules_security_python/rules/sec-py/no-dynamic-import.cases.md +35 -0
  38. codelaw_rules_security_python/rules/sec-py/no-dynamic-import.md +51 -0
  39. codelaw_rules_security_python/rules/sec-py/no-exec-eval.cases.md +51 -0
  40. codelaw_rules_security_python/rules/sec-py/no-exec-eval.md +56 -0
  41. codelaw_rules_security_python/rules/sec-py/no-format-string-injection.cases.md +35 -0
  42. codelaw_rules_security_python/rules/sec-py/no-format-string-injection.md +44 -0
  43. codelaw_rules_security_python/rules/sec-py/no-hardcoded-crypto-key.cases.md +51 -0
  44. codelaw_rules_security_python/rules/sec-py/no-hardcoded-crypto-key.md +91 -0
  45. codelaw_rules_security_python/rules/sec-py/no-hardcoded-secret.cases.md +61 -0
  46. codelaw_rules_security_python/rules/sec-py/no-hardcoded-secret.md +82 -0
  47. codelaw_rules_security_python/rules/sec-py/no-header-injection.cases.md +45 -0
  48. codelaw_rules_security_python/rules/sec-py/no-header-injection.md +55 -0
  49. codelaw_rules_security_python/rules/sec-py/no-insecure-protocol.cases.md +41 -0
  50. codelaw_rules_security_python/rules/sec-py/no-insecure-protocol.md +52 -0
  51. codelaw_rules_security_python/rules/sec-py/no-insecure-random.cases.md +41 -0
  52. codelaw_rules_security_python/rules/sec-py/no-insecure-random.md +67 -0
  53. codelaw_rules_security_python/rules/sec-py/no-insecure-tempfile.cases.md +41 -0
  54. codelaw_rules_security_python/rules/sec-py/no-insecure-tempfile.md +62 -0
  55. codelaw_rules_security_python/rules/sec-py/no-ldap-injection.cases.md +41 -0
  56. codelaw_rules_security_python/rules/sec-py/no-ldap-injection.md +51 -0
  57. codelaw_rules_security_python/rules/sec-py/no-llm-output-to-sink.cases.md +31 -0
  58. codelaw_rules_security_python/rules/sec-py/no-llm-output-to-sink.md +55 -0
  59. codelaw_rules_security_python/rules/sec-py/no-log-injection.cases.md +45 -0
  60. codelaw_rules_security_python/rules/sec-py/no-log-injection.md +52 -0
  61. codelaw_rules_security_python/rules/sec-py/no-mako.cases.md +37 -0
  62. codelaw_rules_security_python/rules/sec-py/no-mako.md +52 -0
  63. codelaw_rules_security_python/rules/sec-py/no-mark-safe.cases.md +51 -0
  64. codelaw_rules_security_python/rules/sec-py/no-mark-safe.md +54 -0
  65. codelaw_rules_security_python/rules/sec-py/no-mass-assignment.cases.md +55 -0
  66. codelaw_rules_security_python/rules/sec-py/no-mass-assignment.md +58 -0
  67. codelaw_rules_security_python/rules/sec-py/no-nosql-injection.cases.md +34 -0
  68. codelaw_rules_security_python/rules/sec-py/no-nosql-injection.md +56 -0
  69. codelaw_rules_security_python/rules/sec-py/no-open-redirect.cases.md +35 -0
  70. codelaw_rules_security_python/rules/sec-py/no-open-redirect.md +51 -0
  71. codelaw_rules_security_python/rules/sec-py/no-partial-path.cases.md +41 -0
  72. codelaw_rules_security_python/rules/sec-py/no-partial-path.md +61 -0
  73. codelaw_rules_security_python/rules/sec-py/no-path-traversal.cases.md +46 -0
  74. codelaw_rules_security_python/rules/sec-py/no-path-traversal.md +54 -0
  75. codelaw_rules_security_python/rules/sec-py/no-prompt-injection.cases.md +46 -0
  76. codelaw_rules_security_python/rules/sec-py/no-prompt-injection.md +65 -0
  77. codelaw_rules_security_python/rules/sec-py/no-pycrypto.cases.md +41 -0
  78. codelaw_rules_security_python/rules/sec-py/no-pycrypto.md +47 -0
  79. codelaw_rules_security_python/rules/sec-py/no-reflected-xss.cases.md +45 -0
  80. codelaw_rules_security_python/rules/sec-py/no-reflected-xss.md +56 -0
  81. codelaw_rules_security_python/rules/sec-py/no-regex-injection.cases.md +33 -0
  82. codelaw_rules_security_python/rules/sec-py/no-regex-injection.md +49 -0
  83. codelaw_rules_security_python/rules/sec-py/no-secret-in-log.cases.md +41 -0
  84. codelaw_rules_security_python/rules/sec-py/no-secret-in-log.md +55 -0
  85. codelaw_rules_security_python/rules/sec-py/no-shell.cases.md +55 -0
  86. codelaw_rules_security_python/rules/sec-py/no-shell.md +63 -0
  87. codelaw_rules_security_python/rules/sec-py/no-silent-except.cases.md +53 -0
  88. codelaw_rules_security_python/rules/sec-py/no-silent-except.md +54 -0
  89. codelaw_rules_security_python/rules/sec-py/no-sql-string.cases.md +91 -0
  90. codelaw_rules_security_python/rules/sec-py/no-sql-string.md +78 -0
  91. codelaw_rules_security_python/rules/sec-py/no-ssrf.cases.md +34 -0
  92. codelaw_rules_security_python/rules/sec-py/no-ssrf.md +54 -0
  93. codelaw_rules_security_python/rules/sec-py/no-stack-trace-response.cases.md +48 -0
  94. codelaw_rules_security_python/rules/sec-py/no-stack-trace-response.md +67 -0
  95. codelaw_rules_security_python/rules/sec-py/no-tls-bypass.cases.md +71 -0
  96. codelaw_rules_security_python/rules/sec-py/no-tls-bypass.md +66 -0
  97. codelaw_rules_security_python/rules/sec-py/no-trust-remote-code.cases.md +31 -0
  98. codelaw_rules_security_python/rules/sec-py/no-trust-remote-code.md +50 -0
  99. codelaw_rules_security_python/rules/sec-py/no-unsafe-deserialize.cases.md +63 -0
  100. codelaw_rules_security_python/rules/sec-py/no-unsafe-deserialize.md +51 -0
  101. codelaw_rules_security_python/rules/sec-py/no-weak-cipher.cases.md +51 -0
  102. codelaw_rules_security_python/rules/sec-py/no-weak-cipher.md +60 -0
  103. codelaw_rules_security_python/rules/sec-py/no-weak-hash.cases.md +41 -0
  104. codelaw_rules_security_python/rules/sec-py/no-weak-hash.md +54 -0
  105. codelaw_rules_security_python/rules/sec-py/no-wildcard-injection.cases.md +41 -0
  106. codelaw_rules_security_python/rules/sec-py/no-wildcard-injection.md +53 -0
  107. codelaw_rules_security_python/rules/sec-py/no-world-writable.cases.md +51 -0
  108. codelaw_rules_security_python/rules/sec-py/no-world-writable.md +57 -0
  109. codelaw_rules_security_python/rules/sec-py/no-xml-unsafe-parser.cases.md +83 -0
  110. codelaw_rules_security_python/rules/sec-py/no-xml-unsafe-parser.md +86 -0
  111. codelaw_rules_security_python/rules/sec-py/no-xmlrpc.cases.md +31 -0
  112. codelaw_rules_security_python/rules/sec-py/no-xmlrpc.md +50 -0
  113. codelaw_rules_security_python/rules/sec-py/no-xpath-injection.cases.md +41 -0
  114. codelaw_rules_security_python/rules/sec-py/no-xpath-injection.md +52 -0
  115. codelaw_rules_security_python/rules/sec-py/paramiko-host-key.cases.md +21 -0
  116. codelaw_rules_security_python/rules/sec-py/paramiko-host-key.md +44 -0
  117. codelaw_rules_security_python/rules/sec-py/password-hash-effort.cases.md +61 -0
  118. codelaw_rules_security_python/rules/sec-py/password-hash-effort.md +74 -0
  119. codelaw_rules_security_python/rules/sec-py/requests-timeout.cases.md +41 -0
  120. codelaw_rules_security_python/rules/sec-py/requests-timeout.md +63 -0
  121. codelaw_rules_security_python/rules/sec-py/tarfile-filter.cases.md +51 -0
  122. codelaw_rules_security_python/rules/sec-py/tarfile-filter.md +71 -0
  123. codelaw_rules_security_python/rules/sec-py/torch-load-weights-only.cases.md +41 -0
  124. codelaw_rules_security_python/rules/sec-py/torch-load-weights-only.md +73 -0
  125. codelaw_rules_security_python/rules/sec-py/upload-secure-filename.cases.md +41 -0
  126. codelaw_rules_security_python/rules/sec-py/upload-secure-filename.md +65 -0
  127. codelaw_rules_security_python/rules/sec-py/urlopen-scheme.cases.md +41 -0
  128. codelaw_rules_security_python/rules/sec-py/urlopen-scheme.md +54 -0
  129. codelaw_rules_security_python/rules/sec-py/weak-key-size.cases.md +51 -0
  130. codelaw_rules_security_python/rules/sec-py/weak-key-size.md +82 -0
  131. codelaw_rules_security_python/rules/sec-py/yaml-safe-load.cases.md +67 -0
  132. codelaw_rules_security_python/rules/sec-py/yaml-safe-load.md +51 -0
  133. codelaw_rules_security_python-0.3.0.dist-info/METADATA +249 -0
  134. codelaw_rules_security_python-0.3.0.dist-info/RECORD +136 -0
  135. codelaw_rules_security_python-0.3.0.dist-info/WHEEL +4 -0
  136. codelaw_rules_security_python-0.3.0.dist-info/licenses/LICENSE +23 -0
@@ -0,0 +1,51 @@
1
+ # sec-py/weak-key-size — cases
2
+
3
+ ### case: 1024
4
+
5
+ ```py
6
+ rsa.generate_private_key(65537, key_size=1024)
7
+ ```
8
+
9
+ ```expect
10
+ 1:1 sec-py/weak-key-size
11
+ ```
12
+
13
+ ### case: 2048
14
+
15
+ ```py
16
+ rsa.generate_private_key(65537, key_size=2048)
17
+ ```
18
+
19
+ ```expect
20
+ (none)
21
+ ```
22
+
23
+ ### case: pycrypto
24
+
25
+ ```py
26
+ RSA.generate(1024)
27
+ ```
28
+
29
+ ```expect
30
+ 1:1 sec-py/weak-key-size
31
+ ```
32
+
33
+ ### case: a small curve
34
+
35
+ ```py
36
+ ec.generate_private_key(ec.SECP192R1())
37
+ ```
38
+
39
+ ```expect
40
+ 1:25 sec-py/weak-key-size
41
+ ```
42
+
43
+ ### case: a good curve
44
+
45
+ ```py
46
+ ec.generate_private_key(ec.SECP256R1())
47
+ ```
48
+
49
+ ```expect
50
+ (none)
51
+ ```
@@ -0,0 +1,82 @@
1
+ ---
2
+ id: sec-py/weak-key-size
3
+ title: 'RSA and DSA keys are at least 2048 bits'
4
+ languages: [python]
5
+ fix: suggest
6
+ fix_reason: "a longer key makes existing signatures and certificates incompatible and slows each operation"
7
+ stability: preview
8
+ ported_from: [bandit/B505, ruff/S505]
9
+ security: { cwe: [326], owasp: ["A04:2025"], severity: high }
10
+ since: 0.2.0
11
+ ---
12
+
13
+ An RSA or DSA key is not generated shorter than 2048 bits, and an elliptic curve is at least 224 bits.
14
+
15
+ **Why:** Short keys can be factored or searched with hardware that is within reach (CWE-326).
16
+
17
+ ```codelaw
18
+ match:
19
+ any:
20
+ - kind: call
21
+ all:
22
+ - { has: { field: function, regex: '(^|\.)generate_private_key$|^(RSA|DSA)\.generate$' } }
23
+ - has:
24
+ field: arguments
25
+ has:
26
+ kind: keyword_argument
27
+ all:
28
+ - { has: { field: name, regex: '^key_size$' } }
29
+ - has:
30
+ field: value
31
+ kind: integer
32
+ regex: '^([0-9]{1,3}|1[0-9]{3}|20[0-3][0-9]|204[0-7])$'
33
+ pattern: $KS
34
+ - kind: call
35
+ all:
36
+ - { has: { field: function, regex: '^(RSA|DSA)\.generate$' } }
37
+ - has:
38
+ field: arguments
39
+ has:
40
+ nthChild: 1
41
+ kind: integer
42
+ regex: '^([0-9]{1,3}|1[0-9]{3}|20[0-3][0-9]|204[0-7])$'
43
+ pattern: $KS
44
+ - { kind: attribute, regex: '\.SECP(1[0-9]{2}|2[01][0-9]|22[0-3])[RK]1$' }
45
+ message: 'This key is too short; use 2048 bits or more'
46
+ fix:
47
+ - { replace: { target: $KS, with: '2048' } }
48
+ ```
49
+
50
+ ## How to fix
51
+
52
+ 1. Use at least 2048 bits for RSA and DSA, 3072 for keys that must last past 2030.
53
+ 2. Use `ec.SECP256R1()` or Ed25519 for new keys.
54
+ 3. Re-issue certificates signed with the old key.
55
+
56
+ ## Examples
57
+
58
+ ### Python
59
+
60
+ #### Don't
61
+
62
+ ```py
63
+ from cryptography.hazmat.primitives.asymmetric import rsa
64
+
65
+ key = rsa.generate_private_key(public_exponent=65537, key_size=1024)
66
+ ```
67
+
68
+ #### Do
69
+
70
+ ```py
71
+ from cryptography.hazmat.primitives.asymmetric import rsa
72
+
73
+ key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
74
+ ```
75
+
76
+ #### Fixed
77
+
78
+ ```py
79
+ from cryptography.hazmat.primitives.asymmetric import rsa
80
+
81
+ key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
82
+ ```
@@ -0,0 +1,67 @@
1
+ # sec-py/yaml-safe-load — cases
2
+
3
+ ### case: a bare load
4
+
5
+ ```py
6
+ import yaml
7
+
8
+ yaml.load(stream)
9
+ ```
10
+
11
+ ```expect
12
+ 3:1 sec-py/yaml-safe-load
13
+ ```
14
+
15
+ ```fixed
16
+ import yaml
17
+
18
+ yaml.safe_load(stream)
19
+ ```
20
+
21
+ ### case: an unsafe Loader
22
+
23
+ ```py
24
+ yaml.load(stream, Loader=yaml.Loader)
25
+ ```
26
+
27
+ ```expect
28
+ 1:1 sec-py/yaml-safe-load
29
+ ```
30
+
31
+ ```fixed
32
+ yaml.safe_load(stream)
33
+ ```
34
+
35
+ ### case: a positional FullLoader
36
+
37
+ ```py
38
+ yaml.load(stream, yaml.FullLoader)
39
+ ```
40
+
41
+ ```expect
42
+ 1:1 sec-py/yaml-safe-load
43
+ ```
44
+
45
+ ```fixed
46
+ yaml.safe_load(stream)
47
+ ```
48
+
49
+ ### case: SafeLoader
50
+
51
+ ```py
52
+ yaml.load(stream, Loader=yaml.SafeLoader)
53
+ ```
54
+
55
+ ```expect
56
+ (none)
57
+ ```
58
+
59
+ ### case: safe_load
60
+
61
+ ```py
62
+ yaml.safe_load(stream)
63
+ ```
64
+
65
+ ```expect
66
+ (none)
67
+ ```
@@ -0,0 +1,51 @@
1
+ ---
2
+ id: sec-py/yaml-safe-load
3
+ title: "`yaml.safe_load` instead of `yaml.load`"
4
+ languages: [python]
5
+ fix: suggest
6
+ fix_reason: "`safe_load` rejects the Python-specific tags (`!!python/object`) a document may rely on"
7
+ stability: preview
8
+ ported_from: [bandit/B506, ruff/S506]
9
+ security: { cwe: [502], owasp: ["A08:2025"], severity: high }
10
+ since: 0.2.0
11
+ ---
12
+
13
+ YAML is read with `yaml.safe_load`, or with `yaml.load` and `SafeLoader`.
14
+
15
+ **Why:** The default and full loaders build arbitrary Python objects, so a crafted document runs code (CWE-502).
16
+
17
+ ```codelaw
18
+ match:
19
+ any:
20
+ - { pattern: 'yaml.load($X)' }
21
+ - { pattern: 'yaml.load($X, Loader=$L)' }
22
+ - { pattern: 'yaml.load($X, $L)' }
23
+ constraints: { L: { not: { regex: '^(yaml\.)?(C?SafeLoader)$' } } }
24
+ message: '`yaml.load` can build arbitrary objects; use `yaml.safe_load`'
25
+ fix: 'yaml.safe_load($X)'
26
+ ```
27
+
28
+ ## How to fix
29
+
30
+ 1. Replace `yaml.load(stream)` with `yaml.safe_load(stream)`.
31
+ 2. If you pass a `Loader`, pass `yaml.SafeLoader`.
32
+
33
+ ## Examples
34
+
35
+ ### Python
36
+
37
+ #### Don't
38
+
39
+ ```py
40
+ import yaml
41
+
42
+ data = yaml.load(stream)
43
+ ```
44
+
45
+ #### Do
46
+
47
+ ```py
48
+ import yaml
49
+
50
+ data = yaml.safe_load(stream)
51
+ ```
@@ -0,0 +1,249 @@
1
+ Metadata-Version: 2.4
2
+ Name: codelaw-rules-security-python
3
+ Version: 0.3.0
4
+ Summary: codelaw's security rules for Python: CWE and OWASP Top 10:2025 mapped; PyPI only (SR-RULE-PACKS)
5
+ License-Expression: MIT
6
+ License-File: LICENSE
7
+ Project-URL: Repository, https://github.com/arpitarya/codelaw
8
+ Requires-Python: >=3.11
9
+ Description-Content-Type: text/markdown
10
+
11
+ # `codelaw-rules-security-python`
12
+
13
+ codelaw's Python security rules (Bandit's set, Django, Flask, FastAPI, ML loaders) — one of codelaw's first-party rule packs
14
+ ([SR-RULE-PACKS](../../records/0101_rule-packs.md)). It ships on PyPI only, as `codelaw-rules-security-python` (L6 decision 11).
15
+
16
+ ```toml
17
+ # codelaw.toml
18
+ extends = ["codelaw:py/recommended", "codelaw:sec-py/recommended"]
19
+ preview = true # every rule is `preview` until a corpus run promotes it
20
+ ```
21
+
22
+ `codelaw init` does not add it: a security pack is chosen, not detected.
23
+
24
+ ## Presets
25
+
26
+ <!-- docs-sync:presets -->
27
+
28
+ | preset | rules | ported from |
29
+ |---|---|---|
30
+ | `sec-py/recommended` | 57 | high-confidence rules, at `error` |
31
+ | `sec-py/strict` | 61 | `sec-py/recommended` and the heuristic rules, at `warn` |
32
+
33
+ <!-- /docs-sync:presets -->
34
+
35
+ `recommended` holds only high-confidence rules, at `error`; `strict` adds the
36
+ heuristic ones, at `warn`, so a team can start without noise.
37
+
38
+ ## Rules
39
+
40
+ 61 rules, each a `match:` rule (no Rust). Every rule carries `security: { cwe, owasp, severity }`
41
+ ([SR-RULE-FORMAT](../../records/0112_rule-format.md) decision 2a), so
42
+
43
+ - its finding names the CWE (`sec-py/<rule> (CWE-79) …`);
44
+ - `codelaw rules --tag cwe:79` and `--tag owasp:A05` find it, and
45
+ `codelaw rules --security-coverage` puts it in the OWASP Top 10:2025 matrix;
46
+ - SARIF carries its `security` and `external/cwe/cwe-<n>` tags and a
47
+ `security-severity` that GitHub code scanning ranks by
48
+ ([SR-CLI-MCP](../../records/0115_cli-and-mcp.md) decision 4).
49
+
50
+ | rule | what it flags | CWE | OWASP 2025 | fix | preset |
51
+ |---|---|---|---|---|---|
52
+ | `sec-py/no-exec-eval` | `exec`, `eval` and `compile` are not given a value that is not a string literal | 94 | A05 | manual | recommended |
53
+ | `sec-py/no-shell` | A subprocess is not started with `shell=True`, and `os.system` / `os.popen` are not given a value that is not a literal | 78 | A05 | suggest | recommended |
54
+ | `sec-py/no-sql-string` | A SQL statement is not built with an f-string, `%`, `+` or `.format`; the values go in as parameters | 89 | A05 | manual | recommended |
55
+ | `sec-py/no-unsafe-deserialize` | Data is not loaded with `pickle`, `cPickle`, `dill`, `marshal`, `shelve` or `jsonpickle` | 502 | A08 | manual | recommended |
56
+ | `sec-py/yaml-safe-load` | YAML is read with `yaml.safe_load`, or with `yaml.load` and `SafeLoader` | 502 | A08 | suggest | recommended |
57
+ | `sec-py/torch-load-weights-only` | `torch.load` is called with `weights_only=True` | 502 | A08 | suggest | recommended |
58
+ | `sec-py/hf-pin-revision` | `from_pretrained`, `hf_hub_download`, `snapshot_download` and `load_dataset` are called with `revision=` | 494 | A03 | manual | recommended |
59
+ | `sec-py/no-xml-unsafe-parser` | XML from outside the program is parsed with `defusedxml`, not with `xml.etree`, `minidom`, `sax` or `lxml` | 611 | A05 | suggest | recommended |
60
+ | `sec-py/no-tls-bypass` | Certificate verification is not switched off (`verify=False`, `_create_unverified_context`), and an SSL context is not pinned to an old protocol | 295 | A04 | suggest | recommended |
61
+ | `sec-py/requests-timeout` | `requests` and `httpx` calls pass `timeout=` | 400 | A06 | suggest | recommended |
62
+ | `sec-py/no-weak-hash` | `hashlib.md5` and `hashlib.sha1` pass `usedforsecurity=False`, or are replaced by SHA-256 | 327 | A04 | suggest | recommended |
63
+ | `sec-py/no-insecure-random` | A password, token, key, nonce or code is not made with the `random` module | 338 | A04 | suggest | recommended |
64
+ | `sec-py/no-hardcoded-secret` | A password, key or token is not a string literal in the code, and a cloud access key is not pasted into it | 798 | A07 | manual | recommended |
65
+ | `sec-py/no-insecure-tempfile` | Temporary files are made with `tempfile.mkstemp`, `NamedTemporaryFile` or `TemporaryDirectory`, not `mktemp`, and not at a fixed path under `/tmp` | 377 | A01 | suggest | recommended |
66
+ | `sec-py/tarfile-filter` | `TarFile.extractall` and `shutil.unpack_archive` pass `filter="data"` | 22 | A01 | suggest | recommended |
67
+ | `sec-py/no-path-traversal` | A value from the request is not passed to `open`, `send_file`, `send_from_directory` or `FileResponse` as a path | 22 | A01 | manual | recommended |
68
+ | `sec-py/no-ssrf` | A value from the request is not the URL given to `requests`, `httpx` or `urllib` | 918 | A01 | manual | recommended |
69
+ | `sec-py/no-open-redirect` | A value from the request is not passed to `redirect`, `HttpResponseRedirect` or `RedirectResponse` | 601 | A01 | manual | recommended |
70
+ | `sec-py/jinja-autoescape` | `Environment` is not created with `autoescape=False` or without `autoescape`, and `render_template_string` / `Template` / `from_string` are not given a template that is not a literal | 79, 1336 | A05 | suggest | recommended |
71
+ | `sec-py/no-mark-safe` | `mark_safe`, `SafeString`, `Markup` and `format_html` are not given a value that is not a literal | 79 | A05 | manual | recommended |
72
+ | `sec-py/flask-debug` | `app.run(debug=True)` is not written in code | 489 | A02 | suggest | recommended |
73
+ | `sec-py/django-settings` | In a settings module, `DEBUG`, `ALLOWED_HOSTS`, `SECRET_KEY` and the cookie flags are not left in their development values | 489, 798, 614 | A02 | manual | recommended |
74
+ | `sec-py/no-csrf-exempt` | A view is not decorated with `@csrf_exempt` | 352 | A01 | manual | recommended |
75
+ | `sec-py/fastapi-cors` | `CORSMiddleware` is not given `allow_origins=["*"]` together with `allow_credentials=True` | 942 | A02 | manual | recommended |
76
+ | `sec-py/no-assert-for-auth` | A permission, role or authentication test is not written as an `assert` | 703 | A10 | manual | recommended |
77
+ | `sec-py/no-silent-except` | An `except` that catches everything (bare, `Exception` or `BaseException`) does not just `pass` or `continue` | 703 | A10 | manual | recommended |
78
+ | `sec-py/paramiko-host-key` | `paramiko` is not told to accept unknown host keys with `AutoAddPolicy` or `WarningPolicy` | 295 | A07 | manual | recommended |
79
+ | `sec-py/no-world-writable` | `os.chmod` and `os.umask` do not give write access to everyone | 732 | A01 | suggest | recommended |
80
+ | `sec-py/no-secret-in-log` | A value named `password`, `token` or `secret` is not written to a log | 532 | A09 | manual | recommended |
81
+ | `sec-py/no-llm-output-to-sink` | The reply of an OpenAI, Anthropic or LangChain call does not reach `exec`, `eval`, a subprocess, SQL or `mark_safe` | 94 | A05 | manual | strict |
82
+ | `sec-py/no-ldap-injection` | An LDAP search filter is not made with an f-string, `%`, `+` or `.format` | 90 | A05 | manual | recommended |
83
+ | `sec-py/no-xpath-injection` | An XPath expression is not made with an f-string, `%`, `+` or `.format`; values go in as XPath variables | 643 | A05 | manual | recommended |
84
+ | `sec-py/no-nosql-injection` | A value from the request is not used whole as a `pymongo` filter, and a `$where` expression is not built from a request value | 943 | A05 | manual | recommended |
85
+ | `sec-py/no-header-injection` | A value from the request is not written into a response header or a cookie value without its line breaks removed | 113 | A05 | manual | recommended |
86
+ | `sec-py/no-log-injection` | A value from the request is not passed to a logger without its line breaks removed | 117 | A09 | manual | strict |
87
+ | `sec-py/cookie-flags` | `set_cookie` passes `secure`, `httponly` and `samesite`, and none of them is `False` or `None` | 614, 1004 | A02 | suggest | recommended |
88
+ | `sec-py/no-insecure-protocol` | `telnetlib`, `ftplib` and SNMP community strings (v1/v2c) are not used | 319 | A04 | manual | recommended |
89
+ | `sec-py/urlopen-scheme` | `urllib.request.urlopen` and `urlretrieve` are not given a value that is not an `http(s)` literal | 22, 918 | A01 | manual | recommended |
90
+ | `sec-py/no-weak-cipher` | A weak cipher (DES, 3DES, ARC2, ARC4, Blowfish, CAST5, IDEA) or ECB mode is not used | 327 | A04 | manual | recommended |
91
+ | `sec-py/no-pycrypto` | `Crypto` is not imported from the unmaintained `pycrypto` package | 1104 | A03 | manual | recommended |
92
+ | `sec-py/weak-key-size` | An RSA or DSA key is not generated shorter than 2048 bits, and an elliptic curve is at least 224 bits | 326 | A04 | suggest | recommended |
93
+ | `sec-py/password-hash-effort` | A password is not hashed with a plain `hashlib` digest, `pbkdf2_hmac` runs at least 600 000 iterations, and `bcrypt` uses at least 10 rounds | 916 | A04 | manual | recommended |
94
+ | `sec-py/no-hardcoded-crypto-key` | A cipher key, HMAC key, IV or nonce is not a literal | 321, 329 | A04 | manual | recommended |
95
+ | `sec-py/no-mako` | `mako.template.Template` is not used | 79 | A05 | manual | recommended |
96
+ | `sec-py/logging-listen` | `logging.config.listen()` is not called | 94 | A08 | manual | recommended |
97
+ | `sec-py/no-wildcard-injection` | A command that runs `tar`, `chown`, `chmod` or `rsync` on `*` is not started through a shell | 155 | A05 | manual | recommended |
98
+ | `sec-py/no-partial-path` | A subprocess is not started with a bare program name such as `"git"` | 426 | A08 | manual | strict |
99
+ | `sec-py/no-xmlrpc` | An `xmlrpc` client or server is not created without `defusedxml.xmlrpc.monkey_patch()` in the program | 776 | A05 | manual | recommended |
100
+ | `sec-py/no-mass-assignment` | `Model(**request.POST)`, `Model.objects.create(**request.data)` and `update(**request.json)` are not used, and a `ModelForm` or serializer does not set `fields = "__all__"` | 915 | A01 | manual | recommended |
101
+ | `sec-py/no-reflected-xss` | A value from the request is not passed to `HttpResponse`, `make_response` or `HTMLResponse`, or built into a returned string, without escaping | 79 | A05 | manual | recommended |
102
+ | `sec-py/flask-settings` | `SECRET_KEY` is not a literal, and `WTF_CSRF_ENABLED` and `SESSION_COOKIE_SECURE` are not switched off in the app configuration | 798, 352, 614 | A02 | manual | recommended |
103
+ | `sec-py/no-dynamic-import` | A value from the request is not passed to `__import__`, `importlib.import_module` or `getattr` | 470 | A05 | manual | recommended |
104
+ | `sec-py/upload-secure-filename` | A file from a request is not saved under the name the client gave it | 434, 22 | A01 | suggest | recommended |
105
+ | `sec-py/ml-unsafe-load` | `numpy.load(allow_pickle=True)`, `joblib.load`, `pandas.read_pickle` and Keras `load_model(safe_mode=False)` are not used | 502 | A08 | manual | recommended |
106
+ | `sec-py/no-trust-remote-code` | `from_pretrained`, `load_dataset` and `pipeline` are not called with `trust_remote_code=True` | 94 | A03 | manual | recommended |
107
+ | `sec-py/no-prompt-injection` | A value from the request is not part of the system prompt of a language-model call | 1427 | A05 | manual | recommended |
108
+ | `sec-py/no-bind-all-interfaces` | A socket or server is not bound to `0.0.0.0` in the source | 605 | A02 | manual | strict |
109
+ | `sec-py/no-regex-injection` | A value from the request is not used as the pattern of `re.compile`, `re.search`, `re.match` or the other `re` functions | 730, 1333 | A06 | suggest | recommended |
110
+ | `sec-py/no-format-string-injection` | A value from the request is not the receiver of `.format` | 134 | A05 | manual | recommended |
111
+ | `sec-py/no-cleartext-http` | `requests` and `httpx` are not called with an `http://` URL, except for localhost | 319 | A04 | manual | recommended |
112
+ | `sec-py/no-stack-trace-response` | A response does not contain `traceback.format_exc()` or the text of the exception | 209 | A10 | manual | recommended |
113
+
114
+ A rule that says `suggest` has a `fix:` that `codelaw fix --unsafe` applies to
115
+ the common shape of the code; a match of another shape stays `manual`, with
116
+ the steps in the rule's *How to fix*. Three rules the catalogue called
117
+ `suggest` are `manual` here, because no edit of the code alone is right:
118
+ `sec-py/no-xpath-injection` (the expression has to be rewritten around
119
+ variables), `sec-py/no-xmlrpc` (the patch must run at start-up) and
120
+ `sec-py/no-cleartext-http` (the server must serve HTTPS first).
121
+
122
+ ## What the rules see
123
+
124
+ The rules match the code **as written**. They follow an alias only where a
125
+ rule says so (`sec-py/no-xml-unsafe-parser` and `sec-py/no-mako` use the
126
+ `imported-from` predicate); `import numpy as np` is matched by its common
127
+ name `np`, and `from subprocess import run` is not matched at all. A value
128
+ that a function receives as a parameter is not a request value.
129
+
130
+ ### `from_source:` is not taint analysis
131
+
132
+ A rule here that asks whether a sink's argument comes from a request
133
+ uses the `from_source:` predicate ([SR-RULE-FORMAT](../../records/0112_rule-format.md)
134
+ decision 3a). It holds when the argument **is** a listed request source
135
+ (or a method called on one), is built from one by concatenation,
136
+ interpolation or `?:`, or is a local name bound to one **in the same
137
+ function** — one or more assignments or destructurings away. It never
138
+ follows a call, a return value, a parameter, a closure's outer variable or
139
+ another file, so a value that crosses a function boundary is not seen
140
+ (cross-function flow waits on a deeper analysis, as B-049's type-aware
141
+ rules do). Every rule page that uses it says so. The sources are listed per
142
+ framework in this pack's `data/sources/<framework>.json`: Django
143
+ (`request.GET`, `request.POST`, `request.COOKIES`, `request.body`,
144
+ `request.FILES`, `request.META`, `request.headers`, DRF's `request.data` and
145
+ `request.query_params`), Flask (`request.args`, `form`, `values`, `json`,
146
+ `get_json`, `data`, `cookies`, `files`, `headers`, `view_args`) and
147
+ FastAPI/Starlette's `Request` (`query_params`, `path_params`, `headers`,
148
+ `cookies`, `form`, `json`, `body`).
149
+
150
+ Two limits follow. FastAPI's typed handler parameters (`def f(q: str)`) are
151
+ function parameters, so they are not sources; only the `request` object is.
152
+ And a method called on a source stays a source: `request.args.get("x").strip()`
153
+ is still the request value, so the way out of a finding is to pass the value
154
+ through a function of your own.
155
+
156
+ ## Not ported, and why
157
+
158
+ This pack accounts for every check of
159
+ [Bandit](https://bandit.readthedocs.io/en/latest/plugins/index.html)
160
+ (Apache-2.0) and the Ruff `S` rules (MIT) that mirror it. The rules are
161
+ written for codelaw; `ported_from:` names the Bandit and Ruff ids they cover
162
+ ([NOTICE](NOTICE)).
163
+
164
+ | Bandit | Ruff | status | where |
165
+ |---|---|---|---|
166
+ | B101 `assert_used` | S101 | partly | `sec-py/no-assert-for-auth`: only an `assert` that is an access check; an `assert` in general is not a security flaw |
167
+ | B102 `exec_used` | S102 | ported | `sec-py/no-exec-eval` |
168
+ | B103 `set_bad_file_permissions` | S103 | ported | `sec-py/no-world-writable` |
169
+ | B104 `hardcoded_bind_all_interfaces` | S104 | ported | `sec-py/no-bind-all-interfaces` (`strict`) |
170
+ | B105, B106, B107 hard-coded passwords | S105, S106, S107 | ported | `sec-py/no-hardcoded-secret`; Django and Flask settings in `sec-py/django-settings` and `sec-py/flask-settings` |
171
+ | B108 `hardcoded_tmp_directory` | S108 | ported | `sec-py/no-insecure-tempfile` |
172
+ | B110, B112 `try_except_pass`, `try_except_continue` | S110, S112 | ported | `sec-py/no-silent-except` |
173
+ | B113 `request_without_timeout` | S113 | ported | `sec-py/requests-timeout` |
174
+ | B201 `flask_debug_true` | S201 | ported | `sec-py/flask-debug` |
175
+ | B202 `tarfile_unsafe_members` | S202 | ported | `sec-py/tarfile-filter` |
176
+ | B301, B302 `pickle`, `marshal` | S301, S302 | ported | `sec-py/no-unsafe-deserialize` |
177
+ | B303 `md5`, `sha1` | S303 | ported | `sec-py/no-weak-hash` |
178
+ | B304, B305 ciphers and modes | S304, S305 | ported | `sec-py/no-weak-cipher` |
179
+ | B306 `mktemp_q` | S306 | ported | `sec-py/no-insecure-tempfile` |
180
+ | B307 `eval` | S307 | ported | `sec-py/no-exec-eval` |
181
+ | B308 `mark_safe` | S308 | ported | `sec-py/no-mark-safe` |
182
+ | B309 `httpsconnection` | - | not ported | Python 2.7 and early 3.x only: `http.client.HTTPSConnection` verifies certificates by default since 3.4.3 |
183
+ | B310 `urllib_urlopen` | S310 | ported | `sec-py/urlopen-scheme` |
184
+ | B311 `random` | S311 | ported | `sec-py/no-insecure-random`: only when the value is bound to a secret-like name; `random` for a dice roll is fine |
185
+ | B312 `telnetlib` | S312 | ported | `sec-py/no-insecure-protocol` (at the import) |
186
+ | B313 to B320 XML calls | S313 to S320 | ported | `sec-py/no-xml-unsafe-parser` |
187
+ | B321 `ftplib` | S321 | ported | `sec-py/no-insecure-protocol` (at the import) |
188
+ | B322 `input` | - | not ported | Python 2's `input` evaluates its input; Python 3's does not |
189
+ | B323 `unverified_context` | S323 | ported | `sec-py/no-tls-bypass` |
190
+ | B324 `hashlib` | S324 | ported | `sec-py/no-weak-hash` |
191
+ | B325 `tempnam` | S325 | ported | `sec-py/no-insecure-tempfile` (`os.tempnam`, `os.tmpnam`) |
192
+ | B401, B402 `telnetlib`, `ftplib` imports | S401, S402 | ported | `sec-py/no-insecure-protocol` |
193
+ | B403 `pickle` import | S403 | covered elsewhere | the load call is flagged by `sec-py/no-unsafe-deserialize`; importing `pickle` to write it is not a flaw |
194
+ | B404 `subprocess` import | S404 | not ported | an import alone flags every program that runs a command; the calls are `sec-py/no-shell` and `sec-py/no-partial-path` |
195
+ | B405 to B410 XML imports | S405 to S410 | covered elsewhere | the parse calls are flagged by `sec-py/no-xml-unsafe-parser`; the import of a parser is not |
196
+ | B411 `xmlrpc` import | S411 | ported | `sec-py/no-xmlrpc` (at the client or server call) |
197
+ | B412 `httpoxy` | S412 | not ported | CGI handlers (`wsgiref.handlers.CGIHandler`) are rare, and web servers now drop the `Proxy` header |
198
+ | B413 `pycrypto` | S413 | ported | `sec-py/no-pycrypto` |
199
+ | B414 `pycryptodome` | - | not ported | Bandit dropped it: `pycryptodome` is maintained |
200
+ | B415 `pyghmi` | S415 | not ported | plain-text IPMI, a niche library; `sec-py/no-insecure-protocol` covers the common ones |
201
+ | B501 to B504 TLS | S501 to S504 | ported | `sec-py/no-tls-bypass` |
202
+ | B505 `weak_cryptographic_key` | S505 | ported | `sec-py/weak-key-size` |
203
+ | B506 `yaml_load` | S506 | ported | `sec-py/yaml-safe-load` |
204
+ | B507 `ssh_no_host_key_verification` | S507 | ported | `sec-py/paramiko-host-key` |
205
+ | B508 `snmp_insecure_version` | S508 | ported | `sec-py/no-insecure-protocol` |
206
+ | B509 `snmp_weak_cryptography` | S509 | not ported | needs the `UsmUserData` protocol arguments checked; only the v1/v2c community string is flagged |
207
+ | B601 `paramiko_calls` | S601 | not ported | `exec_command` runs on the remote host and is flagged by Bandit for any call; no safe rewrite to name |
208
+ | B602, B604, B605 shell | S602, S604, S605 | ported | `sec-py/no-shell` |
209
+ | B603 `subprocess_without_shell_equals_true` | S603 | not ported | informational in Bandit and flags every `subprocess` call; the dangerous cases are `sec-py/no-shell` and `sec-py/no-wildcard-injection` |
210
+ | B606 `start_process_with_no_shell` | S606 | not ported | `os.exec*` and `os.spawn*` are rare; `sec-py/no-partial-path` covers `subprocess` and `os.system` |
211
+ | B607 `start_process_with_partial_path` | S607 | ported | `sec-py/no-partial-path` (`strict`) |
212
+ | B608 `hardcoded_sql_expressions` | S608 | ported | `sec-py/no-sql-string`: from the call that runs the statement, not from a string that looks like SQL |
213
+ | B609 `linux_commands_wildcard_injection` | S609 | ported | `sec-py/no-wildcard-injection` |
214
+ | B610, B611 Django `extra`, `RawSQL` | S610, S611 | ported | `sec-py/no-sql-string` |
215
+ | B612 `logging_config_insecure_listen` | S612 | ported | `sec-py/logging-listen` |
216
+ | B613 `trojansource` | - | not ported | bidirectional control characters in the source bytes; a rule reads the syntax tree and does not see them |
217
+ | B614 `pytorch_load` | - | ported | `sec-py/torch-load-weights-only` |
218
+ | B615 `huggingface_unsafe_download` | - | ported | `sec-py/hf-pin-revision` |
219
+ | B701 `jinja2_autoescape_false` | S701 | ported | `sec-py/jinja-autoescape` |
220
+ | B702 `use_of_mako_templates` | S702 | ported | `sec-py/no-mako` |
221
+ | B703 `django_mark_safe` | S703 | ported | `sec-py/no-mark-safe` |
222
+ | B704 `markupsafe_markup_xss` | S704 | ported | `sec-py/no-mark-safe` |
223
+
224
+ Beyond Bandit and Ruff the pack adds the framework and library rules of the
225
+ catalogue: Django, Flask and FastAPI settings and sinks, mass assignment,
226
+ uploads, header, LDAP, XPath and NoSQL injection, ML model loading
227
+ (`torch.load`, `joblib`, `numpy`, Hugging Face), `trust_remote_code`, prompt
228
+ injection and language-model output reaching a sink. Two parts of the catalogue are not
229
+ built: the `strict` ReDoS check for a literal pattern with nested quantifiers
230
+ (`sec-py/no-regex-injection` handles only a request-supplied pattern), and a
231
+ `from_source` check on every argument of a call (it reads the first, and for a
232
+ logger the second).
233
+
234
+ ## Corpus
235
+
236
+ `packs/security-python/corpus.toml` holds the finding count per rule over the
237
+ pinned repositories (`scripts/corpus.json`): Flask, Starlette,
238
+ full-stack-fastapi-template and djangoproject.com, 946 files. On 2026-10-26
239
+ the rules gave **34 findings, all of them read by hand: one false positive**
240
+ (`sec-py/no-open-redirect` on a redirect to a trusted URL that had `?q=…`
241
+ appended from the request, which `from_source:` cannot tell from a hostile
242
+ target), about 3%. The other 33 are what the rules say: a `mark_safe` of a
243
+ non-literal, an MD5 or SHA-1 digest, an `exec` of a config file, a request
244
+ without a `timeout`, a `subprocess` started by a bare name (`strict`), and
245
+ the like. Two limits of that number: four repositories are a small sample,
246
+ and the noisy rules skip test files (`exclude:` in their frontmatter) because
247
+ the first run, before they did, was mostly asserts and `password="password"`
248
+ in tests. Every rule is `preview` until its count has been reviewed again
249
+ over a larger corpus.
@@ -0,0 +1,136 @@
1
+ codelaw_rules_security_python/LICENSE,sha256=_R8NFLyGiKUo7mPzbUGbqg3hdEKYhaTsIgBGXqtFfa8,1097
2
+ codelaw_rules_security_python/NOTICE,sha256=I5c_ZIxoE-PJcMJpjDP9MG2WT5TS7QA36DO_58fI2Qo,1100
3
+ codelaw_rules_security_python/README.md,sha256=T8L_yTB8NsMKFO7NahW536QUNGgjuSy28BcJ17Y7Xqg,21535
4
+ codelaw_rules_security_python/codelaw-pack.toml,sha256=Q4E2eLKNaKLZRTRZlRrJn-vav5YuYznMLaJRUGOrjxA,265
5
+ codelaw_rules_security_python/corpus.toml,sha256=7kCkBqK0TlzXL5ej4948CgI2EwrFOgOx4KccG-60rqk,1986
6
+ codelaw_rules_security_python/data/sources/django.json,sha256=kopyhAr3eY8lIf9Uty8wci4f8u1J3twKQRzflRKEK8U,327
7
+ codelaw_rules_security_python/data/sources/fastapi.json,sha256=ePtnSdeNuLqstvRQ1XP0Rel3fCjwQm6gIWV02n8VCpI,170
8
+ codelaw_rules_security_python/data/sources/flask.json,sha256=7AeuNT6MLWNM068ZgxyaUI17kNyYJzI_yXXWMRnK5g4,243
9
+ codelaw_rules_security_python/presets/sec-py/recommended.toml,sha256=Vf4Y2omb5IAAmFn18eE9HcCBM442LX0CfyGI2nnQ_fk,2133
10
+ codelaw_rules_security_python/presets/sec-py/strict.toml,sha256=hUL0Npbe5RcGK8_pPRqxyVlGJqD2G5LBjT5psb84y-c,277
11
+ codelaw_rules_security_python/rules/sec-py/cookie-flags.cases.md,sha256=xI4glUrdBRxb-W7SyE-naFssXaFpQUVfAf-WQGTp2wo,818
12
+ codelaw_rules_security_python/rules/sec-py/cookie-flags.md,sha256=HUIFGqhDrDpdvTGTJqux5cmjh2SbOi_FRzRZuxumz08,3235
13
+ codelaw_rules_security_python/rules/sec-py/django-settings.cases.md,sha256=SI9FXe1FEaQlSNFLG7Qa4fRmuZPoBGQteQjAmMe5NNw,738
14
+ codelaw_rules_security_python/rules/sec-py/django-settings.md,sha256=yBxipH_y89YZ7T06xNmIF3csSKlOiOetJ6VGdPBsvfg,2303
15
+ codelaw_rules_security_python/rules/sec-py/fastapi-cors.cases.md,sha256=Z5FLQYtsSv_Y_8Gx2UjqoAeCyaYgpCSw0IYcb4CLHMw,483
16
+ codelaw_rules_security_python/rules/sec-py/fastapi-cors.md,sha256=18iO3b1OwBbhSHFbPN-lqqZHw3-7Y0QJ4meUvkh94oU,1288
17
+ codelaw_rules_security_python/rules/sec-py/flask-debug.cases.md,sha256=YODqWw22aWjIZK1J7b6oVfeTLGf8QwyavTVLZwq5NfQ,280
18
+ codelaw_rules_security_python/rules/sec-py/flask-debug.md,sha256=Di85uSsqH9NfNHRdECriJbdNOTQW9rBTAPlGgI1cork,1449
19
+ codelaw_rules_security_python/rules/sec-py/flask-settings.cases.md,sha256=DhKAcPaxaOEeivMSf2HUwD3a9xYhr-7unKRxBIA3iA8,584
20
+ codelaw_rules_security_python/rules/sec-py/flask-settings.md,sha256=aq3RM2SKy4339Om0mV4maCbPbU7sRZuSeYR62KazIH0,2884
21
+ codelaw_rules_security_python/rules/sec-py/hf-pin-revision.cases.md,sha256=ARuVN_1DZk6Bd2eQ8-2xsJgAzGz_aoibtnwJKc5Pyf8,595
22
+ codelaw_rules_security_python/rules/sec-py/hf-pin-revision.md,sha256=Qmb0gwPvwhl9DtwTUtUjHmmuNVAlrFe1-iLsR1DmTqU,1529
23
+ codelaw_rules_security_python/rules/sec-py/jinja-autoescape.cases.md,sha256=-kMJkwPZ1SjQSAAJkZogL3326ckG5bqWW4feBA2K-EA,732
24
+ codelaw_rules_security_python/rules/sec-py/jinja-autoescape.md,sha256=vHNhu_SuguAFmy46FgVkJWmxY8LVtvb6invvIcuuPCM,2286
25
+ codelaw_rules_security_python/rules/sec-py/logging-listen.cases.md,sha256=XTFws7H-7B7s7uZGIqrpHoq4UELslE5drwHmOQO0Yj0,292
26
+ codelaw_rules_security_python/rules/sec-py/logging-listen.md,sha256=9w9jzuBr9k8_cGnBXw26T2x5QWr7gexYXRDYX1kUrH0,1132
27
+ codelaw_rules_security_python/rules/sec-py/ml-unsafe-load.cases.md,sha256=n0Ces_BDR4RatAsWnNW9mW2j5v0uIn_xs2g89Q6T01Y,585
28
+ codelaw_rules_security_python/rules/sec-py/ml-unsafe-load.md,sha256=oJ00fhmBtV3zC-OU4pg4YyDf74iiLtwiZaD0gOPkgcM,1944
29
+ codelaw_rules_security_python/rules/sec-py/no-assert-for-auth.cases.md,sha256=fn_aGMNGV4hJa0ecSUNOIJJ9jlwSn01eftjBNa0yUFA,338
30
+ codelaw_rules_security_python/rules/sec-py/no-assert-for-auth.md,sha256=O2YZ7SYZnvLLngF9PEn_66IHsnAbWezVHBh7OIGlt98,1432
31
+ codelaw_rules_security_python/rules/sec-py/no-bind-all-interfaces.cases.md,sha256=ivhe3vmSv8POLVa98KQOkhIeVos4JqYSt-cYKr2aKqI,419
32
+ codelaw_rules_security_python/rules/sec-py/no-bind-all-interfaces.md,sha256=xl_Y1JPfeXeboBuy5xYetqJZc14Ro71FJYEKeztlK4c,2010
33
+ codelaw_rules_security_python/rules/sec-py/no-cleartext-http.cases.md,sha256=1Xjc04kIeUXl25gduOWVzRyT2z_YiinpKXBZiE1pFx4,458
34
+ codelaw_rules_security_python/rules/sec-py/no-cleartext-http.md,sha256=yPDZA4pJigoEMLm_POeRmxlYyONYXRH-fCj8cc7S8mk,1308
35
+ codelaw_rules_security_python/rules/sec-py/no-csrf-exempt.cases.md,sha256=0C6NuUPuSyxFDqCLyPrlOnNo8knm1aoCvNo6SQsSzpw,457
36
+ codelaw_rules_security_python/rules/sec-py/no-csrf-exempt.md,sha256=6pHRkTT63pn-plkHrwaqBA9Ladp2wXGwSX5fbP5_s8g,1051
37
+ codelaw_rules_security_python/rules/sec-py/no-dynamic-import.cases.md,sha256=13mKQBcBU_4t2TL-4H_h8VHJGm1SW7U3R90ICOEG4-c,445
38
+ codelaw_rules_security_python/rules/sec-py/no-dynamic-import.md,sha256=sw3aXGPb6501gzKchubtnu0RwcRfUJ8wxSqEi4NyujA,1512
39
+ codelaw_rules_security_python/rules/sec-py/no-exec-eval.cases.md,sha256=9RJytLwZ79i0il6HpXT1PQcIhVJW1q5M9DRdFQxnvLY,478
40
+ codelaw_rules_security_python/rules/sec-py/no-exec-eval.md,sha256=i5J3P-4WndmXeWT2FUw4Bxd6VhaIaUZ7Pxoqk9B_cpk,1459
41
+ codelaw_rules_security_python/rules/sec-py/no-format-string-injection.cases.md,sha256=XD_rYPkQDVvaHkirhj_wPi8ZaJ0O8IFTqMiw7dWJhDg,480
42
+ codelaw_rules_security_python/rules/sec-py/no-format-string-injection.md,sha256=ZqFCjihKa7OtwoaRyuQTvGHgJSPb8EvYQSP1P6V4VT8,1379
43
+ codelaw_rules_security_python/rules/sec-py/no-hardcoded-crypto-key.cases.md,sha256=ch4k31D1KBp_sQq2_pn9jM0eq5XdNhmGuI1hQFcfrkY,588
44
+ codelaw_rules_security_python/rules/sec-py/no-hardcoded-crypto-key.md,sha256=fp9NjSO8boy6xMQMMQzk5_4T44BAo308A7atP8Yyy3c,2947
45
+ codelaw_rules_security_python/rules/sec-py/no-hardcoded-secret.cases.md,sha256=PvIJLkgZiWpFOn-bURv1S5VxJ2ZiSsv5wM4R870bBkk,669
46
+ codelaw_rules_security_python/rules/sec-py/no-hardcoded-secret.md,sha256=opAA1G6D833jHOcUD1P2qV9zDRJZibjGiWtYwKW6JdA,2969
47
+ codelaw_rules_security_python/rules/sec-py/no-header-injection.cases.md,sha256=JEXhxP-iaWslxVKAOksUkjVu5C9A_cWpK0tTWKAx2Xw,526
48
+ codelaw_rules_security_python/rules/sec-py/no-header-injection.md,sha256=nEge53cgzIa1l5qSlOI6SI5tx-18NydMyksnDIDHGXI,1766
49
+ codelaw_rules_security_python/rules/sec-py/no-insecure-protocol.cases.md,sha256=NG4CFrdKjTr-CQS8jviLaXAzurEiplQZMwhsdwfnewE,404
50
+ codelaw_rules_security_python/rules/sec-py/no-insecure-protocol.md,sha256=swl_iKw1e3oKH01lwjfpBnUS-2HYkJ43qizTEB3fYCA,1413
51
+ codelaw_rules_security_python/rules/sec-py/no-insecure-random.cases.md,sha256=z2QL5JVsDVpaWCwys6NlsTQ-RenrJkFNThXX2z130zc,430
52
+ codelaw_rules_security_python/rules/sec-py/no-insecure-random.md,sha256=GLB3xZEXZY5iPvH-aAxS_twUTzwyeR6cFYFgj7ja2Ko,1545
53
+ codelaw_rules_security_python/rules/sec-py/no-insecure-tempfile.cases.md,sha256=ZbEXV3QSi3MHcg-FOWJofFQXgJwZZySiV_MRj2wXy9s,432
54
+ codelaw_rules_security_python/rules/sec-py/no-insecure-tempfile.md,sha256=V3EETTbYnG_uwffqLpR-oW8qXsYAQ6Ta5bM_iNwrHHo,1531
55
+ codelaw_rules_security_python/rules/sec-py/no-ldap-injection.cases.md,sha256=0yd9c6Rkgc6SFcTZ_agNdX1hQo9RPvveDFcjRlXmrUE,461
56
+ codelaw_rules_security_python/rules/sec-py/no-ldap-injection.md,sha256=2T06bXVdd7Pr2DEPSenFs5z7RKu1LcjzYi88l6GzAoc,1427
57
+ codelaw_rules_security_python/rules/sec-py/no-llm-output-to-sink.cases.md,sha256=HSjojlHwC88SguVjKm_jCZoFYSs8dtea4pSsvp4Q9tQ,368
58
+ codelaw_rules_security_python/rules/sec-py/no-llm-output-to-sink.md,sha256=M9bdnMgzDZAaL6wwiDOivQ6JL38vX8BdWVG-XkpVqNo,1732
59
+ codelaw_rules_security_python/rules/sec-py/no-log-injection.cases.md,sha256=wO5Aqz170Nx1ojMj2WL1CP4a0riFwcVh27e776fCTiw,536
60
+ codelaw_rules_security_python/rules/sec-py/no-log-injection.md,sha256=04fJYQf6g-rYNZtiZxFk9mLcGBhHGTxT1Jm-s5tFzJw,1730
61
+ codelaw_rules_security_python/rules/sec-py/no-mako.cases.md,sha256=XYjI8HKimIszoV5picmlNg9pcm3XB6HObDIt6t5PS70,360
62
+ codelaw_rules_security_python/rules/sec-py/no-mako.md,sha256=lPz_CXEgIzoVo196Qe970aZcCeHBY-BJAZ0F4wKSdP8,1277
63
+ codelaw_rules_security_python/rules/sec-py/no-mark-safe.cases.md,sha256=0gLF4XzpOAgpfc5eEhwuCUoYuc1N2VmibQS3aKcvn7A,488
64
+ codelaw_rules_security_python/rules/sec-py/no-mark-safe.md,sha256=l5hYrzvqXz1lPzNEyNL-66_TrGt19aXno4t1sOb_Ucs,1524
65
+ codelaw_rules_security_python/rules/sec-py/no-mass-assignment.cases.md,sha256=pNYIVb3bSPxg0XZMjaPJeL9QKIAYkd63__hG4HqDZn0,593
66
+ codelaw_rules_security_python/rules/sec-py/no-mass-assignment.md,sha256=w08H1WKZywFoOKN3cNYq6DrcBMcvul_z6bjp_Hb0k6E,1670
67
+ codelaw_rules_security_python/rules/sec-py/no-nosql-injection.cases.md,sha256=oWd18Lp4AwNK2mgU97YRhdUT4e1FhJ7_-JAaqmhdLZg,460
68
+ codelaw_rules_security_python/rules/sec-py/no-nosql-injection.md,sha256=kHZCE67qW96fEm2pYYLsfmPTfUv0ERbCLvweWg1A4gU,1950
69
+ codelaw_rules_security_python/rules/sec-py/no-open-redirect.cases.md,sha256=KDF2AGSVMW2WrllKpxICfQZLeiY3hwzOkLM-mOoCx8o,435
70
+ codelaw_rules_security_python/rules/sec-py/no-open-redirect.md,sha256=nvemD_S4rwEp_4uGJnYEQdqpUfLsZcE4WtuelBz1oOA,1598
71
+ codelaw_rules_security_python/rules/sec-py/no-partial-path.cases.md,sha256=G7qBUzSbeetBRULL4HUMheKgxiuEImxwn1rKu4bM1F4,450
72
+ codelaw_rules_security_python/rules/sec-py/no-partial-path.md,sha256=-90duEFxl0Ydc9L5VSE2IYxZ9mPAt2qC3V-looPCNwc,1522
73
+ codelaw_rules_security_python/rules/sec-py/no-path-traversal.cases.md,sha256=x1joUXMrFT-j6Ii4Fxj_qSYp_KKp4pl1R2Lx9Q3IwmU,533
74
+ codelaw_rules_security_python/rules/sec-py/no-path-traversal.md,sha256=zJmvdNPbRpSjNNEB6sRGIpMD-0_wR3w84mcpQ-frLWQ,1740
75
+ codelaw_rules_security_python/rules/sec-py/no-prompt-injection.cases.md,sha256=kKLzEeYl7Md-mfrUTAnKTJNbA1FsoHolspV71V1Ngbw,644
76
+ codelaw_rules_security_python/rules/sec-py/no-prompt-injection.md,sha256=oVxTNSbMrYYb5aF-IBMTdxI8ezN54emaPOFYvUST5Xs,2164
77
+ codelaw_rules_security_python/rules/sec-py/no-pycrypto.cases.md,sha256=odkuJrXbYDs0gUiaHTdeQz-JQqJCisn6gLhnnk-Nu-4,396
78
+ codelaw_rules_security_python/rules/sec-py/no-pycrypto.md,sha256=hWacG8YYee4HpGFXgIPc_WY11C2p-2-aL-7xql1qYco,1318
79
+ codelaw_rules_security_python/rules/sec-py/no-reflected-xss.cases.md,sha256=xkqnciGWxoyrTxzdx2iXNA0neFgvZYLPbU2oTgI2Ans,532
80
+ codelaw_rules_security_python/rules/sec-py/no-reflected-xss.md,sha256=1yid96GaNwKamb0Uxnkf9oXaZ0QX9pnNgQy-eX-oO2c,1930
81
+ codelaw_rules_security_python/rules/sec-py/no-regex-injection.cases.md,sha256=8m2drHxndYpZYAb1l87PeJRE6iE9LCwThkdg7kCqzSg,380
82
+ codelaw_rules_security_python/rules/sec-py/no-regex-injection.md,sha256=AV6S8RiC0taNAPFAExUEuqeM5s7VlkVYkMlonfOr6IM,1631
83
+ codelaw_rules_security_python/rules/sec-py/no-secret-in-log.cases.md,sha256=vD0GAVDM_ngghttsNFLMP_gMswc2nTd2C6Lct9sTDCE,423
84
+ codelaw_rules_security_python/rules/sec-py/no-secret-in-log.md,sha256=Ltz6b3TCNNzgezDX3X07v88sBQq4eRVoxq5460fzS4E,1451
85
+ codelaw_rules_security_python/rules/sec-py/no-shell.cases.md,sha256=8OHYSRDRdqawfsbJFmnlrlcVzF6041cnvVP6SangwHU,563
86
+ codelaw_rules_security_python/rules/sec-py/no-shell.md,sha256=bx7Brkl3lxKJzF083xpZVuIznV8k6w2oiAu6oAEA9OY,1762
87
+ codelaw_rules_security_python/rules/sec-py/no-silent-except.cases.md,sha256=gcTBZaFsVXeTFwBYDYcOFAUxaHJH-CGg0d6DXbrp8-Y,467
88
+ codelaw_rules_security_python/rules/sec-py/no-silent-except.md,sha256=Z5rF5ri6thoPt6SNvx_VL6vo138xz2De05NDL1Xc1RM,1339
89
+ codelaw_rules_security_python/rules/sec-py/no-sql-string.cases.md,sha256=_o60UU0_dUulSdqoIzjhjsAkCoVy9knOeu_uzIxHiX4,1087
90
+ codelaw_rules_security_python/rules/sec-py/no-sql-string.md,sha256=cCpD0oCpz6njkDF7JkVjEF9_7YX24oCMvh48UD2HMww,2656
91
+ codelaw_rules_security_python/rules/sec-py/no-ssrf.cases.md,sha256=GB9Xydct2LldgGLyBTY-9CkZz0Oq1rnekSwvGcsjw7E,454
92
+ codelaw_rules_security_python/rules/sec-py/no-ssrf.md,sha256=jj7wL6kX-hUhiE5BQD1fB0Y1i66YLMkBSJ-Zk8n_UO8,1782
93
+ codelaw_rules_security_python/rules/sec-py/no-stack-trace-response.cases.md,sha256=uiTyRwSV9Sm4oA06_EaNsCiO93uM2QU239EYHi_et1M,529
94
+ codelaw_rules_security_python/rules/sec-py/no-stack-trace-response.md,sha256=JodSReesiOozdvBYU93kJDZrCK5L4ss8YKRTXMYBXTQ,1905
95
+ codelaw_rules_security_python/rules/sec-py/no-tls-bypass.cases.md,sha256=KpXyvEAz9T9gG4OZ0PMcgL224JrHWtdiEhdJ0_SPo5w,805
96
+ codelaw_rules_security_python/rules/sec-py/no-tls-bypass.md,sha256=RKxGoZ5veAcl-2SFfwFxS18XswuPtB6h7xX8J3bpLHI,2198
97
+ codelaw_rules_security_python/rules/sec-py/no-trust-remote-code.cases.md,sha256=yt4XGu7Ialx9J5K17mRRXPTYNWK-ul0CmKn_zO910IQ,403
98
+ codelaw_rules_security_python/rules/sec-py/no-trust-remote-code.md,sha256=IPMfIzSt-GAMrfegyMQGmAM5WidEkfQ2QVsKPnBLEdI,1404
99
+ codelaw_rules_security_python/rules/sec-py/no-unsafe-deserialize.cases.md,sha256=mHtX0wPs8CRMaGd5DDQvXweolg-fCRGdfEQYGj2ah1o,590
100
+ codelaw_rules_security_python/rules/sec-py/no-unsafe-deserialize.md,sha256=jL8x36irhEXq1GdsESgHTQD1Wf3N5Ln4bm39321yvn0,1296
101
+ codelaw_rules_security_python/rules/sec-py/no-weak-cipher.cases.md,sha256=AXpoaFe_ACCwzPjvZTvmcWx8ivtCZF-mB-vuT--9cAY,495
102
+ codelaw_rules_security_python/rules/sec-py/no-weak-cipher.md,sha256=nOCPQWaM79QIXo9s13d9yNPKU6975qsKa0P6oG6Z_wc,1593
103
+ codelaw_rules_security_python/rules/sec-py/no-weak-hash.cases.md,sha256=HCjazWiSskDoNR6JIN6eekmIUC04BWfza4P92gl91YQ,374
104
+ codelaw_rules_security_python/rules/sec-py/no-weak-hash.md,sha256=2J7Wv-u2fpLFBP_RGtsvEaWsqMaKPlJcRAfzc3XAfZg,1395
105
+ codelaw_rules_security_python/rules/sec-py/no-wildcard-injection.cases.md,sha256=u3BYFcGFCdJd0u4qDXM0HRKndrDtS9Q7KvEClqP2Qt4,418
106
+ codelaw_rules_security_python/rules/sec-py/no-wildcard-injection.md,sha256=kDUIYIc00iKm0ei7p2AaNFIaC8Qcku8RDH4TNEpZRiA,1401
107
+ codelaw_rules_security_python/rules/sec-py/no-world-writable.cases.md,sha256=rWUSyAyo9w0LEgbklFmYsCHYs0N-dj95ADxYI9pSiU8,464
108
+ codelaw_rules_security_python/rules/sec-py/no-world-writable.md,sha256=QVrVyFd3HrAfx5dlhIwydO_752gNVYSJ2FaKV70xeno,1112
109
+ codelaw_rules_security_python/rules/sec-py/no-xml-unsafe-parser.cases.md,sha256=rbrpJpePU2MeHrpNuPrILTb7QZGl-kkp6iGA2uVtHf0,900
110
+ codelaw_rules_security_python/rules/sec-py/no-xml-unsafe-parser.md,sha256=PjyZLMF0pECNa3iOzVJ10IloB_0RBpkth2DGNZtaeuM,2543
111
+ codelaw_rules_security_python/rules/sec-py/no-xmlrpc.cases.md,sha256=p_7ccr7j2H-Ru8-TzsGlr_NUuDuYwynRz2X8RuEIOIs,309
112
+ codelaw_rules_security_python/rules/sec-py/no-xmlrpc.md,sha256=0mOX-QWQxnl2iZVUmKbvkMeJ-iztMjvTrKfs7KQYk5E,1337
113
+ codelaw_rules_security_python/rules/sec-py/no-xpath-injection.cases.md,sha256=12ELsXAeZ0FRSBPs1WrmWQH3Nlo6wwFoHo2Ip6poaZ8,453
114
+ codelaw_rules_security_python/rules/sec-py/no-xpath-injection.md,sha256=dQpJF8r3TUO0dPzN94x06xxONNfDO3E2wRSNc8aZsBo,1481
115
+ codelaw_rules_security_python/rules/sec-py/paramiko-host-key.cases.md,sha256=_cW9njkzLeCqpZglP6roybNrXHtTTvEZXv6azC0iPQ0,284
116
+ codelaw_rules_security_python/rules/sec-py/paramiko-host-key.md,sha256=jOzj4P45qimJsuA1EHGTZRGY-hGFaRAik7dygjrK_xY,1172
117
+ codelaw_rules_security_python/rules/sec-py/password-hash-effort.cases.md,sha256=y4RK-stw00hyT-Co-ziofg2zbZfcqMj9QDIe-vacMag,748
118
+ codelaw_rules_security_python/rules/sec-py/password-hash-effort.md,sha256=47MZ3PL08EpGKokgagK-toMBBrJCN0RsHeqJDWMzUVI,2295
119
+ codelaw_rules_security_python/rules/sec-py/requests-timeout.cases.md,sha256=-bSMFejq0o_QFz4x5Ace3MefgHu7XLFJeY4w7VAyuAQ,412
120
+ codelaw_rules_security_python/rules/sec-py/requests-timeout.md,sha256=Hwg6jf8bVw29Dt184f0OyXZ4N_3P75w3SDTONWSN6iY,1423
121
+ codelaw_rules_security_python/rules/sec-py/tarfile-filter.cases.md,sha256=tJyDnb16lUXgaivjlfhL3a0P6xsXNKS-0BGGuOs04BE,523
122
+ codelaw_rules_security_python/rules/sec-py/tarfile-filter.md,sha256=dy8SWGL1IMzN2Hwb5AObxhKMadWyxOarZVp1kwPcqyw,1681
123
+ codelaw_rules_security_python/rules/sec-py/torch-load-weights-only.cases.md,sha256=yqHrGKPeg9S8xlJpYMCnZp0iGokQpG4MXtSgrx-RLBM,497
124
+ codelaw_rules_security_python/rules/sec-py/torch-load-weights-only.md,sha256=NzBSyS5SUYiyRgxncOfMOP9gzH0abrQVM4sywXmP4-k,1659
125
+ codelaw_rules_security_python/rules/sec-py/upload-secure-filename.cases.md,sha256=dMMaUR8rO_8_R3oH2XjkKAUj5wIsY07YViI6OSW0F4g,453
126
+ codelaw_rules_security_python/rules/sec-py/upload-secure-filename.md,sha256=lLvrDO4KKLHwJkYuVg45OeAxsozwhPoaEGDMcEcbBDw,1752
127
+ codelaw_rules_security_python/rules/sec-py/urlopen-scheme.cases.md,sha256=dGpfEzMhSc-q65SaoULm12UG0lj5fb2hy11I8_On14s,431
128
+ codelaw_rules_security_python/rules/sec-py/urlopen-scheme.md,sha256=327_LJI5r2qJFX11HRSzonu7qI-RH21lUlLY-bI3Z-Q,1419
129
+ codelaw_rules_security_python/rules/sec-py/weak-key-size.cases.md,sha256=A6QAQ9S8lnc_48K98Jlp1chWvGvX6HCVWmaG3U-WeRU,547
130
+ codelaw_rules_security_python/rules/sec-py/weak-key-size.md,sha256=LNcsMDOks_lqY904MrEWeab5EZ2SKDYIiH8FZS45G-g,2262
131
+ codelaw_rules_security_python/rules/sec-py/yaml-safe-load.cases.md,sha256=RA4YO0Ys9vOUu4_YiknDqMdiXCU68owoqzzP2j8y7TQ,678
132
+ codelaw_rules_security_python/rules/sec-py/yaml-safe-load.md,sha256=cfTLRHvcfxwhlbBJdKxDZ3LvQBlSgunfDMQd12HRuMI,1134
133
+ codelaw_rules_security_python-0.3.0.dist-info/METADATA,sha256=qMl5vS7p_3s_ZVaYIQhuzGILRLWuZrcpyttrBSwGn4I,21887
134
+ codelaw_rules_security_python-0.3.0.dist-info/WHEEL,sha256=iL940CG79gUG1gJG0fuOXtdNe75u1bVsFzkAeObStpM,97
135
+ codelaw_rules_security_python-0.3.0.dist-info/licenses/LICENSE,sha256=_R8NFLyGiKUo7mPzbUGbqg3hdEKYhaTsIgBGXqtFfa8,1097
136
+ codelaw_rules_security_python-0.3.0.dist-info/RECORD,,