seaworthycode 1.1.2 → 1.2.3

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 +739 -42
  2. package/dist/index.js.map +1 -1
  3. package/package.json +14 -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,325 @@
1
+ # attribution: CWE-79
2
+ attribution: CWE-79
3
+ language: go
4
+ applies-to: []
5
+
6
+ sources:
7
+ - id: net/http.FormValue
8
+ class: http-params
9
+ query: |
10
+ (call_expression
11
+ function: (selector_expression
12
+ field: (field_identifier) @method
13
+ (#match? @method "^(FormValue|PostFormValue)$"))
14
+ arguments: (argument_list (_) @arg)) @source
15
+
16
+ - id: net/http.URL.Query
17
+ class: http-params
18
+ query: |
19
+ (call_expression
20
+ function: (selector_expression
21
+ operand: (call_expression
22
+ function: (selector_expression
23
+ field: (field_identifier) @query
24
+ (#eq? @query "Query")))
25
+ field: (field_identifier) @get
26
+ (#eq? @get "Get"))
27
+ arguments: (argument_list (_) @arg)) @source
28
+
29
+ - id: gin.Context.Query
30
+ class: http-params
31
+ query: |
32
+ (call_expression
33
+ function: (selector_expression
34
+ operand: (identifier) @recv
35
+ field: (field_identifier) @method
36
+ (#match? @recv "^c$")
37
+ (#match? @method "^(Query|Param|PostForm)$"))
38
+ arguments: (argument_list (_) @arg)) @source
39
+
40
+ - id: echo.Context.Query
41
+ class: http-params
42
+ query: |
43
+ (call_expression
44
+ function: (selector_expression
45
+ operand: (identifier) @recv
46
+ field: (field_identifier) @method
47
+ (#match? @recv "^c$")
48
+ (#match? @method "^(QueryParam|FormValue)$"))
49
+ arguments: (argument_list (_) @arg)) @source
50
+
51
+ - id: net/http.Request.Body
52
+ class: http-body
53
+ query: |
54
+ (call_expression
55
+ function: (selector_expression
56
+ operand: (identifier) @obj
57
+ field: (field_identifier) @field
58
+ (#eq? @obj "io")
59
+ (#eq? @field "ReadAll"))
60
+ arguments: (argument_list
61
+ (selector_expression
62
+ field: (field_identifier) @body
63
+ (#eq? @body "Body")))) @source
64
+
65
+ - id: os.Args
66
+ class: process-argv
67
+ query: |
68
+ (index_expression
69
+ operand: (selector_expression
70
+ operand: (identifier) @obj
71
+ field: (field_identifier) @field
72
+ (#eq? @obj "os")
73
+ (#eq? @field "Args"))) @source
74
+
75
+ - id: os.Getenv
76
+ class: env-var
77
+ query: |
78
+ (call_expression
79
+ function: (selector_expression
80
+ operand: (identifier) @obj
81
+ field: (field_identifier) @field
82
+ (#eq? @obj "os")
83
+ (#eq? @field "Getenv"))
84
+ arguments: (argument_list (_) @arg)) @source
85
+
86
+ - id: io.ReadAll
87
+ class: network-response
88
+ query: |
89
+ (call_expression
90
+ function: (selector_expression
91
+ operand: (identifier) @obj
92
+ field: (field_identifier) @field
93
+ (#eq? @obj "io")
94
+ (#eq? @field "ReadAll"))
95
+ arguments: (argument_list
96
+ (_) @arg
97
+ (#not-match? @arg "Body"))) @source
98
+
99
+ - id: os.ReadFile
100
+ class: fs-read
101
+ query: |
102
+ (call_expression
103
+ function: (selector_expression
104
+ operand: (identifier) @obj
105
+ field: (field_identifier) @field
106
+ (#eq? @obj "os")
107
+ (#eq? @field "ReadFile"))
108
+ arguments: (argument_list (_) @arg)) @source
109
+
110
+ sinks:
111
+ - id: fmt.Fprintf
112
+ sink-class: xss
113
+ query: |
114
+ (call_expression
115
+ function: (selector_expression
116
+ operand: (identifier) @obj
117
+ field: (field_identifier) @field
118
+ (#eq? @obj "fmt")
119
+ (#eq? @field "Fprintf"))
120
+ arguments: (argument_list (_) @sink .)) @match
121
+
122
+ - id: io.WriteString
123
+ sink-class: xss
124
+ query: |
125
+ (call_expression
126
+ function: (selector_expression
127
+ operand: (identifier) @obj
128
+ field: (field_identifier) @field
129
+ (#eq? @obj "io")
130
+ (#eq? @field "WriteString"))
131
+ arguments: (argument_list (_) @sink .)) @match
132
+
133
+ - id: template.HTML
134
+ sink-class: xss
135
+ query: |
136
+ (call_expression
137
+ function: (selector_expression
138
+ operand: (identifier) @obj
139
+ field: (field_identifier) @field
140
+ (#eq? @obj "template")
141
+ (#eq? @field "HTML"))
142
+ arguments: (argument_list (_) @sink)) @match
143
+
144
+ - id: gin.Context.String
145
+ sink-class: xss
146
+ query: |
147
+ (call_expression
148
+ function: (selector_expression
149
+ operand: (identifier) @recv
150
+ field: (field_identifier) @field
151
+ (#match? @recv "^c$")
152
+ (#match? @field "^(String|HTML)$"))
153
+ arguments: (argument_list (_) @sink .)) @match
154
+
155
+ - id: db.Query
156
+ sink-class: sql-injection
157
+ query: |
158
+ (call_expression
159
+ function: (selector_expression
160
+ field: (field_identifier) @field
161
+ (#match? @field "^(Query|Exec|QueryRow)$"))
162
+ arguments: (argument_list . (_) @sink)) @match
163
+
164
+ - id: fmt.Sprintf-sql
165
+ sink-class: sql-injection
166
+ query: |
167
+ (call_expression
168
+ function: (selector_expression
169
+ operand: (identifier) @obj
170
+ field: (field_identifier) @field
171
+ (#eq? @obj "fmt")
172
+ (#eq? @field "Sprintf"))
173
+ arguments: (argument_list
174
+ (interpreted_string_literal) @sink
175
+ (#match? @sink "SELECT|INSERT|UPDATE|DELETE|UNION"))) @match
176
+
177
+ - id: exec.Command
178
+ sink-class: command-injection
179
+ query: |
180
+ (call_expression
181
+ function: (selector_expression
182
+ operand: (identifier) @obj
183
+ field: (field_identifier) @field
184
+ (#eq? @obj "exec")
185
+ (#match? @field "^(Command|CommandContext)$"))
186
+ arguments: (argument_list (_) @sink .)) @match
187
+
188
+ - id: os.Open
189
+ sink-class: path-traversal
190
+ query: |
191
+ (call_expression
192
+ function: (selector_expression
193
+ operand: (identifier) @obj
194
+ field: (field_identifier) @field
195
+ (#eq? @obj "os")
196
+ (#match? @field "^(Open|OpenFile|ReadFile|Create)$"))
197
+ arguments: (argument_list . (_) @sink)) @match
198
+
199
+ - id: http.Redirect
200
+ sink-class: url-injection
201
+ query: |
202
+ (call_expression
203
+ function: (selector_expression
204
+ operand: (identifier) @obj
205
+ field: (field_identifier) @field
206
+ (#eq? @obj "http")
207
+ (#eq? @field "Redirect"))
208
+ arguments: (argument_list
209
+ (_) (_) (_) @sink
210
+ (#not-match? @sink "^[0-9]+$"))) @match
211
+
212
+ - id: gin.Context.Redirect
213
+ sink-class: url-injection
214
+ query: |
215
+ (call_expression
216
+ function: (selector_expression
217
+ operand: (identifier) @recv
218
+ field: (field_identifier) @field
219
+ (#match? @recv "^c$")
220
+ (#eq? @field "Redirect"))
221
+ arguments: (argument_list
222
+ (_) (_) @sink
223
+ (#not-match? @sink "^[0-9]+$"))) @match
224
+
225
+ - id: maps.Copy
226
+ sink-class: prototype-pollution
227
+ query: |
228
+ (call_expression
229
+ function: (selector_expression
230
+ operand: (identifier) @obj
231
+ field: (field_identifier) @field
232
+ (#eq? @obj "maps")
233
+ (#eq? @field "Copy"))
234
+ arguments: (argument_list
235
+ (_)
236
+ [
237
+ (identifier) @sink
238
+ (call_expression) @sink
239
+ (selector_expression) @sink
240
+ (index_expression) @sink
241
+ (binary_expression) @sink
242
+ ])) @match
243
+
244
+ - id: plugin.Open
245
+ sink-class: code-execution
246
+ query: |
247
+ (call_expression
248
+ function: (selector_expression
249
+ operand: (identifier) @obj
250
+ field: (field_identifier) @field
251
+ (#eq? @obj "plugin")
252
+ (#eq? @field "Open"))
253
+ arguments: (argument_list . (_) @sink)) @match
254
+
255
+ sanitisers:
256
+ - id: html.EscapeString
257
+ sanitises: [xss]
258
+ autofix-safety: requires-import
259
+ query: |
260
+ (call_expression
261
+ function: (selector_expression
262
+ operand: (identifier) @obj
263
+ field: (field_identifier) @field
264
+ (#eq? @obj "html")
265
+ (#eq? @field "EscapeString"))
266
+ arguments: (argument_list (_) @arg)) @sanitiser
267
+
268
+ - id: url.QueryEscape
269
+ sanitises: [url-injection]
270
+ autofix-safety: requires-import
271
+ query: |
272
+ (call_expression
273
+ function: (selector_expression
274
+ operand: (identifier) @obj
275
+ field: (field_identifier) @field
276
+ (#eq? @obj "url")
277
+ (#eq? @field "QueryEscape"))
278
+ arguments: (argument_list (_) @arg)) @sanitiser
279
+
280
+ - id: filepath.Clean
281
+ sanitises: [path-traversal]
282
+ autofix-safety: requires-import
283
+ query: |
284
+ (call_expression
285
+ function: (selector_expression
286
+ operand: (identifier) @obj
287
+ field: (field_identifier) @field
288
+ (#eq? @obj "filepath")
289
+ (#eq? @field "Clean"))
290
+ arguments: (argument_list (_) @arg)) @sanitiser
291
+
292
+ - id: maps.Clone
293
+ sanitises: [prototype-pollution]
294
+ autofix-safety: requires-import
295
+ query: |
296
+ (call_expression
297
+ function: (selector_expression
298
+ operand: (identifier) @obj
299
+ field: (field_identifier) @field
300
+ (#eq? @obj "maps")
301
+ (#eq? @field "Clone"))
302
+ arguments: (argument_list (_) @arg)) @sanitiser
303
+
304
+ - id: parameterised-query
305
+ sanitises: [sql-injection]
306
+ query: |
307
+ (call_expression
308
+ function: (selector_expression
309
+ field: (field_identifier) @field
310
+ (#match? @field "^(Query|Exec|QueryRow)$"))
311
+ arguments: (argument_list
312
+ (interpreted_string_literal)
313
+ (_))) @sanitiser
314
+
315
+ - id: strconv.Quote
316
+ sanitises: [command-injection]
317
+ autofix-safety: requires-import
318
+ query: |
319
+ (call_expression
320
+ function: (selector_expression
321
+ operand: (identifier) @obj
322
+ field: (field_identifier) @field
323
+ (#eq? @obj "strconv")
324
+ (#eq? @field "Quote"))
325
+ arguments: (argument_list (_) @arg)) @sanitiser
@@ -0,0 +1,158 @@
1
+ language: java
2
+ cases:
3
+ - name: "SQLi servlet — getParameter to executeQuery concat"
4
+ language: java
5
+ code: |
6
+ class T {
7
+ void f(java.sql.Statement stmt, javax.servlet.http.HttpServletRequest req) throws Exception {
8
+ String id = req.getParameter("id");
9
+ stmt.executeQuery("SELECT * FROM users WHERE id = " + id);
10
+ }
11
+ }
12
+ expect:
13
+ count: 1
14
+ flows:
15
+ - sourceId: servlet.request.getParameter
16
+ sinkId: java.Statement.execute
17
+
18
+ - name: "SQLi sanitised — parameterised execute"
19
+ language: java
20
+ code: |
21
+ class T {
22
+ void f(java.sql.PreparedStatement ps, javax.servlet.http.HttpServletRequest req) throws Exception {
23
+ String id = req.getParameter("id");
24
+ ps.executeQuery();
25
+ }
26
+ }
27
+ expect:
28
+ count: 0
29
+
30
+ - name: "SQLi Spring — RequestParam to JdbcTemplate query"
31
+ language: java
32
+ code: |
33
+ import org.springframework.web.bind.annotation.RequestParam;
34
+ class T {
35
+ void m(org.springframework.jdbc.core.JdbcTemplate jdbc, @RequestParam String id) {
36
+ jdbc.query("SELECT * FROM users WHERE id = " + id);
37
+ }
38
+ }
39
+ expect:
40
+ count: 1
41
+ flows:
42
+ - sourceId: spring.requestParam
43
+ sinkId: java.JdbcTemplate.query
44
+
45
+ - name: "Command injection — getParameter to Runtime.exec"
46
+ language: java
47
+ code: |
48
+ class T {
49
+ void f(javax.servlet.http.HttpServletRequest req) throws Exception {
50
+ String cmd = req.getParameter("cmd");
51
+ Runtime.getRuntime().exec(cmd);
52
+ }
53
+ }
54
+ expect:
55
+ count: 1
56
+ flows:
57
+ - sourceId: servlet.request.getParameter
58
+ sinkId: java.Runtime.exec
59
+
60
+ - name: "XSS — getParameter to response print"
61
+ language: java
62
+ code: |
63
+ class T {
64
+ void f(javax.servlet.http.HttpServletRequest req, javax.servlet.http.HttpServletResponse res) throws Exception {
65
+ String html = req.getParameter("q");
66
+ res.getWriter().print(html);
67
+ }
68
+ }
69
+ expect:
70
+ count: 1
71
+ flows:
72
+ - sourceId: servlet.request.getParameter
73
+ sinkId: java.response.print
74
+
75
+ - name: "XSS sanitised — htmlEscape before print"
76
+ language: java
77
+ code: |
78
+ class T {
79
+ void f(javax.servlet.http.HttpServletResponse res, String html) throws Exception {
80
+ String safe = org.springframework.web.util.HtmlUtils.htmlEscape(html);
81
+ res.getWriter().print(safe);
82
+ }
83
+ }
84
+ expect:
85
+ count: 0
86
+
87
+ - name: "Path traversal — getParameter to File"
88
+ language: java
89
+ code: |
90
+ class T {
91
+ void f(javax.servlet.http.HttpServletRequest req) {
92
+ String path = req.getParameter("path");
93
+ new File(path);
94
+ }
95
+ }
96
+ expect:
97
+ count: 1
98
+ flows:
99
+ - sourceId: servlet.request.getParameter
100
+ sinkId: java.File.constructor
101
+
102
+ - name: "Open redirect — getParameter to sendRedirect"
103
+ language: java
104
+ code: |
105
+ class T {
106
+ void f(javax.servlet.http.HttpServletRequest req, javax.servlet.http.HttpServletResponse res) throws Exception {
107
+ String url = req.getParameter("url");
108
+ res.sendRedirect(url);
109
+ }
110
+ }
111
+ expect:
112
+ count: 1
113
+ flows:
114
+ - sourceId: servlet.request.getParameter
115
+ sinkId: java.response.sendRedirect
116
+
117
+ - name: "Code execution — getenv to ScriptEngine eval"
118
+ language: java
119
+ code: |
120
+ class T {
121
+ void f(javax.script.ScriptEngine engine) throws Exception {
122
+ String code = System.getenv("CODE");
123
+ engine.eval(code);
124
+ }
125
+ }
126
+ expect:
127
+ count: 1
128
+ flows:
129
+ - sourceId: java.System.getenv
130
+ sinkId: java.ScriptEngine.eval
131
+
132
+ - name: "Path not sanitised — normalize/getCanonicalPath before File"
133
+ language: java
134
+ code: |
135
+ class T {
136
+ void f(javax.servlet.http.HttpServletRequest req) throws Exception {
137
+ String path = req.getParameter("path");
138
+ String safe = new java.io.File(path).getCanonicalPath();
139
+ new java.io.File(safe);
140
+ }
141
+ }
142
+ expect:
143
+ count: 2
144
+ flows:
145
+ - sourceId: servlet.request.getParameter
146
+ sinkId: java.File.constructorScoped
147
+
148
+ - name: "Command sanitised — parseInt before exec"
149
+ language: java
150
+ code: |
151
+ class T {
152
+ void f(String port) throws Exception {
153
+ int p = Integer.parseInt(port);
154
+ Runtime.getRuntime().exec(new String[] { "echo", String.valueOf(p) });
155
+ }
156
+ }
157
+ expect:
158
+ count: 0