seaworthycode 1.1.1 → 1.1.4

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 (68) hide show
  1. package/dist/index.js +269 -59
  2. package/dist/index.js.map +1 -1
  3. package/package.json +16 -12
  4. package/rules/external/configuration/insecure-cookie-flags.test.yaml +114 -0
  5. package/rules/external/configuration/insecure-cookie-flags.yaml +77 -0
  6. package/rules/external/configuration/missing-ssl-verification.test.yaml +130 -0
  7. package/rules/external/configuration/missing-ssl-verification.yaml +123 -0
  8. package/rules/external/data-exposure/debug-artifacts.test.yaml +143 -0
  9. package/rules/external/data-exposure/debug-artifacts.yaml +57 -0
  10. package/rules/external/data-exposure/hardcoded-ip.test.yaml +131 -0
  11. package/rules/external/data-exposure/hardcoded-ip.yaml +67 -0
  12. package/rules/external/data-exposure/localstorage-sensitive-data.test.yaml +58 -0
  13. package/rules/external/data-exposure/localstorage-sensitive-data.yaml +60 -0
  14. package/rules/external/dependencies/deprecated-functions.test.yaml +92 -0
  15. package/rules/external/dependencies/deprecated-functions.yaml +66 -0
  16. package/rules/external/ops/hardcoded-port.test.yaml +141 -0
  17. package/rules/external/ops/hardcoded-port.yaml +91 -0
  18. package/rules/external/ops/insecure-file-permissions.test.yaml +111 -0
  19. package/rules/external/ops/insecure-file-permissions.yaml +91 -0
  20. package/rules/external/resilience/missing-memory-limit.test.yaml +54 -0
  21. package/rules/external/resilience/missing-memory-limit.yaml +59 -0
  22. package/rules/external/resilience/missing-timeout-config.test.yaml +179 -0
  23. package/rules/external/resilience/missing-timeout-config.yaml +124 -0
  24. package/rules/external/security/broken-crypto-algorithm.test.yaml +104 -0
  25. package/rules/external/security/broken-crypto-algorithm.yaml +79 -0
  26. package/rules/external/security/http-method-override.test.yaml +40 -0
  27. package/rules/external/security/http-method-override.yaml +35 -0
  28. package/rules/external/security/http-no-tls.test.yaml +115 -0
  29. package/rules/external/security/http-no-tls.yaml +59 -0
  30. package/rules/external/security/path-traversal.test.yaml +188 -0
  31. package/rules/external/security/path-traversal.yaml +210 -0
  32. package/rules/external/security/unsafe-innerhtml.test.yaml +72 -0
  33. package/rules/external/security/unsafe-innerhtml.yaml +46 -0
  34. package/rules/external/security/untrusted-deserialization.test.yaml +79 -0
  35. package/rules/external/security/untrusted-deserialization.yaml +48 -0
  36. package/rules/external/security/weak-encryption-mode.test.yaml +126 -0
  37. package/rules/external/security/weak-encryption-mode.yaml +104 -0
  38. package/rules/external/security/weak-hash-algorithm.test.yaml +121 -0
  39. package/rules/external/security/weak-hash-algorithm.yaml +87 -0
  40. package/rules/external/security/xxe-parsing.test.yaml +76 -0
  41. package/rules/external/security/xxe-parsing.yaml +63 -0
  42. package/rules/internal/security/dangerous-eval.test.yaml +126 -0
  43. package/rules/internal/security/dangerous-eval.yaml +134 -0
  44. package/rules/internal/security/no-document-write.test.yaml +33 -0
  45. package/rules/internal/security/no-document-write.yaml +40 -0
  46. package/rules/internal/taint/MATRIX.md +16 -0
  47. package/rules/internal/taint/bash.test.yaml +84 -0
  48. package/rules/internal/taint/bash.yaml +166 -0
  49. package/rules/internal/taint/dvwa.test.yaml +217 -0
  50. package/rules/internal/taint/go.test.yaml +207 -0
  51. package/rules/internal/taint/go.yaml +325 -0
  52. package/rules/internal/taint/java.test.yaml +158 -0
  53. package/rules/internal/taint/java.yaml +318 -0
  54. package/rules/internal/taint/javascript.test.yaml +374 -0
  55. package/rules/internal/taint/javascript.yaml +439 -0
  56. package/rules/internal/taint/php.test.yaml +134 -0
  57. package/rules/internal/taint/php.yaml +331 -0
  58. package/rules/internal/taint/python.test.yaml +427 -0
  59. package/rules/internal/taint/python.yaml +636 -0
  60. package/rules/internal/taint/ruby.test.yaml +148 -0
  61. package/rules/internal/taint/ruby.yaml +233 -0
  62. package/rules/internal/taint/rust.test.yaml +585 -0
  63. package/rules/internal/taint/rust.yaml +483 -0
  64. package/rules/internal/taint/tsx.test.yaml +140 -0
  65. package/rules/internal/taint/tsx.yaml +51 -0
  66. package/rules/internal/taint/typescript.test.yaml +393 -0
  67. package/rules/internal/taint/typescript.yaml +660 -0
  68. package/wasm/tree-sitter-sql.wasm +0 -0
@@ -0,0 +1,636 @@
1
+ # attribution: CWE-79
2
+ attribution: CWE-79
3
+ language: python
4
+ applies-to: []
5
+
6
+ sources:
7
+ - id: flask.request.json
8
+ class: http-body
9
+ query: |
10
+ [
11
+ (call
12
+ function: (attribute
13
+ object: [
14
+ (attribute
15
+ object: (identifier) @obj
16
+ attribute: (identifier) @attr1
17
+ (#eq? @obj "flask")
18
+ (#eq? @attr1 "request"))
19
+ (identifier) @req
20
+ (#eq? @req "request")
21
+ ]
22
+ attribute: (identifier) @attr2
23
+ (#match? @attr2 "^(get_json|json)$"))) @source
24
+ (attribute
25
+ object: [
26
+ (attribute
27
+ object: (identifier) @obj
28
+ attribute: (identifier) @attr1
29
+ (#eq? @obj "flask")
30
+ (#eq? @attr1 "request"))
31
+ (identifier) @req
32
+ (#eq? @req "request")
33
+ ]
34
+ attribute: (identifier) @attr2
35
+ (#match? @attr2 "^(get_json|json)$")) @source
36
+ ]
37
+
38
+ - id: flask.request.form
39
+ class: http-body
40
+ query: |
41
+ (attribute
42
+ object: [
43
+ (attribute
44
+ object: (identifier) @obj
45
+ attribute: (identifier) @attr1
46
+ (#eq? @obj "flask")
47
+ (#eq? @attr1 "request"))
48
+ (identifier) @req
49
+ (#eq? @req "request")
50
+ ]
51
+ attribute: (identifier) @attr2
52
+ (#eq? @attr2 "form")) @source
53
+
54
+ - id: request.args
55
+ class: http-params
56
+ query: |
57
+ (attribute
58
+ object: [
59
+ (attribute
60
+ object: (attribute
61
+ object: (identifier) @obj
62
+ attribute: (identifier) @attr1
63
+ (#eq? @obj "flask")
64
+ (#eq? @attr1 "request"))
65
+ attribute: (identifier) @attr2
66
+ (#eq? @attr2 "args"))
67
+ (attribute
68
+ object: (identifier) @req
69
+ attribute: (identifier) @attr2
70
+ (#eq? @req "request")
71
+ (#eq? @attr2 "args"))
72
+ ]) @source
73
+
74
+ - id: request.values
75
+ class: http-params
76
+ query: |
77
+ (attribute
78
+ object: [
79
+ (attribute
80
+ object: (attribute
81
+ object: (identifier) @obj
82
+ attribute: (identifier) @attr1
83
+ (#eq? @obj "flask")
84
+ (#eq? @attr1 "request"))
85
+ attribute: (identifier) @attr2
86
+ (#eq? @attr2 "values"))
87
+ (attribute
88
+ object: (identifier) @req
89
+ attribute: (identifier) @attr2
90
+ (#eq? @req "request")
91
+ (#eq? @attr2 "values"))
92
+ ]) @source
93
+
94
+ - id: django.request.GET
95
+ class: http-params
96
+ query: |
97
+ (attribute
98
+ object: (identifier) @obj
99
+ attribute: (identifier) @attr
100
+ (#eq? @obj "request")
101
+ (#eq? @attr "GET")) @source
102
+
103
+ - id: django.request.POST
104
+ class: http-body
105
+ query: |
106
+ (attribute
107
+ object: (identifier) @obj
108
+ attribute: (identifier) @attr
109
+ (#eq? @obj "request")
110
+ (#eq? @attr "POST")) @source
111
+
112
+ - id: django.request.COOKIES
113
+ class: http-params
114
+ query: |
115
+ (attribute
116
+ object: (identifier) @obj
117
+ attribute: (identifier) @attr
118
+ (#eq? @obj "request")
119
+ (#eq? @attr "COOKIES")) @source
120
+
121
+ - id: sys.argv
122
+ class: process-argv
123
+ query: |
124
+ (attribute
125
+ object: (identifier) @obj
126
+ attribute: (identifier) @attr
127
+ (#eq? @obj "sys")
128
+ (#eq? @attr "argv")) @source
129
+
130
+ - id: os.environ.get
131
+ class: env-var
132
+ query: |
133
+ (call
134
+ function: (attribute
135
+ object: (attribute
136
+ object: (identifier) @obj
137
+ attribute: (identifier) @attr1
138
+ (#eq? @obj "os")
139
+ (#eq? @attr1 "environ"))
140
+ attribute: (identifier) @attr2
141
+ (#eq? @attr2 "get"))) @source
142
+
143
+ - id: starlette.request.query_params
144
+ class: http-params
145
+ query: |
146
+ (call
147
+ function: (attribute
148
+ object: (attribute
149
+ object: (identifier) @obj
150
+ attribute: (identifier) @attr1
151
+ (#eq? @obj "request")
152
+ (#eq? @attr1 "query_params"))
153
+ attribute: (identifier) @attr2
154
+ (#eq? @attr2 "get"))) @source
155
+
156
+ - id: starlette.request.path_params
157
+ class: http-params
158
+ query: |
159
+ (subscript
160
+ value: (attribute
161
+ object: (identifier) @obj
162
+ attribute: (identifier) @attr1
163
+ (#eq? @obj "request")
164
+ (#eq? @attr1 "path_params"))) @source
165
+
166
+ - id: fastapi.UploadFile.filename
167
+ class: http-body
168
+ query: |
169
+ (attribute
170
+ object: (identifier) @obj
171
+ attribute: (identifier) @attr
172
+ (#eq? @obj "upload_file")
173
+ (#eq? @attr "filename")) @source
174
+
175
+ - id: open-read
176
+ class: fs-read
177
+ query: |
178
+ (call
179
+ function: (attribute
180
+ object: (call
181
+ function: (identifier) @func
182
+ (#eq? @func "open")
183
+ arguments: (argument_list (_) @arg))
184
+ attribute: (identifier) @attr
185
+ (#eq? @attr "read"))) @source
186
+
187
+ - id: requests.response.text
188
+ class: network-response
189
+ query: |
190
+ [
191
+ (call
192
+ function: (attribute
193
+ object: (call
194
+ function: (attribute
195
+ object: (identifier) @obj
196
+ attribute: (identifier) @method
197
+ (#eq? @obj "requests")
198
+ (#match? @method "^(get|post|put|delete|patch)$"))
199
+ arguments: (argument_list (_) @url))
200
+ attribute: (identifier) @attr
201
+ (#eq? @attr "text"))) @source
202
+ (attribute
203
+ object: (call
204
+ function: (attribute
205
+ object: (identifier) @obj
206
+ attribute: (identifier) @method
207
+ (#eq? @obj "requests")
208
+ (#match? @method "^(get|post|put|delete|patch)$"))
209
+ arguments: (argument_list (_) @url))
210
+ attribute: (identifier) @attr
211
+ (#eq? @attr "text")) @source
212
+ ]
213
+
214
+ - id: requests.response.json
215
+ class: network-response
216
+ query: |
217
+ (call
218
+ function: (attribute
219
+ object: (call
220
+ function: (attribute
221
+ object: (identifier) @obj
222
+ attribute: (identifier) @method
223
+ (#eq? @obj "requests")
224
+ (#match? @method "^(get|post|put|delete|patch)$"))
225
+ arguments: (argument_list (_) @url))
226
+ attribute: (identifier) @attr
227
+ (#eq? @attr "json"))) @source
228
+
229
+ - id: request.headers
230
+ class: http-params
231
+ # NOTE: These queries match any identifier named "request", not just
232
+ # framework-provided request objects. This may produce false positives
233
+ # when local variables are named "request".
234
+ query: |
235
+ [
236
+ (attribute
237
+ object: (attribute
238
+ object: (identifier) @obj
239
+ attribute: (identifier) @attr
240
+ (#eq? @obj "request")
241
+ (#eq? @attr "headers"))) @source
242
+ (attribute
243
+ object: (attribute
244
+ object: (attribute
245
+ object: (identifier) @flask
246
+ attribute: (identifier) @req
247
+ (#eq? @flask "flask")
248
+ (#eq? @req "request"))
249
+ attribute: (identifier) @headers
250
+ (#eq? @headers "headers"))) @source
251
+ ]
252
+
253
+ - id: request.cookies
254
+ class: http-params
255
+ # NOTE: These queries match any identifier named "request", not just
256
+ # framework-provided request objects. This may produce false positives
257
+ # when local variables are named "request".
258
+ query: |
259
+ [
260
+ (attribute
261
+ object: (attribute
262
+ object: (identifier) @obj
263
+ attribute: (identifier) @attr
264
+ (#eq? @obj "request")
265
+ (#match? @attr "^(cookies|COOKIES)$"))) @source
266
+ (attribute
267
+ object: (attribute
268
+ object: (attribute
269
+ object: (identifier) @flask
270
+ attribute: (identifier) @req
271
+ (#eq? @flask "flask")
272
+ (#eq? @req "request"))
273
+ attribute: (identifier) @cookies
274
+ (#eq? @cookies "cookies"))) @source
275
+ ]
276
+
277
+ - id: input
278
+ class: stdin
279
+ query: |
280
+ (call
281
+ function: (identifier) @func
282
+ (#eq? @func "input")) @source
283
+
284
+ sinks:
285
+ - id: eval
286
+ sink-class: code-execution
287
+ query: |
288
+ (call
289
+ function: (identifier) @func
290
+ (#eq? @func "eval")
291
+ arguments: (argument_list (_) @sink)) @match
292
+
293
+ - id: exec
294
+ sink-class: code-execution
295
+ query: |
296
+ (call
297
+ function: (identifier) @func
298
+ (#eq? @func "exec")
299
+ arguments: (argument_list (_) @sink)) @match
300
+
301
+ - id: os.system
302
+ sink-class: command-injection
303
+ query: |
304
+ (call
305
+ function: (attribute
306
+ object: (identifier) @obj
307
+ attribute: (identifier) @attr
308
+ (#eq? @obj "os")
309
+ (#eq? @attr "system"))
310
+ arguments: (argument_list (_) @sink)) @match
311
+
312
+ - id: subprocess.call
313
+ sink-class: command-injection
314
+ query: |
315
+ (call
316
+ function: (attribute
317
+ object: (identifier) @obj
318
+ attribute: (identifier) @attr
319
+ (#eq? @obj "subprocess")
320
+ (#match? @attr "^(call|check_call|check_output|run)$"))
321
+ arguments: (argument_list (_) @sink)) @match
322
+
323
+ - id: subprocess.Popen
324
+ sink-class: command-injection
325
+ query: |
326
+ (call
327
+ function: (identifier) @func
328
+ (#eq? @func "Popen")
329
+ arguments: (argument_list (_) @sink)) @match
330
+
331
+ - id: django.http.HttpResponse
332
+ sink-class: xss
333
+ query: |
334
+ (call
335
+ function: (identifier) @func
336
+ (#eq? @func "HttpResponse")
337
+ arguments: (argument_list (_) @sink)) @match
338
+
339
+ - id: flask.render_template_string
340
+ sink-class: xss
341
+ query: |
342
+ (call
343
+ function: (attribute
344
+ object: (identifier) @obj
345
+ attribute: (identifier) @attr
346
+ (#eq? @obj "flask")
347
+ (#match? @attr "^(render_template_string|Markup)$"))
348
+ arguments: (argument_list (_) @sink)) @match
349
+
350
+ - id: flask.make_response
351
+ sink-class: xss
352
+ query: |
353
+ (call
354
+ function: (attribute
355
+ object: (identifier) @obj
356
+ attribute: (identifier) @attr
357
+ (#eq? @obj "flask")
358
+ (#eq? @attr "make_response"))
359
+ arguments: (argument_list (_) @sink)) @match
360
+
361
+ - id: cursor.execute
362
+ sink-class: sql-injection
363
+ query: |
364
+ (call
365
+ function: (attribute
366
+ object: (identifier) @obj
367
+ attribute: (identifier) @attr
368
+ (#eq? @attr "execute"))
369
+ arguments: (argument_list (_) @sink)) @match
370
+
371
+ - id: connection.execute
372
+ sink-class: sql-injection
373
+ query: |
374
+ (call
375
+ function: (attribute
376
+ object: (attribute
377
+ object: (identifier) @obj
378
+ attribute: (identifier) @attr1
379
+ (#eq? @attr1 "connection"))
380
+ attribute: (identifier) @attr2
381
+ (#eq? @attr2 "execute"))
382
+ arguments: (argument_list (_) @sink)) @match
383
+
384
+ - id: open-write
385
+ sink-class: path-traversal
386
+ query: |
387
+ (call
388
+ function: (identifier) @func
389
+ (#eq? @func "open")
390
+ arguments: (argument_list (_) @sink)) @match
391
+
392
+ - id: django.http.HttpResponseRedirect
393
+ sink-class: url-injection
394
+ query: |
395
+ (call
396
+ function: (identifier) @func
397
+ (#eq? @func "HttpResponseRedirect")
398
+ arguments: (argument_list (_) @sink)) @match
399
+
400
+ - id: flask.redirect
401
+ sink-class: url-injection
402
+ query: |
403
+ (call
404
+ function: (attribute
405
+ object: (identifier) @obj
406
+ attribute: (identifier) @attr
407
+ (#eq? @obj "flask")
408
+ (#eq? @attr "redirect"))
409
+ arguments: (argument_list (_) @sink)) @match
410
+
411
+ - id: dict.update
412
+ sink-class: prototype-pollution
413
+ query: |
414
+ (call
415
+ function: (attribute
416
+ object: (_) @obj
417
+ attribute: (identifier) @attr
418
+ (#eq? @attr "update"))
419
+ arguments: (argument_list (_) @sink)) @match
420
+
421
+ - id: dict.setdefault
422
+ sink-class: prototype-pollution
423
+ query: |
424
+ (call
425
+ function: (attribute
426
+ object: (_) @obj
427
+ attribute: (identifier) @attr
428
+ (#eq? @attr "setdefault"))
429
+ arguments: (argument_list (_) @key (_) @sink)) @match
430
+
431
+ - id: pickle.loads
432
+ sink-class: code-execution
433
+ query: |
434
+ (call
435
+ function: (attribute
436
+ object: (identifier) @obj
437
+ attribute: (identifier) @attr
438
+ (#eq? @obj "pickle")
439
+ (#eq? @attr "loads"))
440
+ arguments: (argument_list (_) @sink)) @match
441
+
442
+ - id: yaml.unsafe_load
443
+ sink-class: code-execution
444
+ query: |
445
+ (call
446
+ function: (attribute
447
+ object: (identifier) @obj
448
+ attribute: (identifier) @attr
449
+ (#eq? @obj "yaml")
450
+ (#eq? @attr "unsafe_load"))
451
+ arguments: (argument_list (_) @sink)) @match
452
+
453
+ - id: starlette.RedirectResponse
454
+ sink-class: url-injection
455
+ query: |
456
+ (call
457
+ function: [
458
+ (identifier) @func
459
+ (attribute
460
+ attribute: (identifier) @func)
461
+ ]
462
+ (#eq? @func "RedirectResponse")
463
+ arguments: (argument_list (_) @sink)) @match
464
+
465
+ - id: starlette.HTMLResponse
466
+ sink-class: xss
467
+ query: |
468
+ (call
469
+ function: [
470
+ (identifier) @func
471
+ (attribute
472
+ attribute: (identifier) @func)
473
+ ]
474
+ (#eq? @func "HTMLResponse")
475
+ arguments: (argument_list (_) @sink)) @match
476
+
477
+ - id: jinja2.Template
478
+ sink-class: xss
479
+ query: |
480
+ (call
481
+ function: [
482
+ (identifier) @func
483
+ (attribute
484
+ attribute: (identifier) @func)
485
+ ]
486
+ (#eq? @func "Template")
487
+ arguments: (argument_list (_) @sink)) @match
488
+
489
+ - id: django.db.models.raw
490
+ sink-class: sql-injection
491
+ query: |
492
+ (call
493
+ function: (attribute
494
+ attribute: (identifier) @method
495
+ (#eq? @method "raw"))
496
+ arguments: (argument_list (_) @sink)) @match
497
+
498
+ - id: django.db.models.expressions.RawSQL
499
+ sink-class: sql-injection
500
+ query: |
501
+ (call
502
+ function: [
503
+ (identifier) @func
504
+ (attribute
505
+ attribute: (identifier) @func)
506
+ ]
507
+ (#eq? @func "RawSQL")
508
+ arguments: (argument_list (_) @sink)) @match
509
+
510
+ sanitisers:
511
+ - id: html.escape
512
+ sanitises: [xss]
513
+ autofix-safety: requires-import
514
+ query: |
515
+ (call
516
+ function: (attribute
517
+ object: (identifier) @obj
518
+ attribute: (identifier) @attr
519
+ (#eq? @obj "html")
520
+ (#eq? @attr "escape"))) @sanitiser
521
+
522
+ - id: markupsafe.escape
523
+ sanitises: [xss]
524
+ autofix-safety: requires-import
525
+ query: |
526
+ (call
527
+ function: (attribute
528
+ object: (identifier) @obj
529
+ attribute: (identifier) @attr
530
+ (#eq? @obj "markupsafe")
531
+ (#eq? @attr "escape"))) @sanitiser
532
+
533
+ - id: django.utils.html.escape
534
+ sanitises: [xss]
535
+ autofix-safety: requires-import
536
+ query: |
537
+ (call
538
+ function: (attribute
539
+ object: (attribute
540
+ object: (attribute
541
+ object: (identifier) @obj
542
+ attribute: (identifier) @attr1
543
+ (#eq? @obj "django")
544
+ (#eq? @attr1 "utils"))
545
+ attribute: (identifier) @attr2
546
+ (#eq? @attr2 "html"))
547
+ attribute: (identifier) @attr3
548
+ (#eq? @attr3 "escape"))) @sanitiser
549
+
550
+ - id: parameterised-query
551
+ sanitises: [sql-injection]
552
+ query: |
553
+ (call
554
+ function: (attribute
555
+ object: (_) @obj
556
+ attribute: (identifier) @attr
557
+ (#eq? @attr "execute"))
558
+ arguments: (argument_list (string) @sql (list) @params)) @sanitiser
559
+
560
+ - id: parameterised-query-named
561
+ sanitises: [sql-injection]
562
+ query: |
563
+ (call
564
+ function: (attribute
565
+ object: (_) @obj
566
+ attribute: (identifier) @attr
567
+ (#eq? @attr "execute"))
568
+ arguments: (argument_list (string) @sql (dictionary) @params)) @sanitiser
569
+
570
+ - id: shlex.quote
571
+ sanitises: [command-injection]
572
+ autofix-safety: requires-import
573
+ query: |
574
+ (call
575
+ function: (attribute
576
+ object: (identifier) @obj
577
+ attribute: (identifier) @attr
578
+ (#eq? @obj "shlex")
579
+ (#eq? @attr "quote"))) @sanitiser
580
+
581
+ - id: os.path.realpath
582
+ sanitises: [path-traversal]
583
+ autofix-safety: requires-import
584
+ query: |
585
+ (call
586
+ function: (attribute
587
+ object: (attribute
588
+ object: (identifier) @obj
589
+ attribute: (identifier) @attr1
590
+ (#eq? @obj "os")
591
+ (#eq? @attr1 "path"))
592
+ attribute: (identifier) @attr2
593
+ (#eq? @attr2 "realpath"))) @sanitiser
594
+
595
+ - id: urllib.parse.quote
596
+ sanitises: [url-injection]
597
+ autofix-safety: requires-import
598
+ query: |
599
+ (call
600
+ function: (attribute
601
+ object: (attribute
602
+ object: (identifier) @obj
603
+ attribute: (identifier) @attr1
604
+ (#eq? @obj "urllib")
605
+ (#eq? @attr1 "parse"))
606
+ attribute: (identifier) @attr2
607
+ (#eq? @attr2 "quote"))) @sanitiser
608
+
609
+ - id: json.dumps
610
+ sanitises: [prototype-pollution]
611
+ autofix-safety: requires-import
612
+ query: |
613
+ (call
614
+ function: (attribute
615
+ object: (identifier) @obj
616
+ attribute: (identifier) @attr
617
+ (#eq? @obj "json")
618
+ (#eq? @attr "dumps"))) @sanitiser
619
+
620
+ - id: copy.deepcopy
621
+ sanitises: [prototype-pollution]
622
+ autofix-safety: requires-import
623
+ query: |
624
+ (call
625
+ function: (attribute
626
+ object: (identifier) @obj
627
+ attribute: (identifier) @attr
628
+ (#eq? @obj "copy")
629
+ (#eq? @attr "deepcopy"))) @sanitiser
630
+
631
+ - id: int.float.cast
632
+ sanitises: [sql-injection]
633
+ query: |
634
+ (call
635
+ function: (identifier) @func
636
+ (#match? @func "^(int|float)$")) @sanitiser