seaworthycode 1.1.2 → 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 +30 -26
  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,148 @@
1
+ language: ruby
2
+ cases:
3
+ - name: "SQLi from params to find_by_sql"
4
+ language: ruby
5
+ code: |
6
+ id = params[:id]
7
+ User.find_by_sql("SELECT * FROM users WHERE id = #{id}")
8
+ expect:
9
+ count: 1
10
+ flows:
11
+ - sourceId: params
12
+ sinkId: ruby.sqli_find
13
+
14
+ - name: "SQLi sanitised by to_i"
15
+ language: ruby
16
+ code: |
17
+ id = params[:id].to_i
18
+ User.find_by_sql("SELECT * FROM users WHERE id = #{id}")
19
+ expect:
20
+ count: 0
21
+
22
+ - name: "SQLi from params to connection.execute"
23
+ language: ruby
24
+ code: |
25
+ sql = params[:q]
26
+ ActiveRecord::Base.connection.execute(sql)
27
+ expect:
28
+ count: 1
29
+ flows:
30
+ - sourceId: params
31
+ sinkId: ruby.sqli_conn
32
+
33
+ - name: "Command injection from request.params to system"
34
+ language: ruby
35
+ code: |
36
+ cmd = request.params["cmd"]
37
+ system(cmd)
38
+ expect:
39
+ count: 1
40
+ flows:
41
+ - sourceId: params
42
+ sinkId: ruby.cmd_call
43
+
44
+ - name: "Command injection via backticks"
45
+ language: ruby
46
+ code: |
47
+ cmd = request.params["cmd"]
48
+ `#{cmd}`
49
+ expect:
50
+ count: 1
51
+ flows:
52
+ - sourceId: params
53
+ sinkId: ruby.cmd_subshell
54
+
55
+ - name: "Command injection sanitised by Shellwords.escape"
56
+ language: ruby
57
+ code: |
58
+ system(Shellwords.escape(params[:cmd]))
59
+ expect:
60
+ count: 0
61
+
62
+ - name: "XSS from cookies to raw"
63
+ language: ruby
64
+ code: |
65
+ html = cookies[:html]
66
+ raw(html)
67
+ expect:
68
+ count: 1
69
+ flows:
70
+ - sourceId: cookies_or_session
71
+ sinkId: rails.xss_raw
72
+
73
+ - name: "XSS sanitised by html_escape"
74
+ language: ruby
75
+ code: |
76
+ html = html_escape(cookies[:html])
77
+ raw(html)
78
+ expect:
79
+ count: 0
80
+
81
+ - name: "Code execution from ARGV to eval"
82
+ language: ruby
83
+ code: |
84
+ code = ARGV[0]
85
+ eval(code)
86
+ expect:
87
+ count: 1
88
+ flows:
89
+ - sourceId: ruby.argv
90
+ sinkId: ruby.eval
91
+
92
+ - name: "Path traversal from ENV to File.read"
93
+ language: ruby
94
+ code: |
95
+ path = ENV["PATH"]
96
+ File.read(path)
97
+ expect:
98
+ count: 1
99
+ flows:
100
+ - sourceId: ruby.env
101
+ sinkId: ruby.path
102
+
103
+ - name: "Path traversal sanitised by basename"
104
+ language: ruby
105
+ code: |
106
+ path = File.basename(params[:path])
107
+ File.read(path)
108
+ expect:
109
+ count: 0
110
+
111
+ - name: "URL redirection from params to redirect_to"
112
+ language: ruby
113
+ code: |
114
+ url = params[:url]
115
+ redirect_to(url)
116
+ expect:
117
+ count: 1
118
+ flows:
119
+ - sourceId: params
120
+ sinkId: ruby.url
121
+
122
+ - name: "URL redirection sanitised by url_encode"
123
+ language: ruby
124
+ code: |
125
+ url = ERB::Util.url_encode(params[:url])
126
+ redirect_to(url)
127
+ expect:
128
+ count: 0
129
+
130
+ - name: "Code execution avoided when params only logged"
131
+ language: ruby
132
+ code: |
133
+ name = params[:name]
134
+ puts(name)
135
+ expect:
136
+ count: 0
137
+
138
+ - name: "Command injection via pipe open"
139
+ language: ruby
140
+ code: |
141
+ cmd = params[:cmd]
142
+ open("|#{cmd}")
143
+ expect:
144
+ count: 1
145
+ flows:
146
+ - sourceId: params
147
+ sinkId: ruby.cmd_pipe_open
148
+
@@ -0,0 +1,233 @@
1
+ # Documented exclusion: Prototype-pollution is excluded as Ruby has no prototype chain.
2
+ # attribution: CWE-79
3
+ attribution: CWE-79
4
+ language: ruby
5
+ applies-to: []
6
+
7
+ sources:
8
+ - id: params
9
+ class: http-params
10
+ query: |
11
+ [
12
+ (identifier) @name (#eq? @name "params")
13
+ (call method: (identifier) @name (#eq? @name "params"))
14
+ ] @source
15
+
16
+ - id: cookies_or_session
17
+ class: http-params
18
+ query: |
19
+ [
20
+ (identifier) @name (#match? @name "^(cookies|session)$")
21
+ (call method: (identifier) @name (#match? @name "^(cookies|session)$"))
22
+ ] @source
23
+
24
+ - id: request.body
25
+ class: http-body
26
+ query: |
27
+ (call
28
+ receiver: (identifier) @recv (#eq? @recv "request")
29
+ method: (identifier) @method (#match? @method "^(body|raw_post)$")) @source
30
+
31
+ - id: request.headers
32
+ class: header
33
+ query: |
34
+ [
35
+ (call
36
+ receiver: (call
37
+ receiver: (identifier) @recv (#eq? @recv "request")
38
+ method: (identifier) @m1 (#eq? @m1 "headers"))
39
+ method: (identifier) @m2 (#match? @m2 "^(\\[\\]|get)$")) @source
40
+ (element_reference
41
+ object: (call
42
+ receiver: (identifier) @recv (#eq? @recv "request")
43
+ method: (identifier) @m1 (#eq? @m1 "headers"))
44
+ [(_)]) @source
45
+ ]
46
+
47
+ - id: request.env.http
48
+ class: header
49
+ query: |
50
+ (element_reference
51
+ object: (call
52
+ receiver: (identifier) @recv (#eq? @recv "request")
53
+ method: (identifier) @m (#eq? @m "env"))
54
+ [(string) @key (#match? @key "^HTTP_")])
55
+
56
+ - id: ruby.argv
57
+ class: process-argv
58
+ query: |
59
+ ((constant) @source (#eq? @source "ARGV"))
60
+
61
+ - id: ruby.env
62
+ class: env-var
63
+ query: |
64
+ ((constant) @source (#eq? @source "ENV"))
65
+
66
+ - id: ruby.file_read
67
+ class: fs-read
68
+ query: |
69
+ (call
70
+ receiver: (constant) @recv (#match? @recv "^(File|IO)$")
71
+ method: (identifier) @method (#match? @method "^(read|readlines|sysread)$")) @source
72
+
73
+ - id: ruby.net_response
74
+ class: network-response
75
+ query: |
76
+ (call
77
+ receiver: (identifier) @recv (#match? @recv "^(response|res)$")
78
+ method: (identifier) @method (#eq? @method "body")) @source
79
+
80
+ sinks:
81
+ - id: ruby.eval
82
+ sink-class: code-execution
83
+ query: |
84
+ (call
85
+ method: (identifier) @method (#match? @method "^(eval|instance_eval|class_eval)$")
86
+ arguments: (argument_list (_) @sink))
87
+
88
+ - id: rails.xss_raw
89
+ sink-class: xss
90
+ query: |
91
+ (call
92
+ method: (identifier) @method1 (#eq? @method1 "raw")
93
+ arguments: (argument_list (_) @sink))
94
+
95
+ - id: rails.xss_html_safe
96
+ sink-class: xss
97
+ query: |
98
+ (call
99
+ receiver: (_) @sink
100
+ method: (identifier) @method2 (#eq? @method2 "html_safe"))
101
+
102
+ - id: rails.xss_render_html
103
+ sink-class: xss
104
+ query: |
105
+ (call
106
+ method: (identifier) @method (#eq? @method "render")
107
+ arguments: (argument_list
108
+ (pair
109
+ key: (hash_key_symbol) @k (#match? @k "^(html|inline)$")
110
+ value: (_) @sink)))
111
+
112
+ - id: ruby.sqli_find
113
+ sink-class: sql-injection
114
+ query: |
115
+ (call
116
+ method: (identifier) @method1 (#match? @method1 "^(find_by_sql|where|select_all|find_by)$")
117
+ arguments: (argument_list (_) @sink))
118
+
119
+ - id: ruby.sqli_conn
120
+ sink-class: sql-injection
121
+ query: |
122
+ (call
123
+ receiver: (call method: (identifier) @method2 (#eq? @method2 "connection"))
124
+ method: (identifier) @method3 (#eq? @method3 "execute")
125
+ arguments: (argument_list (_) @sink))
126
+
127
+ - id: ruby.cmd_call
128
+ sink-class: command-injection
129
+ query: |
130
+ (call
131
+ method: (identifier) @method1 (#match? @method1 "^(system|exec|spawn)$")
132
+ arguments: (argument_list (_) @sink))
133
+
134
+ - id: ruby.cmd_subshell
135
+ sink-class: command-injection
136
+ query: |
137
+ (subshell) @sink
138
+
139
+ - id: ruby.cmd_pipe_open
140
+ sink-class: command-injection
141
+ query: |
142
+ (call
143
+ method: (identifier) @method (#eq? @method "open")
144
+ arguments: (argument_list
145
+ (string
146
+ (string_content) @s (#match? @s "^\\|")) @sink))
147
+
148
+ - id: ruby.path
149
+ sink-class: path-traversal
150
+ query: |
151
+ (call
152
+ receiver: (constant) @recv1 (#match? @recv1 "^(File|Dir|IO)$")
153
+ method: (identifier) @method1 (#match? @method1 "^(read|write|open|glob|delete|rmdir|mkdir)$")
154
+ arguments: (argument_list (_) @sink))
155
+
156
+ - id: ruby.path_send_file
157
+ sink-class: path-traversal
158
+ query: |
159
+ (call
160
+ method: (identifier) @method (#match? @method "^(send_file|send_data)$")
161
+ arguments: (argument_list (_) @sink))
162
+
163
+ - id: ruby.path_require
164
+ sink-class: path-traversal
165
+ query: |
166
+ (call
167
+ method: (identifier) @method2 (#match? @method2 "^(require|load)$")
168
+ arguments: (argument_list (_) @sink))
169
+
170
+ - id: ruby.url
171
+ sink-class: url-injection
172
+ query: |
173
+ (call
174
+ method: (identifier) @method (#eq? @method "redirect_to")
175
+ arguments: (argument_list (_) @sink))
176
+
177
+ sanitisers:
178
+ - id: html_escape
179
+ sanitises:
180
+ - xss
181
+ autofix-safety: global
182
+ query: |
183
+ (call
184
+ method: (identifier) @method (#match? @method "^(html_escape|escape_html|escape)$")) @sanitiser
185
+
186
+ - id: numeric_cast
187
+ sanitises:
188
+ - xss
189
+ - sql-injection
190
+ - command-injection
191
+ - path-traversal
192
+ - url-injection
193
+ query: |
194
+ (call
195
+ receiver: (_)
196
+ method: (identifier) @method (#match? @method "^(to_i|to_f)$")) @sanitiser
197
+
198
+ - id: shell_escape
199
+ sanitises:
200
+ - command-injection
201
+ query: |
202
+ (call
203
+ receiver: (constant) @recv (#eq? @recv "Shellwords")
204
+ method: (identifier) @method (#eq? @method "escape")) @sanitiser
205
+
206
+ - id: path_sanitise
207
+ sanitises:
208
+ - path-traversal
209
+ query: |
210
+ (call
211
+ method: (identifier) @method (#eq? @method "basename")) @sanitiser
212
+
213
+ - id: url_sanitise
214
+ sanitises:
215
+ - url-injection
216
+ query: |
217
+ (call
218
+ method: (identifier) @method (#match? @method "^(escape|url_encode)$")) @sanitiser
219
+
220
+ - id: sql_quote
221
+ sanitises:
222
+ - sql-injection
223
+ query: |
224
+ (call
225
+ receiver: (call method: (identifier) @m (#eq? @m "connection"))
226
+ method: (identifier) @method (#eq? @method "quote")) @sanitiser
227
+
228
+ - id: sql_sanitize_array
229
+ sanitises:
230
+ - sql-injection
231
+ query: |
232
+ (call
233
+ method: (identifier) @method (#eq? @method "sanitize_sql_array")) @sanitiser