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.
- codelaw_rules_security_python/LICENSE +23 -0
- codelaw_rules_security_python/NOTICE +19 -0
- codelaw_rules_security_python/README.md +239 -0
- codelaw_rules_security_python/codelaw-pack.toml +6 -0
- codelaw_rules_security_python/corpus.toml +65 -0
- codelaw_rules_security_python/data/sources/django.json +17 -0
- codelaw_rules_security_python/data/sources/fastapi.json +10 -0
- codelaw_rules_security_python/data/sources/flask.json +14 -0
- codelaw_rules_security_python/presets/sec-py/recommended.toml +60 -0
- codelaw_rules_security_python/presets/sec-py/strict.toml +8 -0
- codelaw_rules_security_python/rules/sec-py/cookie-flags.cases.md +61 -0
- codelaw_rules_security_python/rules/sec-py/cookie-flags.md +95 -0
- codelaw_rules_security_python/rules/sec-py/django-settings.cases.md +61 -0
- codelaw_rules_security_python/rules/sec-py/django-settings.md +68 -0
- codelaw_rules_security_python/rules/sec-py/fastapi-cors.cases.md +31 -0
- codelaw_rules_security_python/rules/sec-py/fastapi-cors.md +46 -0
- codelaw_rules_security_python/rules/sec-py/flask-debug.cases.md +31 -0
- codelaw_rules_security_python/rules/sec-py/flask-debug.md +59 -0
- codelaw_rules_security_python/rules/sec-py/flask-settings.cases.md +51 -0
- codelaw_rules_security_python/rules/sec-py/flask-settings.md +84 -0
- codelaw_rules_security_python/rules/sec-py/hf-pin-revision.cases.md +51 -0
- codelaw_rules_security_python/rules/sec-py/hf-pin-revision.md +58 -0
- codelaw_rules_security_python/rules/sec-py/jinja-autoescape.cases.md +62 -0
- codelaw_rules_security_python/rules/sec-py/jinja-autoescape.md +80 -0
- codelaw_rules_security_python/rules/sec-py/logging-listen.cases.md +31 -0
- codelaw_rules_security_python/rules/sec-py/logging-listen.md +47 -0
- codelaw_rules_security_python/rules/sec-py/ml-unsafe-load.cases.md +61 -0
- codelaw_rules_security_python/rules/sec-py/ml-unsafe-load.md +68 -0
- codelaw_rules_security_python/rules/sec-py/no-assert-for-auth.cases.md +31 -0
- codelaw_rules_security_python/rules/sec-py/no-assert-for-auth.md +51 -0
- codelaw_rules_security_python/rules/sec-py/no-bind-all-interfaces.cases.md +41 -0
- codelaw_rules_security_python/rules/sec-py/no-bind-all-interfaces.md +75 -0
- codelaw_rules_security_python/rules/sec-py/no-cleartext-http.cases.md +41 -0
- codelaw_rules_security_python/rules/sec-py/no-cleartext-http.md +56 -0
- codelaw_rules_security_python/rules/sec-py/no-csrf-exempt.cases.md +49 -0
- codelaw_rules_security_python/rules/sec-py/no-csrf-exempt.md +47 -0
- codelaw_rules_security_python/rules/sec-py/no-dynamic-import.cases.md +35 -0
- codelaw_rules_security_python/rules/sec-py/no-dynamic-import.md +51 -0
- codelaw_rules_security_python/rules/sec-py/no-exec-eval.cases.md +51 -0
- codelaw_rules_security_python/rules/sec-py/no-exec-eval.md +56 -0
- codelaw_rules_security_python/rules/sec-py/no-format-string-injection.cases.md +35 -0
- codelaw_rules_security_python/rules/sec-py/no-format-string-injection.md +44 -0
- codelaw_rules_security_python/rules/sec-py/no-hardcoded-crypto-key.cases.md +51 -0
- codelaw_rules_security_python/rules/sec-py/no-hardcoded-crypto-key.md +91 -0
- codelaw_rules_security_python/rules/sec-py/no-hardcoded-secret.cases.md +61 -0
- codelaw_rules_security_python/rules/sec-py/no-hardcoded-secret.md +82 -0
- codelaw_rules_security_python/rules/sec-py/no-header-injection.cases.md +45 -0
- codelaw_rules_security_python/rules/sec-py/no-header-injection.md +55 -0
- codelaw_rules_security_python/rules/sec-py/no-insecure-protocol.cases.md +41 -0
- codelaw_rules_security_python/rules/sec-py/no-insecure-protocol.md +52 -0
- codelaw_rules_security_python/rules/sec-py/no-insecure-random.cases.md +41 -0
- codelaw_rules_security_python/rules/sec-py/no-insecure-random.md +67 -0
- codelaw_rules_security_python/rules/sec-py/no-insecure-tempfile.cases.md +41 -0
- codelaw_rules_security_python/rules/sec-py/no-insecure-tempfile.md +62 -0
- codelaw_rules_security_python/rules/sec-py/no-ldap-injection.cases.md +41 -0
- codelaw_rules_security_python/rules/sec-py/no-ldap-injection.md +51 -0
- codelaw_rules_security_python/rules/sec-py/no-llm-output-to-sink.cases.md +31 -0
- codelaw_rules_security_python/rules/sec-py/no-llm-output-to-sink.md +55 -0
- codelaw_rules_security_python/rules/sec-py/no-log-injection.cases.md +45 -0
- codelaw_rules_security_python/rules/sec-py/no-log-injection.md +52 -0
- codelaw_rules_security_python/rules/sec-py/no-mako.cases.md +37 -0
- codelaw_rules_security_python/rules/sec-py/no-mako.md +52 -0
- codelaw_rules_security_python/rules/sec-py/no-mark-safe.cases.md +51 -0
- codelaw_rules_security_python/rules/sec-py/no-mark-safe.md +54 -0
- codelaw_rules_security_python/rules/sec-py/no-mass-assignment.cases.md +55 -0
- codelaw_rules_security_python/rules/sec-py/no-mass-assignment.md +58 -0
- codelaw_rules_security_python/rules/sec-py/no-nosql-injection.cases.md +34 -0
- codelaw_rules_security_python/rules/sec-py/no-nosql-injection.md +56 -0
- codelaw_rules_security_python/rules/sec-py/no-open-redirect.cases.md +35 -0
- codelaw_rules_security_python/rules/sec-py/no-open-redirect.md +51 -0
- codelaw_rules_security_python/rules/sec-py/no-partial-path.cases.md +41 -0
- codelaw_rules_security_python/rules/sec-py/no-partial-path.md +61 -0
- codelaw_rules_security_python/rules/sec-py/no-path-traversal.cases.md +46 -0
- codelaw_rules_security_python/rules/sec-py/no-path-traversal.md +54 -0
- codelaw_rules_security_python/rules/sec-py/no-prompt-injection.cases.md +46 -0
- codelaw_rules_security_python/rules/sec-py/no-prompt-injection.md +65 -0
- codelaw_rules_security_python/rules/sec-py/no-pycrypto.cases.md +41 -0
- codelaw_rules_security_python/rules/sec-py/no-pycrypto.md +47 -0
- codelaw_rules_security_python/rules/sec-py/no-reflected-xss.cases.md +45 -0
- codelaw_rules_security_python/rules/sec-py/no-reflected-xss.md +56 -0
- codelaw_rules_security_python/rules/sec-py/no-regex-injection.cases.md +33 -0
- codelaw_rules_security_python/rules/sec-py/no-regex-injection.md +49 -0
- codelaw_rules_security_python/rules/sec-py/no-secret-in-log.cases.md +41 -0
- codelaw_rules_security_python/rules/sec-py/no-secret-in-log.md +55 -0
- codelaw_rules_security_python/rules/sec-py/no-shell.cases.md +55 -0
- codelaw_rules_security_python/rules/sec-py/no-shell.md +63 -0
- codelaw_rules_security_python/rules/sec-py/no-silent-except.cases.md +53 -0
- codelaw_rules_security_python/rules/sec-py/no-silent-except.md +54 -0
- codelaw_rules_security_python/rules/sec-py/no-sql-string.cases.md +91 -0
- codelaw_rules_security_python/rules/sec-py/no-sql-string.md +78 -0
- codelaw_rules_security_python/rules/sec-py/no-ssrf.cases.md +34 -0
- codelaw_rules_security_python/rules/sec-py/no-ssrf.md +54 -0
- codelaw_rules_security_python/rules/sec-py/no-stack-trace-response.cases.md +48 -0
- codelaw_rules_security_python/rules/sec-py/no-stack-trace-response.md +67 -0
- codelaw_rules_security_python/rules/sec-py/no-tls-bypass.cases.md +71 -0
- codelaw_rules_security_python/rules/sec-py/no-tls-bypass.md +66 -0
- codelaw_rules_security_python/rules/sec-py/no-trust-remote-code.cases.md +31 -0
- codelaw_rules_security_python/rules/sec-py/no-trust-remote-code.md +50 -0
- codelaw_rules_security_python/rules/sec-py/no-unsafe-deserialize.cases.md +63 -0
- codelaw_rules_security_python/rules/sec-py/no-unsafe-deserialize.md +51 -0
- codelaw_rules_security_python/rules/sec-py/no-weak-cipher.cases.md +51 -0
- codelaw_rules_security_python/rules/sec-py/no-weak-cipher.md +60 -0
- codelaw_rules_security_python/rules/sec-py/no-weak-hash.cases.md +41 -0
- codelaw_rules_security_python/rules/sec-py/no-weak-hash.md +54 -0
- codelaw_rules_security_python/rules/sec-py/no-wildcard-injection.cases.md +41 -0
- codelaw_rules_security_python/rules/sec-py/no-wildcard-injection.md +53 -0
- codelaw_rules_security_python/rules/sec-py/no-world-writable.cases.md +51 -0
- codelaw_rules_security_python/rules/sec-py/no-world-writable.md +57 -0
- codelaw_rules_security_python/rules/sec-py/no-xml-unsafe-parser.cases.md +83 -0
- codelaw_rules_security_python/rules/sec-py/no-xml-unsafe-parser.md +86 -0
- codelaw_rules_security_python/rules/sec-py/no-xmlrpc.cases.md +31 -0
- codelaw_rules_security_python/rules/sec-py/no-xmlrpc.md +50 -0
- codelaw_rules_security_python/rules/sec-py/no-xpath-injection.cases.md +41 -0
- codelaw_rules_security_python/rules/sec-py/no-xpath-injection.md +52 -0
- codelaw_rules_security_python/rules/sec-py/paramiko-host-key.cases.md +21 -0
- codelaw_rules_security_python/rules/sec-py/paramiko-host-key.md +44 -0
- codelaw_rules_security_python/rules/sec-py/password-hash-effort.cases.md +61 -0
- codelaw_rules_security_python/rules/sec-py/password-hash-effort.md +74 -0
- codelaw_rules_security_python/rules/sec-py/requests-timeout.cases.md +41 -0
- codelaw_rules_security_python/rules/sec-py/requests-timeout.md +63 -0
- codelaw_rules_security_python/rules/sec-py/tarfile-filter.cases.md +51 -0
- codelaw_rules_security_python/rules/sec-py/tarfile-filter.md +71 -0
- codelaw_rules_security_python/rules/sec-py/torch-load-weights-only.cases.md +41 -0
- codelaw_rules_security_python/rules/sec-py/torch-load-weights-only.md +73 -0
- codelaw_rules_security_python/rules/sec-py/upload-secure-filename.cases.md +41 -0
- codelaw_rules_security_python/rules/sec-py/upload-secure-filename.md +65 -0
- codelaw_rules_security_python/rules/sec-py/urlopen-scheme.cases.md +41 -0
- codelaw_rules_security_python/rules/sec-py/urlopen-scheme.md +54 -0
- codelaw_rules_security_python/rules/sec-py/weak-key-size.cases.md +51 -0
- codelaw_rules_security_python/rules/sec-py/weak-key-size.md +82 -0
- codelaw_rules_security_python/rules/sec-py/yaml-safe-load.cases.md +67 -0
- codelaw_rules_security_python/rules/sec-py/yaml-safe-load.md +51 -0
- codelaw_rules_security_python-0.3.0.dist-info/METADATA +249 -0
- codelaw_rules_security_python-0.3.0.dist-info/RECORD +136 -0
- codelaw_rules_security_python-0.3.0.dist-info/WHEEL +4 -0
- 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,,
|