ronin-sql 0.2.4 → 1.0.0

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 (154) hide show
  1. data/.document +4 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +1 -0
  4. data/.yardopts +1 -0
  5. data/COPYING.txt +623 -288
  6. data/{History.txt → ChangeLog.md} +33 -35
  7. data/Gemfile +25 -0
  8. data/README.md +110 -0
  9. data/Rakefile +30 -20
  10. data/bin/ronin-sql +18 -5
  11. data/gemspec.yml +16 -0
  12. data/lib/ronin/formatting/extensions/sql.rb +4 -3
  13. data/lib/ronin/formatting/extensions/sql/string.rb +83 -10
  14. data/lib/ronin/formatting/sql.rb +4 -3
  15. data/lib/ronin/sql.rb +5 -12
  16. data/lib/ronin/{code/sql/create_index.rb → sql/binary_expr.rb} +25 -18
  17. data/lib/ronin/sql/clause.rb +72 -0
  18. data/lib/ronin/sql/clauses.rb +297 -0
  19. data/lib/ronin/sql/emittable.rb +84 -0
  20. data/lib/ronin/sql/emitter.rb +375 -0
  21. data/lib/ronin/sql/field.rb +106 -0
  22. data/lib/ronin/{code/sql/as.rb → sql/fields.rb} +36 -17
  23. data/lib/ronin/{code/sql/binary_expr.rb → sql/function.rb} +27 -27
  24. data/lib/ronin/sql/functions.rb +989 -0
  25. data/lib/ronin/sql/injection.rb +125 -157
  26. data/lib/ronin/{code/sql/default_values_clause.rb → sql/literal.rb} +13 -11
  27. data/lib/ronin/sql/literals.rb +72 -0
  28. data/lib/ronin/sql/operators.rb +332 -0
  29. data/lib/ronin/sql/sql.rb +86 -0
  30. data/lib/ronin/sql/statement.rb +70 -0
  31. data/lib/ronin/sql/statement_list.rb +110 -0
  32. data/lib/ronin/sql/statements.rb +115 -0
  33. data/lib/ronin/{code/sql/desc.rb → sql/unary_expr.rb} +11 -11
  34. data/lib/ronin/sql/version.rb +5 -4
  35. data/ronin-sql.gemspec +61 -0
  36. data/spec/formatting/sql/string_spec.rb +172 -0
  37. data/spec/spec_helper.rb +1 -4
  38. data/spec/sql/binary_expr.rb +5 -0
  39. data/spec/sql/binary_expr_examples.rb +25 -0
  40. data/spec/sql/clause_examples.rb +43 -0
  41. data/spec/sql/clause_spec.rb +31 -0
  42. data/spec/sql/clauses_spec.rb +43 -0
  43. data/spec/sql/emittable_spec.rb +41 -0
  44. data/spec/sql/emitter_spec.rb +472 -0
  45. data/spec/sql/field_spec.rb +103 -0
  46. data/spec/sql/fields_spec.rb +40 -0
  47. data/spec/sql/function_examples.rb +30 -0
  48. data/spec/sql/function_spec.rb +25 -0
  49. data/spec/sql/functions_spec.rb +110 -0
  50. data/spec/sql/injection_spec.rb +233 -0
  51. data/spec/sql/literal_spec.rb +5 -0
  52. data/spec/sql/literals_spec.rb +46 -0
  53. data/spec/sql/operators_spec.rb +44 -0
  54. data/spec/sql/sql_spec.rb +18 -0
  55. data/spec/sql/statement_examples.rb +39 -0
  56. data/spec/sql/statement_list_spec.rb +48 -0
  57. data/spec/sql/statement_sql.rb +38 -0
  58. data/spec/sql/statements_spec.rb +22 -0
  59. data/spec/sql/unary_expr.rb +5 -0
  60. data/spec/sql/unary_expr_examples.rb +20 -0
  61. metadata +116 -217
  62. data.tar.gz.sig +0 -0
  63. data/Manifest.txt +0 -108
  64. data/README.txt +0 -112
  65. data/lib/ronin/code/sql.rb +0 -22
  66. data/lib/ronin/code/sql/add_column_clause.rb +0 -42
  67. data/lib/ronin/code/sql/alter_table.rb +0 -52
  68. data/lib/ronin/code/sql/asc.rb +0 -36
  69. data/lib/ronin/code/sql/between.rb +0 -66
  70. data/lib/ronin/code/sql/clause.rb +0 -35
  71. data/lib/ronin/code/sql/code.rb +0 -35
  72. data/lib/ronin/code/sql/common_dialect.rb +0 -66
  73. data/lib/ronin/code/sql/create.rb +0 -74
  74. data/lib/ronin/code/sql/create_table.rb +0 -44
  75. data/lib/ronin/code/sql/create_view.rb +0 -41
  76. data/lib/ronin/code/sql/delete.rb +0 -52
  77. data/lib/ronin/code/sql/dialect.rb +0 -282
  78. data/lib/ronin/code/sql/drop.rb +0 -55
  79. data/lib/ronin/code/sql/drop_index.rb +0 -41
  80. data/lib/ronin/code/sql/drop_table.rb +0 -41
  81. data/lib/ronin/code/sql/drop_view.rb +0 -41
  82. data/lib/ronin/code/sql/emittable.rb +0 -100
  83. data/lib/ronin/code/sql/exceptions.rb +0 -24
  84. data/lib/ronin/code/sql/exceptions/unknown_clause.rb +0 -29
  85. data/lib/ronin/code/sql/exceptions/unknown_dialect.rb +0 -29
  86. data/lib/ronin/code/sql/exceptions/unknown_statement.rb +0 -29
  87. data/lib/ronin/code/sql/expr.rb +0 -102
  88. data/lib/ronin/code/sql/field.rb +0 -101
  89. data/lib/ronin/code/sql/fields_clause.rb +0 -46
  90. data/lib/ronin/code/sql/from_clause.rb +0 -42
  91. data/lib/ronin/code/sql/function.rb +0 -53
  92. data/lib/ronin/code/sql/group_by_clause.rb +0 -46
  93. data/lib/ronin/code/sql/having_clause.rb +0 -46
  94. data/lib/ronin/code/sql/in.rb +0 -47
  95. data/lib/ronin/code/sql/injected_statement.rb +0 -100
  96. data/lib/ronin/code/sql/injection.rb +0 -203
  97. data/lib/ronin/code/sql/insert.rb +0 -54
  98. data/lib/ronin/code/sql/intersect_clause.rb +0 -42
  99. data/lib/ronin/code/sql/join_clause.rb +0 -123
  100. data/lib/ronin/code/sql/like.rb +0 -73
  101. data/lib/ronin/code/sql/limit_clause.rb +0 -42
  102. data/lib/ronin/code/sql/modifier.rb +0 -48
  103. data/lib/ronin/code/sql/offset_clause.rb +0 -42
  104. data/lib/ronin/code/sql/on_clause.rb +0 -55
  105. data/lib/ronin/code/sql/order_by_clause.rb +0 -42
  106. data/lib/ronin/code/sql/program.rb +0 -225
  107. data/lib/ronin/code/sql/rename_to_clause.rb +0 -42
  108. data/lib/ronin/code/sql/replace.rb +0 -54
  109. data/lib/ronin/code/sql/select.rb +0 -103
  110. data/lib/ronin/code/sql/set_clause.rb +0 -42
  111. data/lib/ronin/code/sql/statement.rb +0 -180
  112. data/lib/ronin/code/sql/token.rb +0 -62
  113. data/lib/ronin/code/sql/unary_expr.rb +0 -47
  114. data/lib/ronin/code/sql/union_all_clause.rb +0 -42
  115. data/lib/ronin/code/sql/union_clause.rb +0 -42
  116. data/lib/ronin/code/sql/update.rb +0 -52
  117. data/lib/ronin/code/sql/values_clause.rb +0 -46
  118. data/lib/ronin/code/sql/where_clause.rb +0 -42
  119. data/lib/ronin/sql/error.rb +0 -26
  120. data/lib/ronin/sql/error/error.rb +0 -62
  121. data/lib/ronin/sql/error/extensions.rb +0 -22
  122. data/lib/ronin/sql/error/extensions/string.rb +0 -77
  123. data/lib/ronin/sql/error/message.rb +0 -62
  124. data/lib/ronin/sql/error/pattern.rb +0 -104
  125. data/lib/ronin/sql/error/patterns.rb +0 -99
  126. data/lib/ronin/sql/extensions.rb +0 -22
  127. data/lib/ronin/sql/extensions/uri.rb +0 -22
  128. data/lib/ronin/sql/extensions/uri/http.rb +0 -107
  129. data/spec/code/sql/common_dialect_spec.rb +0 -205
  130. data/spec/code/sql/create_examples.rb +0 -19
  131. data/spec/code/sql/create_index_spec.rb +0 -25
  132. data/spec/code/sql/create_table_spec.rb +0 -27
  133. data/spec/code/sql/create_view_spec.rb +0 -16
  134. data/spec/code/sql/delete_spec.rb +0 -14
  135. data/spec/code/sql/drop_examples.rb +0 -10
  136. data/spec/code/sql/drop_index_spec.rb +0 -16
  137. data/spec/code/sql/drop_table_spec.rb +0 -16
  138. data/spec/code/sql/drop_view_spec.rb +0 -16
  139. data/spec/code/sql/has_default_values_clause_examples.rb +0 -10
  140. data/spec/code/sql/has_fields_clause_examples.rb +0 -15
  141. data/spec/code/sql/has_from_clause_examples.rb +0 -13
  142. data/spec/code/sql/has_values_clause_examples.rb +0 -15
  143. data/spec/code/sql/has_where_clause_examples.rb +0 -15
  144. data/spec/code/sql/insert_spec.rb +0 -21
  145. data/spec/code/sql/replace_spec.rb +0 -21
  146. data/spec/code/sql/select_spec.rb +0 -105
  147. data/spec/code/sql/update_spec.rb +0 -26
  148. data/spec/helpers/code.rb +0 -14
  149. data/spec/sql/error_spec.rb +0 -24
  150. data/spec/sql/extensions/uri/http_spec.rb +0 -34
  151. data/spec/sql_spec.rb +0 -9
  152. data/tasks/spec.rb +0 -10
  153. data/tasks/yard.rb +0 -13
  154. metadata.gz.sig +0 -0
@@ -0,0 +1,84 @@
1
+ #
2
+ # Ronin SQL - A Ruby DSL for crafting SQL Injections.
3
+ #
4
+ # Copyright (c) 2007-2013 Hal Brodigan (postmodern.mod3 at gmail.com)
5
+ #
6
+ # This file is part of Ronin SQL.
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation; either version 2 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # This program is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with this program; if not, write to the Free Software
20
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
+ #
22
+
23
+ require 'ronin/sql/emitter'
24
+
25
+ module Ronin
26
+ module SQL
27
+ #
28
+ # Allows an object to be converted to raw SQL.
29
+ #
30
+ module Emittable
31
+ #
32
+ # Creates a new emitter.
33
+ #
34
+ # @param [Hash] options
35
+ # Additional options for {Emitter#initialize}.
36
+ #
37
+ def emitter(options={})
38
+ Emitter.new(options)
39
+ end
40
+
41
+ #
42
+ # The default `to_sql` method.
43
+ #
44
+ # @param [Hash] options
45
+ # Additional options for {#emitter}.
46
+ #
47
+ # @option options [:lower, :upper, :random, nil] :case
48
+ # Case for keywords.
49
+ #
50
+ # @option options [String] :space (' ')
51
+ # String to use for white-space.
52
+ #
53
+ # @option options [:single, :double] :quotes (:single)
54
+ # Type of quotes to use for Strings.
55
+ #
56
+ # @return [String]
57
+ # The raw SQL.
58
+ #
59
+ # @raise [ArgumentError]
60
+ # Could not emit an unknown SQL object.
61
+ #
62
+ def to_sql(options={})
63
+ emitter(options).emit(self)
64
+ end
65
+
66
+ #
67
+ # @see #to_sql
68
+ #
69
+ def to_s
70
+ to_sql
71
+ end
72
+
73
+ #
74
+ # Inspects the object.
75
+ #
76
+ # @return [String]
77
+ # The inspected object.
78
+ #
79
+ def inspect
80
+ "#<#{self.class}: #{to_sql}>"
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,375 @@
1
+ #
2
+ # Ronin SQL - A Ruby DSL for crafting SQL Injections.
3
+ #
4
+ # Copyright (c) 2007-2013 Hal Brodigan (postmodern.mod3 at gmail.com)
5
+ #
6
+ # This file is part of Ronin SQL.
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation; either version 2 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # This program is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with this program; if not, write to the Free Software
20
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
+ #
22
+
23
+ require 'ronin/formatting/sql'
24
+
25
+ module Ronin
26
+ module SQL
27
+ #
28
+ # Generates raw SQL.
29
+ #
30
+ class Emitter
31
+
32
+ # The case to use when emitting keywords
33
+ attr_reader :case
34
+
35
+ # String to use for white-space
36
+ attr_reader :space
37
+
38
+ # Type of String quotes to use
39
+ attr_reader :quotes
40
+
41
+ #
42
+ # Initializes the SQL Emitter.
43
+ #
44
+ # @param [Hash] options
45
+ # Emitter options.
46
+ #
47
+ # @option options [:lower, :upper, :random, nil] :case
48
+ # Case for keywords.
49
+ #
50
+ # @option options [String] :space (' ')
51
+ # String to use for white-space.
52
+ #
53
+ # @option options [:single, :double] :quotes (:single)
54
+ # Type of quotes to use for Strings.
55
+ #
56
+ def initialize(options={})
57
+ @case = options[:case]
58
+ @space = options.fetch(:space,' ')
59
+ @quotes = options.fetch(:quotes,:single)
60
+ end
61
+
62
+ #
63
+ # Emits a SQL keyword.
64
+ #
65
+ # @param [Symbol, Array<Symbol>] keyword
66
+ # The SQL keyword.
67
+ #
68
+ # @return [String]
69
+ # The raw SQL.
70
+ #
71
+ def emit_keyword(keyword)
72
+ keyword = Array(keyword).join(@space)
73
+
74
+ case @case
75
+ when :upper then keyword.upcase
76
+ when :lower then keyword.downcase
77
+ when :random
78
+ keyword.tap do
79
+ (keyword.length / 2).times do
80
+ index = rand(keyword.length)
81
+ keyword[index] = keyword[index].swapcase
82
+ end
83
+ end
84
+ else
85
+ keyword
86
+ end
87
+ end
88
+
89
+ #
90
+ # Emits a SQL operator.
91
+ #
92
+ # @param [Symbol] op
93
+ # The operator symbol.
94
+ #
95
+ # @return [String]
96
+ # The raw SQL.
97
+ #
98
+ def emit_operator(op)
99
+ op = op.to_s
100
+
101
+ case op
102
+ when /^[a-zA-Z]+$/ then emit_keyword(op)
103
+ else op
104
+ end
105
+ end
106
+
107
+ #
108
+ # Emits the `NULL` value.
109
+ #
110
+ # @return ["NULL"]
111
+ #
112
+ def emit_null
113
+ emit_keyword(:NULL)
114
+ end
115
+
116
+ #
117
+ # Emits a `false` value.
118
+ #
119
+ # @return [String]
120
+ # The raw SQL.
121
+ #
122
+ def emit_false
123
+ "1=0"
124
+ end
125
+
126
+ #
127
+ # Emits a `true` value.
128
+ #
129
+ # @return [String]
130
+ # The raw SQL.
131
+ #
132
+ def emit_true
133
+ "1=1"
134
+ end
135
+
136
+ #
137
+ # Emits a SQL Integer.
138
+ #
139
+ # @param [Integer] int
140
+ # The Integer.
141
+ #
142
+ # @return [String]
143
+ # The raw SQL.
144
+ #
145
+ def emit_integer(int)
146
+ int.to_s
147
+ end
148
+
149
+ #
150
+ # Emits a SQL Decimal.
151
+ #
152
+ # @param [Float] decimal
153
+ # The decimal.
154
+ #
155
+ # @return [String]
156
+ # The raw SQL.
157
+ #
158
+ def emit_decimal(decimal)
159
+ decimal.to_s
160
+ end
161
+
162
+ #
163
+ # Emits a SQL String.
164
+ #
165
+ # @param [String] string
166
+ # The String.
167
+ #
168
+ # @return [String]
169
+ # The raw SQL.
170
+ #
171
+ def emit_string(string)
172
+ string.sql_escape(@quotes)
173
+ end
174
+
175
+ #
176
+ # Emits a SQL field.
177
+ #
178
+ # @param [Field, Symbol, String] field
179
+ # The SQL field.
180
+ #
181
+ # @return [String]
182
+ # The raw SQL.
183
+ #
184
+ def emit_field(field)
185
+ field.to_s
186
+ end
187
+
188
+ #
189
+ # Emits a list of elements.
190
+ #
191
+ # @param [#map] list
192
+ # The list of elements.
193
+ #
194
+ # @return [String]
195
+ # The raw SQL.
196
+ #
197
+ def emit_list(list)
198
+ '(' + list.map { |element| emit(element) }.join(',') + ')'
199
+ end
200
+
201
+ #
202
+ # Emits a list of columns and assigned values.
203
+ #
204
+ # @param [Hash{Field,Symbol => Object}] values
205
+ # The column names and values.
206
+ #
207
+ # @return [String]
208
+ # The raw SQL.
209
+ #
210
+ def emit_assignments(values)
211
+ values.map { |key,value|
212
+ "#{emit_keyword(key)}=#{emit(value)}"
213
+ }.join(',')
214
+ end
215
+
216
+ #
217
+ # Emits a SQL expression.
218
+ #
219
+ # @param [BinaryExpr, UnaryExpr] expr
220
+ # The SQL expression.
221
+ #
222
+ # @return [String]
223
+ # The raw SQL.
224
+ #
225
+ def emit_expression(expr)
226
+ op = emit_operator(expr.operator)
227
+
228
+ case expr
229
+ when BinaryExpr
230
+ left, right = emit(expr.left), emit(expr.right)
231
+
232
+ left = "(#{left})" if expr.left.kind_of?(Statement)
233
+ right = "(#{right})" if expr.right.kind_of?(Statement)
234
+
235
+ case op
236
+ when /^\w+$/ then [left, op, right].join(@space)
237
+ else "#{left}#{op}#{right}"
238
+ end
239
+ when UnaryExpr
240
+ operand = emit(expr.operand)
241
+ operand = "(#{operand})" if expr.operand.kind_of?(Statement)
242
+
243
+ case op
244
+ when /^\w+$/ then [op, operand].join(@space)
245
+ else "#{op}#{operand}"
246
+ end
247
+ end
248
+ end
249
+
250
+ #
251
+ # Emits a SQL function.
252
+ #
253
+ # @param [Function] function
254
+ # The SQL function.
255
+ #
256
+ # @return [String]
257
+ # The raw SQL.
258
+ #
259
+ def emit_function(function)
260
+ name = emit_keyword(function.name)
261
+ arguments = function.arguments.map { |argument| emit(argument) }
262
+
263
+ return "#{name}(#{arguments.join(',')})"
264
+ end
265
+
266
+ #
267
+ # Emits a SQL object.
268
+ #
269
+ # @param [#to_sql] object
270
+ # The SQL object.
271
+ #
272
+ # @return [String]
273
+ # The raw SQL.
274
+ #
275
+ # @raise [ArgumentError]
276
+ # Could not emit an unknown SQL object.
277
+ #
278
+ def emit(object)
279
+ case object
280
+ when NilClass then emit_null
281
+ when TrueClass then emit_true
282
+ when FalseClass then emit_false
283
+ when Integer then emit_integer(object)
284
+ when Float then emit_decimal(object)
285
+ when String then emit_string(object)
286
+ when Literal then emit(object.value)
287
+ when Field, Symbol then emit_field(object)
288
+ when Array then emit_list(object)
289
+ when Hash then emit_assignments(object)
290
+ when BinaryExpr, UnaryExpr then emit_expression(object)
291
+ when Clause then emit_clause(object)
292
+ when Statement then emit_statement(object)
293
+ when StatementList then emit_statement_list(object)
294
+ else
295
+ if object.respond_to?(:to_sql)
296
+ object.to_sql
297
+ else
298
+ raise(ArgumentError,"cannot emit #{object.class}")
299
+ end
300
+ end
301
+ end
302
+
303
+ #
304
+ # Emits a SQL Clause.
305
+ #
306
+ # @param [Clause] clause
307
+ # The SQL Clause.
308
+ #
309
+ # @return [String]
310
+ # The raw SQL.
311
+ #
312
+ def emit_clause(clause)
313
+ sql = emit_keyword(clause.keyword)
314
+
315
+ unless clause.argument.nil?
316
+ sql << @space << emit(clause.argument)
317
+ end
318
+
319
+ return sql
320
+ end
321
+
322
+ #
323
+ # Emits multiple SQL Clauses.
324
+ #
325
+ # @param [Array<Clause>] clauses
326
+ # The clauses to emit.
327
+ #
328
+ # @return [String]
329
+ # The emitted clauses.
330
+ #
331
+ def emit_clauses(clauses)
332
+ clauses.map { |clause| emit_clause(clause) }.join(@space)
333
+ end
334
+
335
+ #
336
+ # Emits a SQL Statement.
337
+ #
338
+ # @param [Statement] stmt
339
+ # The SQL Statement.
340
+ #
341
+ # @return [String]
342
+ # The raw SQL.
343
+ #
344
+ def emit_statement(stmt)
345
+ sql = emit_keyword(stmt.keyword)
346
+
347
+ unless stmt.argument.nil?
348
+ sql << @space << emit(stmt.argument)
349
+ end
350
+
351
+ unless stmt.clauses.empty?
352
+ sql << @space << emit_clauses(stmt.clauses)
353
+ end
354
+
355
+ return sql
356
+ end
357
+
358
+ #
359
+ # Emits a full SQL statement list.
360
+ #
361
+ # @param [StatementList] list
362
+ # The SQL statement list.
363
+ #
364
+ # @return [String]
365
+ # The raw SQL.
366
+ #
367
+ def emit_statement_list(list)
368
+ list.statements.map { |stmt|
369
+ emit_statement(stmt)
370
+ }.join(";#{@space}")
371
+ end
372
+
373
+ end
374
+ end
375
+ end