sequel 5.83.1 → 5.84.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. checksums.yaml +4 -4
  2. data/lib/sequel/adapters/shared/sqlite.rb +3 -1
  3. data/lib/sequel/database/schema_methods.rb +2 -0
  4. data/lib/sequel/extensions/pg_json_ops.rb +328 -1
  5. data/lib/sequel/sql.rb +8 -5
  6. data/lib/sequel/version.rb +2 -2
  7. metadata +2 -236
  8. data/CHANGELOG +0 -1397
  9. data/README.rdoc +0 -936
  10. data/doc/advanced_associations.rdoc +0 -884
  11. data/doc/association_basics.rdoc +0 -1859
  12. data/doc/bin_sequel.rdoc +0 -146
  13. data/doc/cheat_sheet.rdoc +0 -255
  14. data/doc/code_order.rdoc +0 -104
  15. data/doc/core_extensions.rdoc +0 -405
  16. data/doc/dataset_basics.rdoc +0 -96
  17. data/doc/dataset_filtering.rdoc +0 -222
  18. data/doc/extensions.rdoc +0 -77
  19. data/doc/fork_safety.rdoc +0 -84
  20. data/doc/mass_assignment.rdoc +0 -98
  21. data/doc/migration.rdoc +0 -660
  22. data/doc/model_dataset_method_design.rdoc +0 -129
  23. data/doc/model_hooks.rdoc +0 -254
  24. data/doc/model_plugins.rdoc +0 -270
  25. data/doc/mssql_stored_procedures.rdoc +0 -43
  26. data/doc/object_model.rdoc +0 -563
  27. data/doc/opening_databases.rdoc +0 -439
  28. data/doc/postgresql.rdoc +0 -611
  29. data/doc/prepared_statements.rdoc +0 -144
  30. data/doc/querying.rdoc +0 -1070
  31. data/doc/reflection.rdoc +0 -120
  32. data/doc/release_notes/5.0.0.txt +0 -159
  33. data/doc/release_notes/5.1.0.txt +0 -31
  34. data/doc/release_notes/5.10.0.txt +0 -84
  35. data/doc/release_notes/5.11.0.txt +0 -83
  36. data/doc/release_notes/5.12.0.txt +0 -141
  37. data/doc/release_notes/5.13.0.txt +0 -27
  38. data/doc/release_notes/5.14.0.txt +0 -63
  39. data/doc/release_notes/5.15.0.txt +0 -39
  40. data/doc/release_notes/5.16.0.txt +0 -110
  41. data/doc/release_notes/5.17.0.txt +0 -31
  42. data/doc/release_notes/5.18.0.txt +0 -69
  43. data/doc/release_notes/5.19.0.txt +0 -28
  44. data/doc/release_notes/5.2.0.txt +0 -33
  45. data/doc/release_notes/5.20.0.txt +0 -89
  46. data/doc/release_notes/5.21.0.txt +0 -87
  47. data/doc/release_notes/5.22.0.txt +0 -48
  48. data/doc/release_notes/5.23.0.txt +0 -56
  49. data/doc/release_notes/5.24.0.txt +0 -56
  50. data/doc/release_notes/5.25.0.txt +0 -32
  51. data/doc/release_notes/5.26.0.txt +0 -35
  52. data/doc/release_notes/5.27.0.txt +0 -21
  53. data/doc/release_notes/5.28.0.txt +0 -16
  54. data/doc/release_notes/5.29.0.txt +0 -22
  55. data/doc/release_notes/5.3.0.txt +0 -121
  56. data/doc/release_notes/5.30.0.txt +0 -20
  57. data/doc/release_notes/5.31.0.txt +0 -148
  58. data/doc/release_notes/5.32.0.txt +0 -46
  59. data/doc/release_notes/5.33.0.txt +0 -24
  60. data/doc/release_notes/5.34.0.txt +0 -40
  61. data/doc/release_notes/5.35.0.txt +0 -56
  62. data/doc/release_notes/5.36.0.txt +0 -60
  63. data/doc/release_notes/5.37.0.txt +0 -30
  64. data/doc/release_notes/5.38.0.txt +0 -28
  65. data/doc/release_notes/5.39.0.txt +0 -19
  66. data/doc/release_notes/5.4.0.txt +0 -80
  67. data/doc/release_notes/5.40.0.txt +0 -40
  68. data/doc/release_notes/5.41.0.txt +0 -25
  69. data/doc/release_notes/5.42.0.txt +0 -136
  70. data/doc/release_notes/5.43.0.txt +0 -98
  71. data/doc/release_notes/5.44.0.txt +0 -32
  72. data/doc/release_notes/5.45.0.txt +0 -34
  73. data/doc/release_notes/5.46.0.txt +0 -87
  74. data/doc/release_notes/5.47.0.txt +0 -59
  75. data/doc/release_notes/5.48.0.txt +0 -14
  76. data/doc/release_notes/5.49.0.txt +0 -59
  77. data/doc/release_notes/5.5.0.txt +0 -61
  78. data/doc/release_notes/5.50.0.txt +0 -78
  79. data/doc/release_notes/5.51.0.txt +0 -47
  80. data/doc/release_notes/5.52.0.txt +0 -87
  81. data/doc/release_notes/5.53.0.txt +0 -23
  82. data/doc/release_notes/5.54.0.txt +0 -27
  83. data/doc/release_notes/5.55.0.txt +0 -21
  84. data/doc/release_notes/5.56.0.txt +0 -51
  85. data/doc/release_notes/5.57.0.txt +0 -23
  86. data/doc/release_notes/5.58.0.txt +0 -31
  87. data/doc/release_notes/5.59.0.txt +0 -73
  88. data/doc/release_notes/5.6.0.txt +0 -31
  89. data/doc/release_notes/5.60.0.txt +0 -22
  90. data/doc/release_notes/5.61.0.txt +0 -43
  91. data/doc/release_notes/5.62.0.txt +0 -132
  92. data/doc/release_notes/5.63.0.txt +0 -33
  93. data/doc/release_notes/5.64.0.txt +0 -50
  94. data/doc/release_notes/5.65.0.txt +0 -21
  95. data/doc/release_notes/5.66.0.txt +0 -24
  96. data/doc/release_notes/5.67.0.txt +0 -32
  97. data/doc/release_notes/5.68.0.txt +0 -61
  98. data/doc/release_notes/5.69.0.txt +0 -26
  99. data/doc/release_notes/5.7.0.txt +0 -108
  100. data/doc/release_notes/5.70.0.txt +0 -35
  101. data/doc/release_notes/5.71.0.txt +0 -21
  102. data/doc/release_notes/5.72.0.txt +0 -33
  103. data/doc/release_notes/5.73.0.txt +0 -66
  104. data/doc/release_notes/5.74.0.txt +0 -45
  105. data/doc/release_notes/5.75.0.txt +0 -35
  106. data/doc/release_notes/5.76.0.txt +0 -86
  107. data/doc/release_notes/5.77.0.txt +0 -63
  108. data/doc/release_notes/5.78.0.txt +0 -67
  109. data/doc/release_notes/5.79.0.txt +0 -28
  110. data/doc/release_notes/5.8.0.txt +0 -170
  111. data/doc/release_notes/5.80.0.txt +0 -40
  112. data/doc/release_notes/5.81.0.txt +0 -31
  113. data/doc/release_notes/5.82.0.txt +0 -61
  114. data/doc/release_notes/5.83.0.txt +0 -56
  115. data/doc/release_notes/5.9.0.txt +0 -99
  116. data/doc/schema_modification.rdoc +0 -679
  117. data/doc/security.rdoc +0 -443
  118. data/doc/sharding.rdoc +0 -286
  119. data/doc/sql.rdoc +0 -648
  120. data/doc/testing.rdoc +0 -204
  121. data/doc/thread_safety.rdoc +0 -15
  122. data/doc/transactions.rdoc +0 -250
  123. data/doc/validations.rdoc +0 -558
  124. data/doc/virtual_rows.rdoc +0 -265
data/doc/security.rdoc DELETED
@@ -1,443 +0,0 @@
1
- = Security Considerations with Sequel
2
-
3
- When using Sequel, there are some security areas you should be aware of:
4
-
5
- * Code Execution
6
- * SQL Injection
7
- * Denial of Service
8
- * Mass Assignment
9
- * General Parameter Handling
10
-
11
- == Code Execution
12
-
13
- The most serious security vulnerability you can have in any library is
14
- a code execution vulnerability. Sequel should not be vulnerable to this,
15
- as it never calls eval on a string that is derived from user input.
16
- However, some Sequel methods used for creating methods via metaprogramming
17
- could conceivably be abused to do so:
18
-
19
- * Sequel::Dataset.def_sql_method
20
- * Sequel::JDBC.load_driver
21
- * Sequel::Plugins.def_dataset_methods
22
- * Sequel::Dataset.prepared_statements_module (private)
23
- * Sequel::SQL::Expression.to_s_method (private)
24
-
25
- As long as you don't call those with user input, you should not be
26
- vulnerable to code execution.
27
-
28
- == SQL Injection
29
-
30
- The primary security concern in SQL database libraries is SQL injection.
31
- Because Sequel promotes using ruby objects for SQL concepts instead
32
- of raw SQL, it is less likely to be vulnerable to SQL injection.
33
- However, because Sequel still makes it easy to use raw SQL, misuse of the
34
- library can result in SQL injection in your application.
35
-
36
- There are basically two kinds of possible SQL injections in Sequel:
37
-
38
- * SQL code injections
39
- * SQL identifier injections
40
-
41
- === SQL Code Injections
42
-
43
- ==== Full SQL Strings
44
-
45
- Some Sequel methods are designed to execute raw SQL strings, including:
46
-
47
- * Sequel::Database#execute
48
- * Sequel::Database#execute_ddl
49
- * Sequel::Database#execute_dui
50
- * Sequel::Database#execute_insert
51
- * Sequel::Database#run
52
- * Sequel::Database#<<
53
- * Sequel::Dataset#fetch_rows
54
- * Sequel::Dataset#with_sql_all
55
- * Sequel::Dataset#with_sql_delete
56
- * Sequel::Dataset#with_sql_each
57
- * Sequel::Dataset#with_sql_first
58
- * Sequel::Dataset#with_sql_insert
59
- * Sequel::Dataset#with_sql_single_value
60
- * Sequel::Dataset#with_sql_update
61
-
62
- Here are some examples of use:
63
-
64
- DB.execute 'SQL'
65
- DB.execute_ddl 'SQL'
66
- DB.execute_dui 'SQL'
67
- DB.execute_insert 'SQL'
68
- DB.run 'SQL'
69
- DB << 'SQL'
70
- DB.fetch_rows('SQL'){|row| }
71
- DB.dataset.with_sql_all('SQL')
72
- DB.dataset.with_sql_delete('SQL')
73
- DB.dataset.with_sql_each('SQL'){|row| }
74
- DB.dataset.with_sql_first('SQL')
75
- DB.dataset.with_sql_insert('SQL')
76
- DB.dataset.with_sql_single_value('SQL')
77
- DB.dataset.with_sql_update('SQL')
78
-
79
- If you pass a string to these methods that is derived from user input, you open
80
- yourself up to SQL injection. These methods are not designed to work at all
81
- with user input. If you must call them with user input, you should escape the
82
- user input manually via Sequel::Database#literal. Example:
83
-
84
- DB.run "SOME SQL #{DB.literal(params[:user].to_s)}"
85
-
86
- ==== Full SQL Strings, With Possible Placeholders
87
-
88
- Other Sequel methods are designed to support execution of raw SQL strings that may contain placeholders:
89
-
90
- * Sequel::Database#[]
91
- * Sequel::Database#fetch
92
- * Sequel::Dataset#with_sql
93
-
94
- Here are some examples of use:
95
-
96
- DB['SQL'].all
97
- DB.fetch('SQL').all
98
- DB.dataset.with_sql('SQL').all
99
-
100
- With these methods you should use placeholders, in which case Sequel automatically escapes the input:
101
-
102
- DB['SELECT * FROM foo WHERE bar = ?', params[:user].to_s]
103
-
104
- ==== Manually Created Literal Strings
105
-
106
- Sequel generally treats ruby strings as SQL strings (escaping them correctly), and
107
- not as raw SQL. However, you can convert a ruby string to a literal string, and
108
- Sequel will then treat it as raw SQL. This is typically done through
109
- Sequel.lit[rdoc-ref:Sequel::SQL::Builders#lit].
110
-
111
- Sequel.lit('a')
112
-
113
- Using Sequel.lit[rdoc-ref:Sequel::SQL::Builders#lit] to turn a ruby string into a literal string results
114
- in SQL injection if the string is derived from user input. With both of these
115
- methods, the strings can contain placeholders, which you can use to safely include
116
- user input inside a literal string:
117
-
118
- Sequel.lit('a = ?', params[:user_id].to_s)
119
-
120
- Even though they have similar names, note that Sequel::Database#literal operates very differently from
121
- String#lit or Sequel.lit[rdoc-ref:Sequel::SQL::Builders#lit].
122
- Sequel::Database#literal is for taking any supported object,
123
- and getting an SQL representation of that object, while
124
- String#lit or Sequel.lit[rdoc-ref:Sequel::SQL::Builders#lit] are for treating
125
- a ruby string as raw SQL. For example:
126
-
127
- DB.literal(Date.today) # "'2013-03-22'"
128
- DB.literal('a') # "'a'"
129
- DB.literal(Sequel.lit('a')) # "a"
130
- DB.literal(a: 'a') # "(\"a\" = 'a')"
131
- DB.literal(a: Sequel.lit('a')) # "(\"a\" = a)"
132
-
133
- ==== SQL Filter Fragments
134
-
135
- Starting in Sequel 5, Sequel does not automatically convert plain strings to
136
- literal strings in typical code. Instead, you can use Sequel.lit to
137
- create literal strings:
138
-
139
- Sequel.lit("name > 'A'")
140
-
141
- To safely include user input as part of an SQL filter fragment, use Sequel.lit
142
- with placeholders:
143
-
144
- DB[:table].where(Sequel.lit("name > ?", params[:id].to_s)) # Safe
145
-
146
- Be careful to never call Sequel.lit where the first argument is derived from
147
- user input.
148
-
149
- There are a few uncommon cases where Sequel will still convert
150
- plain strings to literal strings.
151
-
152
- ==== SQL Fragment passed to Dataset#lock_style and Model#lock!
153
-
154
- The Sequel::Dataset#lock_style and Sequel::Model#lock! methods also treat
155
- an input string as SQL code. These methods should not be called with user input.
156
-
157
- DB[:table].lock_style(params[:id]) # SQL injection!
158
- Album.first.lock!(params[:id]) # SQL injection!
159
-
160
- ==== SQL Type Names
161
-
162
- In general, most places where Sequel needs to use an SQL type that should
163
- be specified by the user, it allows you to use a ruby string, and that
164
- string is used verbatim as the SQL type. You should not use user input
165
- for type strings.
166
-
167
- DB[:table].select(Sequel.cast(:a, params[:id])) # SQL injection!
168
-
169
- ==== SQL Function Names
170
-
171
- In most cases, Sequel does not quote SQL function names. You should not use
172
- user input for function names.
173
-
174
- DB[:table].select(Sequel.function(params[:id])) # SQL injection!
175
-
176
- ==== SQL Window Frames
177
-
178
- For backwards compatibility, Sequel supports regular strings in the
179
- window function :frame option, which will be treated as a literal string:
180
-
181
- DB[:table].select{fun(arg).over(frame: 'SQL Here')}
182
-
183
- You should make sure the frame argument is not derived from user input,
184
- or switch to using a hash as the :frame option value.
185
-
186
- ==== auto_literal_strings extension
187
-
188
- If the auto_literal_strings extension is used for backwards compatibility,
189
- then Sequel will treat plain strings as literal strings if they are used
190
- as the first argument to a filtering method. This can lead to SQL
191
- injection:
192
-
193
- DB[:table].where("name > #{params[:id].to_s}")
194
- # SQL injection when using auto_literal_strings extension
195
-
196
- If you are using the auto_literal_strings extension, you need to be very careful,
197
- as the following methods will treat a plain string given as the first argument
198
- as a literal string:
199
-
200
- * Sequel::Dataset#where
201
- * Sequel::Dataset#having
202
- * Sequel::Dataset#filter
203
- * Sequel::Dataset#exclude
204
- * Sequel::Dataset#exclude_having
205
- * Sequel::Dataset#or
206
- * Sequel::Dataset#first
207
- * Sequel::Dataset#last
208
- * Sequel::Dataset#[]
209
-
210
- Even stuff that looks like it may be safe isn't:
211
-
212
- DB[:table].first(params[:num_rows])
213
- # SQL injection when using auto_literal_strings extension
214
-
215
- The Model.find[rdoc-ref:Sequel::Model::ClassMethods#find] and
216
- Model.find_or_create[rdoc-ref:Sequel::Model::ClassMethods#find_or_create]
217
- class methods will also treat string arguments as literal strings if the
218
- auto_literal_strings extension is used:
219
-
220
- Album.find(params[:id])
221
- # SQL injection when using auto_literal_strings extension
222
-
223
- Similar to the filter methods, the auto_literal_strings extension
224
- also makes Sequel::Dataset#update treats a string argument as raw SQL:
225
-
226
- DB[:table].update("column = 1")
227
-
228
- So you should not do:
229
-
230
- DB[:table].update(params[:changes])
231
- # SQL injection when using auto_literal_strings extension
232
-
233
- or:
234
-
235
- DB[:table].update("column = #{params[:value].to_s}")
236
- # SQL injection when using auto_literal_strings extension
237
-
238
- Instead, you should do:
239
-
240
- DB[:table].update(column: params[:value].to_s) # Safe
241
-
242
- Because using the auto_literal_strings extension makes SQL injection
243
- so much eaiser, it is recommended to not use it, and instead
244
- use Sequel.lit with placeholders.
245
-
246
- === SQL Identifier Injections
247
-
248
- Usually, Sequel treats ruby symbols as SQL identifiers, and ruby
249
- strings as SQL strings. However, there are some parts of Sequel
250
- that treat ruby strings as SQL identifiers if an SQL string would
251
- not make sense in the same context.
252
-
253
- For example, Sequel::Database#from and Sequel::Dataset#from will treat a string as
254
- a table name:
255
-
256
- DB.from('t') # SELECT * FROM "t"
257
-
258
- Another place where Sequel treats ruby strings as identifiers are
259
- the Sequel::Dataset#insert and Sequel::Dataset#update methods:
260
-
261
- DB[:t].update('b'=>1) # UPDATE "t" SET "b" = 1
262
- DB[:t].insert('b'=>1) # INSERT INTO "t" ("b") VALUES (1)
263
-
264
- Note how the identifier is still quoted in these cases. Sequel quotes identifiers by default
265
- on most databases. However, it does not quote identifiers by default on DB2.
266
- On those databases using an identifier derived from user input can lead to SQL injection.
267
- Similarly, if you turn off identifier quoting manually on other databases, you open yourself
268
- up to SQL injection if you use identifiers derived from user input.
269
-
270
- When Sequel quotes identifiers, using an identifier derived from user input does not lead to
271
- SQL injection, since the identifiers are also escaped when quoting.
272
- Exceptions to this are Oracle (can't escape <tt>"</tt>) and Microsoft Access
273
- (can't escape <tt>]</tt>).
274
-
275
- In general, even if doesn't lead to SQL Injection, you should avoid using identifiers
276
- derived from user input unless absolutely necessary.
277
-
278
- Sequel also allows you to create identifiers using
279
- Sequel.identifier[rdoc-ref:Sequel::SQL::Builders#identifier] for plain identifiers,
280
- Sequel.qualify[rdoc-ref:Sequel::SQL::Builders#qualify] and
281
- Sequel::SQL::Indentifier#[][rdoc-ref:Sequel::SQL::QualifyingMethods#[]] for qualified identifiers, and
282
- Sequel.as[rdoc-ref:Sequel::SQL::Builders#as] for aliased expressions. So if you
283
- pass any of those values derived from user input, you are dealing with the same scenario.
284
-
285
- Note that the issues with SQL identifiers do not just apply to places where
286
- strings are used as identifiers, they also apply to all places where Sequel
287
- uses symbols as identifiers. However, if you are creating symbols from user input,
288
- you at least have a denial of service vulnerability in ruby <2.2, and possibly a
289
- more serious vulnerability.
290
-
291
- Note that many Database schema modification methods (e.g. create_table, add_column)
292
- also allow for SQL identifier injections, and possibly also SQL code injections.
293
- These methods should never be called with user input.
294
-
295
- == Denial of Service
296
-
297
- Sequel converts some strings to symbols. Because symbols in ruby <2.2 are not
298
- garbage collected, if the strings that are converted to symbols are
299
- derived from user input, you have a denial of service vulnerability due to
300
- memory exhaustion.
301
-
302
- The strings that Sequel converts to symbols are generally not derived
303
- from user input, so Sequel in general is not vulnerable to this. However,
304
- users should be aware of the cases in which Sequel creates symbols, so
305
- they do not introduce a vulnerability into their application.
306
-
307
- === Column Names/Aliases
308
-
309
- Sequel returns SQL result sets as an array of hashes with symbol keys. The
310
- keys are derived from the name that the database server gives the column. These
311
- names are generally static. For example:
312
-
313
- SELECT column FROM table
314
-
315
- The database will generally use "column" as the name in the result set.
316
-
317
- If you use an alias:
318
-
319
- SELECT column AS alias FROM table
320
-
321
- The database will generally use "alias" as the name in the result set. So
322
- if you allow the user to control the alias name:
323
-
324
- DB[:table].select(:column.as(params[:alias]))
325
-
326
- Then you can have a denial of service vulnerability. In general, such a vulnerability
327
- is unlikely, because you are probably indexing into the returned hash(es) by name,
328
- and if an alias was used and you didn't expect it, your application wouldn't work.
329
-
330
- === Database Connection Options
331
-
332
- All database connection options are converted to symbols. For a
333
- connection URL, the keys are generally fixed, but the scheme is turned
334
- into a symbol and the query option keys are used as connection option
335
- keys, so they are converted to symbols as well. For example:
336
-
337
- postgres://host/database?option1=foo&option2=bar
338
-
339
- Will result in :postgres, :option1, and :option2 symbols being created.
340
-
341
- Certain option values are also converted to symbols. In the general case,
342
- the sql_log_level option value is, but some adapters treat additional
343
- options similarly.
344
-
345
- This is not generally a risk unless you are allowing the user to control
346
- the connection URLs or are connecting to arbitrary databases at runtime.
347
-
348
- == Mass Assignment
349
-
350
- Mass assignment is the practice of passing a hash of columns and values
351
- to a single method, and having multiple column values for a given object set
352
- based on the content of the hash.
353
- The security issue here is that mass assignment may allow the user to
354
- set columns that you didn't intend to allow.
355
-
356
- The Model#set[rdoc-ref:Sequel::Model::InstanceMethods#set] and Model#update[rdoc-ref:Sequel::Model::InstanceMethods#update] methods do mass
357
- assignment. The default configuration of Sequel::Model allows all model
358
- columns except for the primary key column(s) to be set via mass assignment.
359
-
360
- Example:
361
-
362
- album = Album.new
363
- album.set(params[:album]) # Mass Assignment
364
-
365
- Both Model.new[rdoc-ref:Sequel::Model::InstanceMethods::new] and Model.create[rdoc-ref:Sequel::Model::ClassMethods#create]
366
- call Model#set[rdoc-ref:Sequel::Model::InstanceMethods#set] internally, so
367
- they also allow mass assignment:
368
-
369
- Album.new(params[:album]) # Mass Assignment
370
- Album.create(params[:album]) # Mass Assignment
371
-
372
- When the argument is derived from user input, instead of these methods, it is encouraged to either use
373
- Model#set_fields[rdoc-ref:Sequel::Model::InstanceMethods#set_fields] or
374
- Model#update_fields[rdoc-ref:Sequel::Model::InstanceMethods#update_fields],
375
- which allow you to specify which fields to allow on a per-call basis. This
376
- pretty much eliminates the chance that the user will be able to set a column
377
- you did not intend to allow:
378
-
379
- album.set_fields(params[:album], [:name, :copies_sold])
380
- album.update_fields(params[:album], [:name, :copies_sold])
381
-
382
- These two methods iterate over the second argument (+:name+ and +:copies_sold+ in
383
- this example) instead of iterating over the entries in the first argument
384
- (<tt>params[:album]</tt> in this example).
385
-
386
- If you want to override the columns that Model#set[rdoc-ref:Sequel::Model::InstanceMethods#set]
387
- allows by default during mass assignment, you can use the whitelist_security plugin, then call
388
- the set_allowed_columns class method.
389
-
390
- Album.plugin :whitelist_security
391
- Album.set_allowed_columns(:name, :copies_sold)
392
- Album.create(params[:album]) # Only name and copies_sold set
393
-
394
- Being explicit on a per-call basis using the set_fields and update_fields methods is recommended
395
- instead of using the whitelist_security plugin and setting a global whitelist.
396
-
397
- For more details on the mass assignment methods, see the {Mass Assignment Guide}[rdoc-ref:doc/mass_assignment.rdoc].
398
-
399
- == General Parameter Handling
400
-
401
- This issue isn't necessarily specific to Sequel, but it is a good general practice.
402
- If you are using values derived from user input, it is best to be explicit about
403
- their type. For example:
404
-
405
- Album.where(id: params[:id])
406
-
407
- is probably a bad idea. Assuming you are using a web framework, <tt>params[:id]</tt> could
408
- be a string, an array, a hash, nil, or potentially something else.
409
-
410
- Assuming that +id+ is an integer field, you probably want to do:
411
-
412
- Album.where(id: params[:id].to_i)
413
-
414
- If you are looking something up by name, you should try to enforce the value to be
415
- a string:
416
-
417
- Album.where(name: params[:name].to_s)
418
-
419
- If you are trying to use an IN clause with a list of id values based on input provided
420
- on a web form:
421
-
422
- Album.where(id: params[:ids].to_a.map(&:to_i))
423
-
424
- Basically, be as explicit as possible. While there aren't any known security issues
425
- in Sequel when you do:
426
-
427
- Album.where(id: params[:id])
428
-
429
- It allows the attacker to choose to do any of the following queries:
430
-
431
- id IS NULL # nil
432
- id = '1' # '1'
433
- id IN ('1', '2', '3') # ['1', '2', '3']
434
- id = ('a' = 'b') # {'a'=>'b'}
435
- id = ('a' IN ('a', 'b') AND 'c' = '') # {'a'=>['a', 'b'], 'c'=>''}
436
-
437
- While none of those allow for SQL injection, it's possible that they
438
- might have an issue in your application. For example, a long array
439
- or deeply nested hash might cause the database to have to do a lot of
440
- work that could be avoided.
441
-
442
- In general, it's best to let the attacker control as little as possible,
443
- and explicitly specifying types helps a great deal there.