agent-security-scanner-mcp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +106 -0
- package/analyzer.py +119 -0
- package/index.js +269 -0
- package/package.json +48 -0
- package/rules/__init__.py +167 -0
- package/rules/dockerfile.security.yaml +291 -0
- package/rules/generic.secrets.yaml +503 -0
- package/rules/go.security.yaml +380 -0
- package/rules/java.security.yaml +453 -0
- package/rules/javascript.security.yaml +504 -0
- package/rules/python.security.yaml +602 -0
|
@@ -0,0 +1,602 @@
|
|
|
1
|
+
rules:
|
|
2
|
+
# ============================================================================
|
|
3
|
+
# INJECTION RULES
|
|
4
|
+
# ============================================================================
|
|
5
|
+
- id: python.lang.security.audit.sqli.sql-injection-db-cursor
|
|
6
|
+
languages: [python]
|
|
7
|
+
severity: ERROR
|
|
8
|
+
message: "Possible SQL injection via string concatenation. Use parameterized queries instead."
|
|
9
|
+
patterns:
|
|
10
|
+
- "cursor\\.execute\\s*\\(\\s*[\"'][^\"']*%"
|
|
11
|
+
- "cursor\\.execute\\s*\\(\\s*f[\"']"
|
|
12
|
+
- "cursor\\.execute\\s*\\(\\s*[^,)]+\\s*\\+\\s*"
|
|
13
|
+
- "cursor\\.execute\\s*\\(\\s*[\"'].*\\.format\\s*\\("
|
|
14
|
+
metadata:
|
|
15
|
+
cwe: "CWE-89"
|
|
16
|
+
owasp: "A03:2021 - Injection"
|
|
17
|
+
confidence: HIGH
|
|
18
|
+
references:
|
|
19
|
+
- https://semgrep.dev/r/python.lang.security.audit.sqli.sql-injection-db-cursor
|
|
20
|
+
- https://owasp.org/Top10/A03_2021-Injection/
|
|
21
|
+
|
|
22
|
+
- id: python.lang.security.audit.sqli.sql-injection-using-sqlalchemy
|
|
23
|
+
languages: [python]
|
|
24
|
+
severity: ERROR
|
|
25
|
+
message: "Possible SQL injection in SQLAlchemy raw query. Use parameterized queries."
|
|
26
|
+
patterns:
|
|
27
|
+
- "text\\s*\\(\\s*f[\"']"
|
|
28
|
+
- "text\\s*\\(\\s*[^)]+\\+"
|
|
29
|
+
- "\\.execute\\s*\\(\\s*f[\"']SELECT"
|
|
30
|
+
- "\\.execute\\s*\\(\\s*f[\"']INSERT"
|
|
31
|
+
- "\\.execute\\s*\\(\\s*f[\"']UPDATE"
|
|
32
|
+
- "\\.execute\\s*\\(\\s*f[\"']DELETE"
|
|
33
|
+
metadata:
|
|
34
|
+
cwe: "CWE-89"
|
|
35
|
+
owasp: "A03:2021 - Injection"
|
|
36
|
+
confidence: HIGH
|
|
37
|
+
references:
|
|
38
|
+
- https://semgrep.dev/r/python.sqlalchemy.security.sqlalchemy-execute-raw-query
|
|
39
|
+
|
|
40
|
+
- id: python.lang.security.audit.sqli.sql-injection-using-django
|
|
41
|
+
languages: [python]
|
|
42
|
+
severity: ERROR
|
|
43
|
+
message: "Possible SQL injection in Django raw query. Use parameterized queries."
|
|
44
|
+
patterns:
|
|
45
|
+
- "\\.raw\\s*\\(\\s*f[\"']"
|
|
46
|
+
- "\\.raw\\s*\\(\\s*[^)]+\\+"
|
|
47
|
+
- "\\.extra\\s*\\(.*where.*\\+.*\\)"
|
|
48
|
+
- "RawSQL\\s*\\(\\s*f[\"']"
|
|
49
|
+
metadata:
|
|
50
|
+
cwe: "CWE-89"
|
|
51
|
+
owasp: "A03:2021 - Injection"
|
|
52
|
+
confidence: HIGH
|
|
53
|
+
references:
|
|
54
|
+
- https://semgrep.dev/r/python.django.security.injection.sql.sql-injection-using-raw
|
|
55
|
+
|
|
56
|
+
# ============================================================================
|
|
57
|
+
# COMMAND INJECTION RULES
|
|
58
|
+
# ============================================================================
|
|
59
|
+
- id: python.lang.security.audit.dangerous-subprocess-use
|
|
60
|
+
languages: [python]
|
|
61
|
+
severity: ERROR
|
|
62
|
+
message: "Detected subprocess with shell=True. This is dangerous when using user input. Use shell=False and pass arguments as a list."
|
|
63
|
+
patterns:
|
|
64
|
+
- "subprocess\\.call\\s*\\([^)]*shell\\s*=\\s*True"
|
|
65
|
+
- "subprocess\\.run\\s*\\([^)]*shell\\s*=\\s*True"
|
|
66
|
+
- "subprocess\\.Popen\\s*\\([^)]*shell\\s*=\\s*True"
|
|
67
|
+
- "subprocess\\.check_output\\s*\\([^)]*shell\\s*=\\s*True"
|
|
68
|
+
- "subprocess\\.check_call\\s*\\([^)]*shell\\s*=\\s*True"
|
|
69
|
+
metadata:
|
|
70
|
+
cwe: "CWE-78"
|
|
71
|
+
owasp: "A03:2021 - Injection"
|
|
72
|
+
confidence: HIGH
|
|
73
|
+
references:
|
|
74
|
+
- https://semgrep.dev/r/python.lang.security.audit.dangerous-subprocess-use
|
|
75
|
+
|
|
76
|
+
- id: python.lang.security.audit.dangerous-system-call
|
|
77
|
+
languages: [python]
|
|
78
|
+
severity: ERROR
|
|
79
|
+
message: "Detected os.system() call. This can lead to command injection. Use subprocess with shell=False instead."
|
|
80
|
+
patterns:
|
|
81
|
+
- "os\\.system\\s*\\("
|
|
82
|
+
- "os\\.popen\\s*\\("
|
|
83
|
+
- "os\\.spawn[lv]?[pe]?\\s*\\("
|
|
84
|
+
metadata:
|
|
85
|
+
cwe: "CWE-78"
|
|
86
|
+
owasp: "A03:2021 - Injection"
|
|
87
|
+
confidence: HIGH
|
|
88
|
+
references:
|
|
89
|
+
- https://semgrep.dev/r/python.lang.security.audit.dangerous-system-call
|
|
90
|
+
|
|
91
|
+
# ============================================================================
|
|
92
|
+
# CODE INJECTION / DANGEROUS EVAL
|
|
93
|
+
# ============================================================================
|
|
94
|
+
- id: python.lang.security.audit.eval-detected
|
|
95
|
+
languages: [python]
|
|
96
|
+
severity: ERROR
|
|
97
|
+
message: "Detected use of eval(). This is dangerous and can lead to code injection. Avoid eval() with untrusted input."
|
|
98
|
+
patterns:
|
|
99
|
+
- "\\beval\\s*\\("
|
|
100
|
+
metadata:
|
|
101
|
+
cwe: "CWE-95"
|
|
102
|
+
owasp: "A03:2021 - Injection"
|
|
103
|
+
confidence: HIGH
|
|
104
|
+
references:
|
|
105
|
+
- https://semgrep.dev/r/python.lang.security.audit.eval-detected
|
|
106
|
+
|
|
107
|
+
- id: python.lang.security.audit.exec-detected
|
|
108
|
+
languages: [python]
|
|
109
|
+
severity: ERROR
|
|
110
|
+
message: "Detected use of exec(). This is dangerous and can lead to code injection. Avoid exec() with untrusted input."
|
|
111
|
+
patterns:
|
|
112
|
+
- "\\bexec\\s*\\("
|
|
113
|
+
metadata:
|
|
114
|
+
cwe: "CWE-95"
|
|
115
|
+
owasp: "A03:2021 - Injection"
|
|
116
|
+
confidence: HIGH
|
|
117
|
+
references:
|
|
118
|
+
- https://semgrep.dev/r/python.lang.security.audit.exec-detected
|
|
119
|
+
|
|
120
|
+
- id: python.lang.security.audit.compile-detected
|
|
121
|
+
languages: [python]
|
|
122
|
+
severity: WARNING
|
|
123
|
+
message: "Detected use of compile(). Ensure input is not from untrusted sources."
|
|
124
|
+
patterns:
|
|
125
|
+
- "\\bcompile\\s*\\([^)]*,[^)]*['\"]exec['\"]"
|
|
126
|
+
metadata:
|
|
127
|
+
cwe: "CWE-95"
|
|
128
|
+
owasp: "A03:2021 - Injection"
|
|
129
|
+
confidence: MEDIUM
|
|
130
|
+
references:
|
|
131
|
+
- https://semgrep.dev/r/python.lang.security.audit.compile-detected
|
|
132
|
+
|
|
133
|
+
# ============================================================================
|
|
134
|
+
# DESERIALIZATION RULES
|
|
135
|
+
# ============================================================================
|
|
136
|
+
- id: python.lang.security.deserialization.pickle-load
|
|
137
|
+
languages: [python]
|
|
138
|
+
severity: ERROR
|
|
139
|
+
message: "Detected pickle deserialization. Pickle is unsafe - arbitrary code execution is possible. Use JSON or other safe formats."
|
|
140
|
+
patterns:
|
|
141
|
+
- "pickle\\.load\\s*\\("
|
|
142
|
+
- "pickle\\.loads\\s*\\("
|
|
143
|
+
- "cPickle\\.load\\s*\\("
|
|
144
|
+
- "cPickle\\.loads\\s*\\("
|
|
145
|
+
- "_pickle\\.load\\s*\\("
|
|
146
|
+
- "_pickle\\.loads\\s*\\("
|
|
147
|
+
metadata:
|
|
148
|
+
cwe: "CWE-502"
|
|
149
|
+
owasp: "A08:2021 - Software and Data Integrity Failures"
|
|
150
|
+
confidence: HIGH
|
|
151
|
+
references:
|
|
152
|
+
- https://semgrep.dev/r/python.lang.security.deserialization.avoid-pickle
|
|
153
|
+
|
|
154
|
+
- id: python.lang.security.deserialization.yaml-load
|
|
155
|
+
languages: [python]
|
|
156
|
+
severity: ERROR
|
|
157
|
+
message: "Detected yaml.load() without safe Loader. Use yaml.safe_load() or yaml.load(data, Loader=yaml.SafeLoader)."
|
|
158
|
+
patterns:
|
|
159
|
+
- "yaml\\.load\\s*\\([^)]*\\)(?!.*Loader)"
|
|
160
|
+
- "yaml\\.load\\s*\\([^)]*,\\s*Loader\\s*=\\s*yaml\\.Loader"
|
|
161
|
+
- "yaml\\.load\\s*\\([^)]*,\\s*Loader\\s*=\\s*yaml\\.UnsafeLoader"
|
|
162
|
+
- "yaml\\.load\\s*\\([^)]*,\\s*Loader\\s*=\\s*yaml\\.FullLoader"
|
|
163
|
+
- "yaml\\.unsafe_load\\s*\\("
|
|
164
|
+
metadata:
|
|
165
|
+
cwe: "CWE-502"
|
|
166
|
+
owasp: "A08:2021 - Software and Data Integrity Failures"
|
|
167
|
+
confidence: HIGH
|
|
168
|
+
references:
|
|
169
|
+
- https://semgrep.dev/r/python.lang.security.deserialization.avoid-unsafe-yaml
|
|
170
|
+
|
|
171
|
+
- id: python.lang.security.deserialization.marshal-load
|
|
172
|
+
languages: [python]
|
|
173
|
+
severity: ERROR
|
|
174
|
+
message: "Detected marshal deserialization. Marshal is not secure against malicious data."
|
|
175
|
+
patterns:
|
|
176
|
+
- "marshal\\.load\\s*\\("
|
|
177
|
+
- "marshal\\.loads\\s*\\("
|
|
178
|
+
metadata:
|
|
179
|
+
cwe: "CWE-502"
|
|
180
|
+
owasp: "A08:2021 - Software and Data Integrity Failures"
|
|
181
|
+
confidence: HIGH
|
|
182
|
+
references:
|
|
183
|
+
- https://semgrep.dev/r/python.lang.security.deserialization.avoid-marshal
|
|
184
|
+
|
|
185
|
+
- id: python.lang.security.deserialization.shelve-open
|
|
186
|
+
languages: [python]
|
|
187
|
+
severity: WARNING
|
|
188
|
+
message: "Detected shelve.open(). Shelve uses pickle internally and is vulnerable to code execution."
|
|
189
|
+
patterns:
|
|
190
|
+
- "shelve\\.open\\s*\\("
|
|
191
|
+
metadata:
|
|
192
|
+
cwe: "CWE-502"
|
|
193
|
+
owasp: "A08:2021 - Software and Data Integrity Failures"
|
|
194
|
+
confidence: MEDIUM
|
|
195
|
+
references:
|
|
196
|
+
- https://semgrep.dev/r/python.lang.security.deserialization.avoid-shelve
|
|
197
|
+
|
|
198
|
+
# ============================================================================
|
|
199
|
+
# CRYPTOGRAPHY RULES
|
|
200
|
+
# ============================================================================
|
|
201
|
+
- id: python.lang.security.crypto.insecure-hash-md5
|
|
202
|
+
languages: [python]
|
|
203
|
+
severity: WARNING
|
|
204
|
+
message: "Detected MD5 hash. MD5 is cryptographically weak. Use SHA-256 or stronger for security purposes."
|
|
205
|
+
patterns:
|
|
206
|
+
- "hashlib\\.md5\\s*\\("
|
|
207
|
+
- "MD5\\.new\\s*\\("
|
|
208
|
+
- "Crypto\\.Hash\\.MD5"
|
|
209
|
+
metadata:
|
|
210
|
+
cwe: "CWE-328"
|
|
211
|
+
owasp: "A02:2021 - Cryptographic Failures"
|
|
212
|
+
confidence: HIGH
|
|
213
|
+
references:
|
|
214
|
+
- https://semgrep.dev/r/python.lang.security.insecure-hash-function-md5
|
|
215
|
+
|
|
216
|
+
- id: python.lang.security.crypto.insecure-hash-sha1
|
|
217
|
+
languages: [python]
|
|
218
|
+
severity: WARNING
|
|
219
|
+
message: "Detected SHA1 hash. SHA1 is cryptographically weak. Use SHA-256 or stronger for security purposes."
|
|
220
|
+
patterns:
|
|
221
|
+
- "hashlib\\.sha1\\s*\\("
|
|
222
|
+
- "SHA1\\.new\\s*\\("
|
|
223
|
+
- "Crypto\\.Hash\\.SHA1"
|
|
224
|
+
- "SHA\\.new\\s*\\("
|
|
225
|
+
metadata:
|
|
226
|
+
cwe: "CWE-328"
|
|
227
|
+
owasp: "A02:2021 - Cryptographic Failures"
|
|
228
|
+
confidence: HIGH
|
|
229
|
+
references:
|
|
230
|
+
- https://semgrep.dev/r/python.lang.security.insecure-hash-function-sha1
|
|
231
|
+
|
|
232
|
+
- id: python.lang.security.crypto.insecure-cipher-des
|
|
233
|
+
languages: [python]
|
|
234
|
+
severity: ERROR
|
|
235
|
+
message: "Detected DES cipher. DES is insecure due to small key size. Use AES instead."
|
|
236
|
+
patterns:
|
|
237
|
+
- "DES\\.new\\s*\\("
|
|
238
|
+
- "DES3\\.new\\s*\\("
|
|
239
|
+
- "Crypto\\.Cipher\\.DES"
|
|
240
|
+
- "Blowfish\\.new\\s*\\("
|
|
241
|
+
- "RC2\\.new\\s*\\("
|
|
242
|
+
- "RC4\\.new\\s*\\("
|
|
243
|
+
- "ARC2\\.new\\s*\\("
|
|
244
|
+
- "ARC4\\.new\\s*\\("
|
|
245
|
+
metadata:
|
|
246
|
+
cwe: "CWE-327"
|
|
247
|
+
owasp: "A02:2021 - Cryptographic Failures"
|
|
248
|
+
confidence: HIGH
|
|
249
|
+
references:
|
|
250
|
+
- https://semgrep.dev/r/python.lang.security.insecure-cipher-algorithm-des
|
|
251
|
+
|
|
252
|
+
- id: python.lang.security.crypto.insecure-random
|
|
253
|
+
languages: [python]
|
|
254
|
+
severity: WARNING
|
|
255
|
+
message: "Detected use of random module for security purposes. Use secrets module instead."
|
|
256
|
+
patterns:
|
|
257
|
+
- "random\\.random\\s*\\("
|
|
258
|
+
- "random\\.randint\\s*\\("
|
|
259
|
+
- "random\\.choice\\s*\\("
|
|
260
|
+
- "random\\.randrange\\s*\\("
|
|
261
|
+
- "random\\.sample\\s*\\("
|
|
262
|
+
- "random\\.shuffle\\s*\\("
|
|
263
|
+
metadata:
|
|
264
|
+
cwe: "CWE-330"
|
|
265
|
+
owasp: "A02:2021 - Cryptographic Failures"
|
|
266
|
+
confidence: MEDIUM
|
|
267
|
+
references:
|
|
268
|
+
- https://semgrep.dev/r/python.lang.security.insecure-random-generator
|
|
269
|
+
|
|
270
|
+
- id: python.lang.security.crypto.weak-rsa-key
|
|
271
|
+
languages: [python]
|
|
272
|
+
severity: ERROR
|
|
273
|
+
message: "RSA key size may be too small. Use at least 2048 bits for RSA keys."
|
|
274
|
+
patterns:
|
|
275
|
+
- "RSA\\.generate\\s*\\(\\s*(512|768|1024)\\s*\\)"
|
|
276
|
+
- "rsa\\.generate_private_key\\s*\\([^)]*key_size\\s*=\\s*(512|768|1024)"
|
|
277
|
+
metadata:
|
|
278
|
+
cwe: "CWE-326"
|
|
279
|
+
owasp: "A02:2021 - Cryptographic Failures"
|
|
280
|
+
confidence: HIGH
|
|
281
|
+
references:
|
|
282
|
+
- https://semgrep.dev/r/python.lang.security.audit.weak-rsa-key-size
|
|
283
|
+
|
|
284
|
+
# ============================================================================
|
|
285
|
+
# PATH TRAVERSAL RULES
|
|
286
|
+
# ============================================================================
|
|
287
|
+
- id: python.lang.security.audit.path-traversal-open
|
|
288
|
+
languages: [python]
|
|
289
|
+
severity: WARNING
|
|
290
|
+
message: "Possible path traversal vulnerability. Validate and sanitize file paths."
|
|
291
|
+
patterns:
|
|
292
|
+
- "open\\s*\\([^)]*\\+[^)]*\\)"
|
|
293
|
+
- "open\\s*\\(\\s*f[\"'][^\"']*\\{"
|
|
294
|
+
- "open\\s*\\([^)]*\\.format\\s*\\("
|
|
295
|
+
- "open\\s*\\([^)]*%[^)]*\\)"
|
|
296
|
+
metadata:
|
|
297
|
+
cwe: "CWE-22"
|
|
298
|
+
owasp: "A01:2021 - Broken Access Control"
|
|
299
|
+
confidence: MEDIUM
|
|
300
|
+
references:
|
|
301
|
+
- https://semgrep.dev/r/python.lang.security.audit.path-traversal-open
|
|
302
|
+
|
|
303
|
+
- id: python.lang.security.audit.path-traversal-pathlib
|
|
304
|
+
languages: [python]
|
|
305
|
+
severity: WARNING
|
|
306
|
+
message: "Possible path traversal with pathlib. Validate user input."
|
|
307
|
+
patterns:
|
|
308
|
+
- "Path\\s*\\([^)]*\\+[^)]*\\)"
|
|
309
|
+
- "Path\\s*\\(\\s*f[\"']"
|
|
310
|
+
metadata:
|
|
311
|
+
cwe: "CWE-22"
|
|
312
|
+
owasp: "A01:2021 - Broken Access Control"
|
|
313
|
+
confidence: MEDIUM
|
|
314
|
+
references:
|
|
315
|
+
- https://semgrep.dev/r/python.lang.security.audit.path-traversal-pathlib
|
|
316
|
+
|
|
317
|
+
# ============================================================================
|
|
318
|
+
# SSRF RULES
|
|
319
|
+
# ============================================================================
|
|
320
|
+
- id: python.lang.security.audit.ssrf-requests
|
|
321
|
+
languages: [python]
|
|
322
|
+
severity: WARNING
|
|
323
|
+
message: "Possible SSRF vulnerability. Validate and whitelist URLs before making requests."
|
|
324
|
+
patterns:
|
|
325
|
+
- "requests\\.get\\s*\\([^)]*\\+[^)]*\\)"
|
|
326
|
+
- "requests\\.get\\s*\\(\\s*f[\"']"
|
|
327
|
+
- "requests\\.post\\s*\\([^)]*\\+[^)]*\\)"
|
|
328
|
+
- "requests\\.post\\s*\\(\\s*f[\"']"
|
|
329
|
+
- "requests\\.put\\s*\\([^)]*\\+[^)]*\\)"
|
|
330
|
+
- "requests\\.delete\\s*\\([^)]*\\+[^)]*\\)"
|
|
331
|
+
- "requests\\.head\\s*\\([^)]*\\+[^)]*\\)"
|
|
332
|
+
- "requests\\.request\\s*\\([^)]*\\+[^)]*\\)"
|
|
333
|
+
metadata:
|
|
334
|
+
cwe: "CWE-918"
|
|
335
|
+
owasp: "A10:2021 - Server-Side Request Forgery"
|
|
336
|
+
confidence: MEDIUM
|
|
337
|
+
references:
|
|
338
|
+
- https://semgrep.dev/r/python.lang.security.audit.ssrf.ssrf-requests
|
|
339
|
+
|
|
340
|
+
- id: python.lang.security.audit.ssrf-urllib
|
|
341
|
+
languages: [python]
|
|
342
|
+
severity: WARNING
|
|
343
|
+
message: "Possible SSRF vulnerability with urllib. Validate and whitelist URLs."
|
|
344
|
+
patterns:
|
|
345
|
+
- "urllib\\.request\\.urlopen\\s*\\([^)]*\\+[^)]*\\)"
|
|
346
|
+
- "urllib\\.request\\.urlopen\\s*\\(\\s*f[\"']"
|
|
347
|
+
- "urlopen\\s*\\([^)]*\\+[^)]*\\)"
|
|
348
|
+
- "urllib2\\.urlopen\\s*\\("
|
|
349
|
+
metadata:
|
|
350
|
+
cwe: "CWE-918"
|
|
351
|
+
owasp: "A10:2021 - Server-Side Request Forgery"
|
|
352
|
+
confidence: MEDIUM
|
|
353
|
+
references:
|
|
354
|
+
- https://semgrep.dev/r/python.lang.security.audit.ssrf.ssrf-urllib
|
|
355
|
+
|
|
356
|
+
# ============================================================================
|
|
357
|
+
# XML / XXE RULES
|
|
358
|
+
# ============================================================================
|
|
359
|
+
- id: python.lang.security.xxe.xml-etree
|
|
360
|
+
languages: [python]
|
|
361
|
+
severity: WARNING
|
|
362
|
+
message: "xml.etree is vulnerable to XXE attacks. Use defusedxml instead."
|
|
363
|
+
patterns:
|
|
364
|
+
- "xml\\.etree\\.ElementTree\\.parse\\s*\\("
|
|
365
|
+
- "ET\\.parse\\s*\\("
|
|
366
|
+
- "ElementTree\\.parse\\s*\\("
|
|
367
|
+
- "xml\\.etree\\.ElementTree\\.fromstring\\s*\\("
|
|
368
|
+
- "ET\\.fromstring\\s*\\("
|
|
369
|
+
metadata:
|
|
370
|
+
cwe: "CWE-611"
|
|
371
|
+
owasp: "A05:2021 - Security Misconfiguration"
|
|
372
|
+
confidence: MEDIUM
|
|
373
|
+
references:
|
|
374
|
+
- https://semgrep.dev/r/python.lang.security.xxe.xml-etree-parse
|
|
375
|
+
|
|
376
|
+
- id: python.lang.security.xxe.lxml
|
|
377
|
+
languages: [python]
|
|
378
|
+
severity: ERROR
|
|
379
|
+
message: "lxml parsing with resolve_entities=True is vulnerable to XXE. Use resolve_entities=False."
|
|
380
|
+
patterns:
|
|
381
|
+
- "lxml\\.etree\\.parse\\s*\\("
|
|
382
|
+
- "etree\\.parse\\s*\\([^)]*resolve_entities\\s*=\\s*True"
|
|
383
|
+
- "XMLParser\\s*\\([^)]*resolve_entities\\s*=\\s*True"
|
|
384
|
+
metadata:
|
|
385
|
+
cwe: "CWE-611"
|
|
386
|
+
owasp: "A05:2021 - Security Misconfiguration"
|
|
387
|
+
confidence: MEDIUM
|
|
388
|
+
references:
|
|
389
|
+
- https://semgrep.dev/r/python.lang.security.xxe.lxml-xxe
|
|
390
|
+
|
|
391
|
+
# ============================================================================
|
|
392
|
+
# AUTHENTICATION / JWT RULES
|
|
393
|
+
# ============================================================================
|
|
394
|
+
- id: python.lang.security.jwt.jwt-decode-without-verify
|
|
395
|
+
languages: [python]
|
|
396
|
+
severity: ERROR
|
|
397
|
+
message: "JWT decoded without signature verification. Set verify=True or use algorithms parameter."
|
|
398
|
+
patterns:
|
|
399
|
+
- "jwt\\.decode\\s*\\([^)]*verify\\s*=\\s*False"
|
|
400
|
+
- "jwt\\.decode\\s*\\([^)]*options\\s*=\\s*\\{[^}]*[\"']verify_signature[\"']\\s*:\\s*False"
|
|
401
|
+
metadata:
|
|
402
|
+
cwe: "CWE-347"
|
|
403
|
+
owasp: "A07:2021 - Identification and Authentication Failures"
|
|
404
|
+
confidence: HIGH
|
|
405
|
+
references:
|
|
406
|
+
- https://semgrep.dev/r/python.jwt.security.jwt-decode-without-verification
|
|
407
|
+
|
|
408
|
+
- id: python.lang.security.jwt.jwt-hardcoded-secret
|
|
409
|
+
languages: [python]
|
|
410
|
+
severity: ERROR
|
|
411
|
+
message: "Hardcoded JWT secret detected. Use environment variables for secrets."
|
|
412
|
+
patterns:
|
|
413
|
+
- "jwt\\.encode\\s*\\([^)]*,\\s*[\"'][^\"']{8,}[\"']\\s*,"
|
|
414
|
+
- "jwt\\.decode\\s*\\([^)]*,\\s*[\"'][^\"']{8,}[\"']\\s*,"
|
|
415
|
+
metadata:
|
|
416
|
+
cwe: "CWE-798"
|
|
417
|
+
owasp: "A07:2021 - Identification and Authentication Failures"
|
|
418
|
+
confidence: HIGH
|
|
419
|
+
references:
|
|
420
|
+
- https://semgrep.dev/r/python.jwt.security.jwt-hardcoded-secret
|
|
421
|
+
|
|
422
|
+
# ============================================================================
|
|
423
|
+
# SSL/TLS RULES
|
|
424
|
+
# ============================================================================
|
|
425
|
+
- id: python.lang.security.ssl.ssl-verify-disabled
|
|
426
|
+
languages: [python]
|
|
427
|
+
severity: ERROR
|
|
428
|
+
message: "SSL certificate verification is disabled. This allows MITM attacks."
|
|
429
|
+
patterns:
|
|
430
|
+
- "verify\\s*=\\s*False"
|
|
431
|
+
- "ssl\\._create_unverified_context"
|
|
432
|
+
- "CERT_NONE"
|
|
433
|
+
- "check_hostname\\s*=\\s*False"
|
|
434
|
+
metadata:
|
|
435
|
+
cwe: "CWE-295"
|
|
436
|
+
owasp: "A07:2021 - Identification and Authentication Failures"
|
|
437
|
+
confidence: HIGH
|
|
438
|
+
references:
|
|
439
|
+
- https://semgrep.dev/r/python.lang.security.audit.ssl-verify-disabled
|
|
440
|
+
|
|
441
|
+
# ============================================================================
|
|
442
|
+
# TEMPLATE INJECTION RULES
|
|
443
|
+
# ============================================================================
|
|
444
|
+
- id: python.lang.security.audit.jinja2-autoescape-disabled
|
|
445
|
+
languages: [python]
|
|
446
|
+
severity: ERROR
|
|
447
|
+
message: "Jinja2 autoescape is disabled. This can lead to XSS vulnerabilities."
|
|
448
|
+
patterns:
|
|
449
|
+
- "Environment\\s*\\([^)]*autoescape\\s*=\\s*False"
|
|
450
|
+
- "Template\\s*\\([^)]*autoescape\\s*=\\s*False"
|
|
451
|
+
- "jinja2\\.Environment\\s*\\([^)]*autoescape\\s*=\\s*False"
|
|
452
|
+
metadata:
|
|
453
|
+
cwe: "CWE-79"
|
|
454
|
+
owasp: "A03:2021 - Injection"
|
|
455
|
+
confidence: HIGH
|
|
456
|
+
references:
|
|
457
|
+
- https://semgrep.dev/r/python.lang.security.audit.jinja2-autoescape-disabled
|
|
458
|
+
|
|
459
|
+
# ============================================================================
|
|
460
|
+
# DJANGO SPECIFIC RULES
|
|
461
|
+
# ============================================================================
|
|
462
|
+
- id: python.django.security.csrf-exempt
|
|
463
|
+
languages: [python]
|
|
464
|
+
severity: WARNING
|
|
465
|
+
message: "CSRF protection is disabled with @csrf_exempt. Ensure this is intentional."
|
|
466
|
+
patterns:
|
|
467
|
+
- "@csrf_exempt"
|
|
468
|
+
metadata:
|
|
469
|
+
cwe: "CWE-352"
|
|
470
|
+
owasp: "A01:2021 - Broken Access Control"
|
|
471
|
+
confidence: HIGH
|
|
472
|
+
references:
|
|
473
|
+
- https://semgrep.dev/r/python.django.security.audit.csrf-exempt
|
|
474
|
+
|
|
475
|
+
- id: python.django.security.debug-enabled
|
|
476
|
+
languages: [python]
|
|
477
|
+
severity: ERROR
|
|
478
|
+
message: "Django DEBUG mode is enabled. Disable in production."
|
|
479
|
+
patterns:
|
|
480
|
+
- "DEBUG\\s*=\\s*True"
|
|
481
|
+
metadata:
|
|
482
|
+
cwe: "CWE-489"
|
|
483
|
+
owasp: "A05:2021 - Security Misconfiguration"
|
|
484
|
+
confidence: HIGH
|
|
485
|
+
references:
|
|
486
|
+
- https://semgrep.dev/r/python.django.security.audit.debug-enabled
|
|
487
|
+
|
|
488
|
+
- id: python.django.security.secret-key-hardcoded
|
|
489
|
+
languages: [python]
|
|
490
|
+
severity: ERROR
|
|
491
|
+
message: "Django SECRET_KEY is hardcoded. Use environment variables."
|
|
492
|
+
patterns:
|
|
493
|
+
- "SECRET_KEY\\s*=\\s*[\"'][^\"']{20,}[\"']"
|
|
494
|
+
metadata:
|
|
495
|
+
cwe: "CWE-798"
|
|
496
|
+
owasp: "A07:2021 - Identification and Authentication Failures"
|
|
497
|
+
confidence: HIGH
|
|
498
|
+
references:
|
|
499
|
+
- https://semgrep.dev/r/python.django.security.audit.hardcoded-secret-key
|
|
500
|
+
|
|
501
|
+
# ============================================================================
|
|
502
|
+
# FLASK SPECIFIC RULES
|
|
503
|
+
# ============================================================================
|
|
504
|
+
- id: python.flask.security.debug-enabled
|
|
505
|
+
languages: [python]
|
|
506
|
+
severity: ERROR
|
|
507
|
+
message: "Flask debug mode is enabled. Disable in production."
|
|
508
|
+
patterns:
|
|
509
|
+
- "app\\.run\\s*\\([^)]*debug\\s*=\\s*True"
|
|
510
|
+
- "Flask\\s*\\([^)]*\\)\\.run\\s*\\([^)]*debug\\s*=\\s*True"
|
|
511
|
+
metadata:
|
|
512
|
+
cwe: "CWE-489"
|
|
513
|
+
owasp: "A05:2021 - Security Misconfiguration"
|
|
514
|
+
confidence: HIGH
|
|
515
|
+
references:
|
|
516
|
+
- https://semgrep.dev/r/python.flask.security.audit.debug-enabled
|
|
517
|
+
|
|
518
|
+
- id: python.flask.security.secret-key-hardcoded
|
|
519
|
+
languages: [python]
|
|
520
|
+
severity: ERROR
|
|
521
|
+
message: "Flask secret key is hardcoded. Use environment variables."
|
|
522
|
+
patterns:
|
|
523
|
+
- "app\\.secret_key\\s*=\\s*[\"'][^\"']{8,}[\"']"
|
|
524
|
+
- "SECRET_KEY\\s*=\\s*[\"'][^\"']{8,}[\"']"
|
|
525
|
+
metadata:
|
|
526
|
+
cwe: "CWE-798"
|
|
527
|
+
owasp: "A07:2021 - Identification and Authentication Failures"
|
|
528
|
+
confidence: HIGH
|
|
529
|
+
references:
|
|
530
|
+
- https://semgrep.dev/r/python.flask.security.audit.hardcoded-secret-key
|
|
531
|
+
|
|
532
|
+
# ============================================================================
|
|
533
|
+
# LOGGING RULES
|
|
534
|
+
# ============================================================================
|
|
535
|
+
- id: python.lang.security.audit.logging-sensitive-data
|
|
536
|
+
languages: [python]
|
|
537
|
+
severity: WARNING
|
|
538
|
+
message: "Possible sensitive data in log statement. Avoid logging passwords, tokens, or secrets."
|
|
539
|
+
patterns:
|
|
540
|
+
- "logging\\.(info|debug|warning|error|critical)\\s*\\([^)]*password"
|
|
541
|
+
- "logging\\.(info|debug|warning|error|critical)\\s*\\([^)]*secret"
|
|
542
|
+
- "logging\\.(info|debug|warning|error|critical)\\s*\\([^)]*token"
|
|
543
|
+
- "logging\\.(info|debug|warning|error|critical)\\s*\\([^)]*api_key"
|
|
544
|
+
- "logger\\.(info|debug|warning|error|critical)\\s*\\([^)]*password"
|
|
545
|
+
- "print\\s*\\([^)]*password"
|
|
546
|
+
metadata:
|
|
547
|
+
cwe: "CWE-532"
|
|
548
|
+
owasp: "A09:2021 - Security Logging and Monitoring Failures"
|
|
549
|
+
confidence: MEDIUM
|
|
550
|
+
references:
|
|
551
|
+
- https://semgrep.dev/r/python.lang.security.audit.logging-sensitive-data
|
|
552
|
+
|
|
553
|
+
# ============================================================================
|
|
554
|
+
# REGEX DENIAL OF SERVICE
|
|
555
|
+
# ============================================================================
|
|
556
|
+
- id: python.lang.security.audit.regex-dos
|
|
557
|
+
languages: [python]
|
|
558
|
+
severity: WARNING
|
|
559
|
+
message: "Potentially vulnerable regex pattern (ReDoS). Review for catastrophic backtracking."
|
|
560
|
+
patterns:
|
|
561
|
+
- "re\\.compile\\s*\\([^)]*\\([^)]*\\+\\)[^)]*\\+"
|
|
562
|
+
- "re\\.match\\s*\\([^)]*\\([^)]*\\*\\)[^)]*\\*"
|
|
563
|
+
- "re\\.search\\s*\\([^)]*\\([^)]*\\+\\)[^)]*\\+"
|
|
564
|
+
metadata:
|
|
565
|
+
cwe: "CWE-1333"
|
|
566
|
+
owasp: "A06:2021 - Vulnerable and Outdated Components"
|
|
567
|
+
confidence: LOW
|
|
568
|
+
references:
|
|
569
|
+
- https://semgrep.dev/r/python.lang.security.audit.regex-dos
|
|
570
|
+
|
|
571
|
+
# ============================================================================
|
|
572
|
+
# HARDCODED CREDENTIALS / SECRETS
|
|
573
|
+
# ============================================================================
|
|
574
|
+
- id: python.lang.security.audit.hardcoded-password
|
|
575
|
+
languages: [python]
|
|
576
|
+
severity: ERROR
|
|
577
|
+
message: "Hardcoded password detected. Use environment variables or a secrets manager."
|
|
578
|
+
patterns:
|
|
579
|
+
- "password\\s*=\\s*[\"'][^\"']{4,}[\"']"
|
|
580
|
+
- "passwd\\s*=\\s*[\"'][^\"']{4,}[\"']"
|
|
581
|
+
- "pwd\\s*=\\s*[\"'][^\"']{4,}[\"']"
|
|
582
|
+
metadata:
|
|
583
|
+
cwe: "CWE-798"
|
|
584
|
+
owasp: "A07:2021 - Identification and Authentication Failures"
|
|
585
|
+
confidence: MEDIUM
|
|
586
|
+
references:
|
|
587
|
+
- https://semgrep.dev/r/python.lang.security.audit.hardcoded-password
|
|
588
|
+
|
|
589
|
+
- id: python.lang.security.audit.hardcoded-api-key
|
|
590
|
+
languages: [python]
|
|
591
|
+
severity: ERROR
|
|
592
|
+
message: "Hardcoded API key detected. Use environment variables."
|
|
593
|
+
patterns:
|
|
594
|
+
- "api_key\\s*=\\s*[\"'][A-Za-z0-9_\\-]{16,}[\"']"
|
|
595
|
+
- "apikey\\s*=\\s*[\"'][A-Za-z0-9_\\-]{16,}[\"']"
|
|
596
|
+
- "API_KEY\\s*=\\s*[\"'][A-Za-z0-9_\\-]{16,}[\"']"
|
|
597
|
+
metadata:
|
|
598
|
+
cwe: "CWE-798"
|
|
599
|
+
owasp: "A07:2021 - Identification and Authentication Failures"
|
|
600
|
+
confidence: HIGH
|
|
601
|
+
references:
|
|
602
|
+
- https://semgrep.dev/r/python.lang.security.audit.hardcoded-api-key
|