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,393 @@
1
+ language: typescript
2
+ cases:
3
+ - name: "AC-4.6: direct XSS flow from req.body to res.send in TS"
4
+ language: typescript
5
+ code: |
6
+ const x = req.body;
7
+ res.send(x);
8
+ expect:
9
+ count: 1
10
+ flows:
11
+ - sourceId: req.body
12
+ sinkId: res.send
13
+
14
+ - name: "AC-4.7: XSS sanitised by encodeURIComponent in TS — no finding"
15
+ language: typescript
16
+ code: |
17
+ res.send(encodeURIComponent(req.body));
18
+ expect:
19
+ count: 0
20
+
21
+ - name: "SQL injection in TS — req.query to db.query"
22
+ language: typescript
23
+ code: |
24
+ const q = req.query.id;
25
+ db.query("SELECT * FROM users WHERE id = " + q);
26
+ expect:
27
+ count: 1
28
+ flows:
29
+ - sourceId: req.query
30
+ sinkId: db.query
31
+
32
+ - name: "SQL injection sanitised by parameterised query in TS"
33
+ language: typescript
34
+ code: |
35
+ db.query("SELECT * FROM users WHERE id = ?", [req.query.id]);
36
+ expect:
37
+ count: 0
38
+
39
+ - name: "Sequelize query with req.query criteria"
40
+ language: typescript
41
+ code: |
42
+ const criteria = req.query.q;
43
+ models.sequelize.query(`SELECT * FROM Products WHERE name LIKE '%${criteria}%'`);
44
+ expect:
45
+ count: 2
46
+ flows:
47
+ - sourceId: req.query
48
+ sinkId: sequelize.query
49
+ - sourceId: req.query
50
+ sinkId: template-literal-sql
51
+
52
+ - name: "Safe parameterised Sequelize-style query"
53
+ language: typescript
54
+ code: |
55
+ models.sequelize.query("SELECT * FROM Products WHERE id = ?", [req.query.id]);
56
+ expect:
57
+ count: 0
58
+
59
+ - name: "URL injection in TS — req.query to res.redirect"
60
+ language: typescript
61
+ code: |
62
+ res.redirect(req.query.next);
63
+ expect:
64
+ count: 1
65
+ flows:
66
+ - sourceId: req.query
67
+ sinkId: res.redirect
68
+
69
+ - name: "Command injection in TS — process.argv to child_process.exec"
70
+ language: typescript
71
+ code: |
72
+ child_process.exec(process.argv[2]);
73
+ expect:
74
+ count: 1
75
+ flows:
76
+ - sourceId: process.argv
77
+ sinkId: child_process.exec
78
+
79
+ - name: "Path traversal in TS — req.params to fs.readFile"
80
+ language: typescript
81
+ code: |
82
+ fs.readFile(req.params.file);
83
+ expect:
84
+ count: 1
85
+ flows:
86
+ - sourceId: req.params
87
+ sinkId: fs.readFile-path
88
+
89
+ - name: "Path traversal sanitised in TS — path.resolve"
90
+ language: typescript
91
+ code: |
92
+ fs.readFile(path.resolve("/safe", req.params.file));
93
+ expect:
94
+ count: 0
95
+
96
+ - name: "Safe fs.writeFile with literal path — zero flows"
97
+ language: typescript
98
+ code: |
99
+ fs.writeFile('./data/app-config.json', 'static');
100
+ expect:
101
+ count: 0
102
+
103
+ - name: "Juice Shop-style codingChallenges read — zero flows"
104
+ language: typescript
105
+ code: |
106
+ import fs from 'fs';
107
+ fs.readFile('./data/codingchallenges/readme.md');
108
+ expect:
109
+ count: 0
110
+
111
+ - name: "Path traversal in TS — req.params to res.sendFile"
112
+ language: typescript
113
+ code: |
114
+ res.sendFile(req.params.file);
115
+ expect:
116
+ count: 1
117
+ flows:
118
+ - sourceId: req.params
119
+ sinkId: res.sendFile
120
+
121
+ - name: "Path traversal in TS — req.query to res.download"
122
+ language: typescript
123
+ code: |
124
+ res.download(req.query.path);
125
+ expect:
126
+ count: 1
127
+ flows:
128
+ - sourceId: req.query
129
+ sinkId: res.download
130
+
131
+ - name: "URL injection in TS — process.env to location.href"
132
+ language: typescript
133
+ code: |
134
+ window.location.href = process.env.REDIRECT_URL;
135
+ expect:
136
+ count: 1
137
+ flows:
138
+ - sourceId: process.env
139
+ sinkId: location.href
140
+
141
+ - name: "URL injection sanitised by encodeURIComponent in TS"
142
+ language: typescript
143
+ code: |
144
+ res.redirect(encodeURIComponent(req.query.redirect));
145
+ expect:
146
+ count: 0
147
+
148
+ - name: "TS — Function call stops propagation"
149
+ language: typescript
150
+ code: |
151
+ const x = req.body;
152
+ helper(x);
153
+ eval(x);
154
+ expect:
155
+ count: 1
156
+ flows:
157
+ - sourceId: req.body
158
+ sinkId: eval
159
+
160
+ - name: "TS — Prototype pollution with merge"
161
+ language: typescript
162
+ code: |
163
+ const target = {};
164
+ merge(target, req.body);
165
+ expect:
166
+ count: 1
167
+ flows:
168
+ - sourceId: req.body
169
+ sinkId: merge-deep
170
+
171
+ - name: "TS — Object.freeze sanitises prototype pollution"
172
+ language: typescript
173
+ code: |
174
+ const target = {};
175
+ Object.assign(target, Object.freeze(req.body));
176
+ expect:
177
+ count: 0
178
+
179
+ - name: "TS — API XSS from req.body to res.json"
180
+ language: typescript
181
+ code: |
182
+ res.json(req.body.label);
183
+ expect:
184
+ count: 1
185
+ flows:
186
+ - sourceId: req.body
187
+ sinkId: res.json
188
+
189
+ - name: "TS — API XSS safe — res.json with literal object"
190
+ language: typescript
191
+ code: |
192
+ res.json({ ok: true });
193
+ expect:
194
+ count: 0
195
+
196
+ - name: "TS — destructuring SQLi from req.query"
197
+ language: typescript
198
+ code: |
199
+ const { id } = req.query;
200
+ db.query("SELECT * FROM users WHERE id = " + id);
201
+ expect:
202
+ count: 1
203
+ flows:
204
+ - sourceId: req.query
205
+ sinkId: db.query
206
+
207
+ - name: "TS — MongoDB $where injection"
208
+ language: typescript
209
+ code: |
210
+ Product.find({ $where: req.query.q });
211
+ expect:
212
+ count: 1
213
+ flows:
214
+ - sourceId: req.query
215
+ sinkId: Model.find-$where
216
+
217
+ - name: "TS — upload path traversal via fs.writeFile"
218
+ language: typescript
219
+ code: |
220
+ fs.writeFile(req.body.path, req.body.data);
221
+ expect:
222
+ count: 1
223
+ flows:
224
+ - sourceId: req.body
225
+ sinkId: fs.writeFile-path
226
+
227
+ - name: "TS — DOMPurify sanitises res.json XSS"
228
+ language: typescript
229
+ code: |
230
+ res.json(DOMPurify.sanitize(req.body.x));
231
+ expect:
232
+ count: 0
233
+
234
+ - name: "TS — optional chaining req?.body to res.send"
235
+ language: typescript
236
+ code: |
237
+ const x = req?.body;
238
+ res.send(x);
239
+ expect:
240
+ count: 1
241
+ flows:
242
+ - sourceId: req.body
243
+ sinkId: res.send
244
+
245
+ - name: "TS — multer req.file.path to fs.writeFile"
246
+ language: typescript
247
+ code: |
248
+ fs.writeFile(req.file.path, buf);
249
+ expect:
250
+ count: 1
251
+ flows:
252
+ - sourceId: req.file.path
253
+ sinkId: fs.writeFile-path
254
+
255
+ - name: "TS — Fastify request.body to res.send XSS"
256
+ language: typescript
257
+ code: |
258
+ const x = request.body;
259
+ res.send(x);
260
+ expect:
261
+ count: 1
262
+ flows:
263
+ - sourceId: fastify.request.body
264
+ sinkId: res.send
265
+
266
+ - name: "TS — req.headers to res.redirect"
267
+ language: typescript
268
+ code: |
269
+ res.redirect(req.headers.referer);
270
+ expect:
271
+ count: 1
272
+ flows:
273
+ - sourceId: req.headers
274
+ sinkId: res.redirect
275
+
276
+ - name: "TS — Prisma $queryRaw SQLi"
277
+ language: typescript
278
+ code: |
279
+ const id = req.query.id;
280
+ prisma.$queryRaw("SELECT * FROM users WHERE id = " + id);
281
+ expect:
282
+ count: 1
283
+ flows:
284
+ - sourceId: req.query
285
+ sinkId: prisma.queryRaw
286
+
287
+ - name: "TS — child_process.spawn command injection"
288
+ language: typescript
289
+ code: |
290
+ child_process.spawn(process.argv[2]);
291
+ expect:
292
+ count: 1
293
+ flows:
294
+ - sourceId: process.argv
295
+ sinkId: child_process.spawn
296
+
297
+ - name: "TS — child_process.spawn with constant argv — no flow"
298
+ language: typescript
299
+ code: |
300
+ child_process.spawn('ls', ['-la']);
301
+ expect:
302
+ count: 0
303
+
304
+ - name: "TS — NestJS @Body to res.send XSS"
305
+ language: typescript
306
+ code: |
307
+ function handler(@Body() body: unknown) {
308
+ res.send(body);
309
+ }
310
+ expect:
311
+ count: 1
312
+ flows:
313
+ - sourceId: nest.decorator-body
314
+ sinkId: res.send
315
+
316
+ - name: "TS — Hono c.req.body to res.send"
317
+ language: typescript
318
+ code: |
319
+ const x = c.req.body;
320
+ res.send(x);
321
+ expect:
322
+ count: 1
323
+ flows:
324
+ - sourceId: hono.req.body
325
+ sinkId: res.send
326
+
327
+ - name: "TS — GraphQL @Args to db.query SQLi"
328
+ language: typescript
329
+ code: |
330
+ function resolver(@Args('id') args: string) {
331
+ db.query("SELECT * FROM t WHERE id = " + args);
332
+ }
333
+ expect:
334
+ count: 1
335
+ flows:
336
+ - sourceId: graphql.args
337
+ sinkId: db.query
338
+
339
+ - name: "TS — Next.js redirect URL injection"
340
+ language: typescript
341
+ code: |
342
+ redirect(req.query.next);
343
+ expect:
344
+ count: 1
345
+ flows:
346
+ - sourceId: req.query
347
+ sinkId: next.redirect
348
+
349
+ - name: "TS — fs/promises readFile path traversal"
350
+ language: typescript
351
+ code: |
352
+ import * as fs from 'fs';
353
+ fs.promises.readFile(req.params.path);
354
+ expect:
355
+ count: 1
356
+ flows:
357
+ - sourceId: req.params
358
+ sinkId: fs.promises.readFile
359
+
360
+ - name: "TS — WebSocket on message to res.send XSS"
361
+ language: typescript
362
+ code: |
363
+ ws.on('message', (data: string) => {
364
+ res.send(data);
365
+ });
366
+ expect:
367
+ count: 1
368
+ flows:
369
+ - sourceId: websocket.message
370
+ sinkId: res.send
371
+
372
+ - name: "TS — code-execution sanitised static Function — no flow"
373
+ language: typescript
374
+ code: |
375
+ const x = req.body;
376
+ new Function("return 1");
377
+ expect:
378
+ count: 0
379
+
380
+ - name: "TS — url-injection sanitised encodeURIComponent on redirect"
381
+ language: typescript
382
+ code: |
383
+ res.redirect(encodeURIComponent(req.query.next));
384
+ expect:
385
+ count: 0
386
+
387
+ - name: "TS — zod.parse blocks XSS to res.send"
388
+ language: typescript
389
+ code: |
390
+ const parsed = z.object({ x: z.string() }).parse(req.body);
391
+ res.send(parsed.x);
392
+ expect:
393
+ count: 0