ronin-code-sql 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/.document +4 -0
  3. data/.editorconfig +11 -0
  4. data/.github/workflows/ruby.yml +27 -0
  5. data/.gitignore +11 -0
  6. data/.mailmap +1 -0
  7. data/.rspec +1 -0
  8. data/.ruby-version +1 -0
  9. data/.yardopts +1 -0
  10. data/COPYING.txt +165 -0
  11. data/ChangeLog.md +104 -0
  12. data/Gemfile +28 -0
  13. data/README.md +212 -0
  14. data/Rakefile +30 -0
  15. data/gemspec.yml +25 -0
  16. data/lib/ronin/code/sql/binary_expr.rb +53 -0
  17. data/lib/ronin/code/sql/clause.rb +74 -0
  18. data/lib/ronin/code/sql/clauses.rb +310 -0
  19. data/lib/ronin/code/sql/emittable.rb +88 -0
  20. data/lib/ronin/code/sql/emitter.rb +406 -0
  21. data/lib/ronin/code/sql/field.rb +110 -0
  22. data/lib/ronin/code/sql/fields.rb +82 -0
  23. data/lib/ronin/code/sql/function.rb +53 -0
  24. data/lib/ronin/code/sql/functions.rb +1265 -0
  25. data/lib/ronin/code/sql/injection.rb +168 -0
  26. data/lib/ronin/code/sql/injection_expr.rb +113 -0
  27. data/lib/ronin/code/sql/literal.rb +40 -0
  28. data/lib/ronin/code/sql/literals.rb +83 -0
  29. data/lib/ronin/code/sql/operators.rb +384 -0
  30. data/lib/ronin/code/sql/statement.rb +72 -0
  31. data/lib/ronin/code/sql/statement_list.rb +112 -0
  32. data/lib/ronin/code/sql/statements.rb +117 -0
  33. data/lib/ronin/code/sql/unary_expr.rb +38 -0
  34. data/lib/ronin/code/sql/version.rb +28 -0
  35. data/lib/ronin/code/sql.rb +96 -0
  36. data/ronin-code-sql.gemspec +62 -0
  37. data/spec/spec_helper.rb +3 -0
  38. data/spec/sql/binary_expr_examples.rb +25 -0
  39. data/spec/sql/binary_expr_spec.rb +5 -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 +47 -0
  43. data/spec/sql/emittable_spec.rb +41 -0
  44. data/spec/sql/emitter_spec.rb +533 -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 +113 -0
  50. data/spec/sql/injection_expr_spec.rb +98 -0
  51. data/spec/sql/injection_spec.rb +172 -0
  52. data/spec/sql/literal_spec.rb +5 -0
  53. data/spec/sql/literals_spec.rb +46 -0
  54. data/spec/sql/operators_spec.rb +44 -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_spec.rb +38 -0
  58. data/spec/sql/statements_spec.rb +22 -0
  59. data/spec/sql/unary_expr_examples.rb +20 -0
  60. data/spec/sql/unary_expr_spec.rb +5 -0
  61. data/spec/sql_spec.rb +18 -0
  62. metadata +157 -0
@@ -0,0 +1,168 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-code-sql - A Ruby DSL for crafting SQL Injections.
4
+ #
5
+ # Copyright (c) 2007-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # ronin-code-sql is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-code-sql is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-code-sql. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/code/sql/literals'
22
+ require 'ronin/code/sql/clauses'
23
+ require 'ronin/code/sql/injection_expr'
24
+ require 'ronin/code/sql/statement_list'
25
+
26
+ module Ronin
27
+ module Code
28
+ module SQL
29
+ #
30
+ # Represents a SQL injection (SQLi).
31
+ #
32
+ # @api public
33
+ #
34
+ # @see http://en.wikipedia.org/wiki/SQL_injection
35
+ #
36
+ class Injection < StatementList
37
+
38
+ include Literals
39
+ include Clauses
40
+
41
+ # Default place holder values.
42
+ PLACE_HOLDERS = {
43
+ integer: 1,
44
+ decimal: 1.0,
45
+ string: '1',
46
+ list: [nil],
47
+ column: :id
48
+ }
49
+
50
+ # The type of element to escape out of
51
+ #
52
+ # @return [:integer, :decimal, :string, :column]
53
+ attr_reader :escape
54
+
55
+ # The expression that will be injected
56
+ #
57
+ # @return [InjectionExpr]
58
+ attr_reader :expression
59
+
60
+ #
61
+ # Initializes a new SQL injection.
62
+ #
63
+ # @param [:integer, :decimal, :string, :column] escape
64
+ # The type of element to escape out of.
65
+ #
66
+ # @param [String, Symbol, Integer] place_holder
67
+ # Place-holder data.
68
+ #
69
+ # @yield [(injection)]
70
+ # If a block is given, it will be evaluated within the injection.
71
+ # If the block accepts an argument, the block will be called with the
72
+ # new injection.
73
+ #
74
+ # @yieldparam [Injection] injection
75
+ # The new injection.
76
+ #
77
+ def initialize(escape: :integer,
78
+ place_holder: PLACE_HOLDERS.fetch(escape),
79
+ &block)
80
+ @escape = escape
81
+ @expression = InjectionExpr.new(place_holder)
82
+
83
+ super(&block)
84
+ end
85
+
86
+ #
87
+ # Appends an `AND` expression to the injection.
88
+ #
89
+ # @yield [(expr)]
90
+ # The return value of the block will be used as the right-hand side
91
+ # operand. If the block accepts an argument, it will be called with
92
+ # the injection.
93
+ #
94
+ # @yieldparam [InjectionExpr] expr
95
+ #
96
+ # @return [self]
97
+ #
98
+ def and(&block)
99
+ @expression.and(&block)
100
+ return self
101
+ end
102
+
103
+ #
104
+ # Appends an `OR` expression to the injection.
105
+ #
106
+ # @yield [(expr)]
107
+ # The return value of the block will be used as the right-hand side
108
+ # operand. If the block accepts an argument, it will be called with
109
+ # the injection expression.
110
+ #
111
+ # @yieldparam [InjectionExpr] expr
112
+ #
113
+ # @return [self]
114
+ #
115
+ def or(&block)
116
+ @expression.or(&block)
117
+ return self
118
+ end
119
+
120
+ #
121
+ # Converts the SQL injection to SQL.
122
+ #
123
+ # @param [Boolean] terminate
124
+ # Specifies whether to terminate the injection with `;--`.
125
+ #
126
+ # @param [Hash{Symbol => Object}] kwargs
127
+ # Additional keyword arguments for {Emitter#initialize}.
128
+ #
129
+ # @return [String]
130
+ # The raw SQL.
131
+ #
132
+ def to_sql(terminate: false, **kwargs)
133
+ emitter = emitter(**kwargs)
134
+ sql = @expression.to_sql(**kwargs)
135
+
136
+ unless clauses.empty?
137
+ sql << emitter.space << emitter.emit_clauses(clauses)
138
+ end
139
+
140
+ unless statements.empty?
141
+ sql << ';' << emitter.space << emitter.emit_statement_list(self)
142
+ end
143
+
144
+ case @escape
145
+ when :string, :list
146
+ if (terminate || (sql[0,1] != sql[-1,1]))
147
+ # terminate the expression
148
+ sql << ';--'
149
+ else
150
+ sql = sql[0..-2]
151
+ end
152
+
153
+ # balance the quotes
154
+ sql = sql[1..-1]
155
+ else
156
+ if terminate
157
+ # terminate the expression
158
+ sql << ';--'
159
+ end
160
+ end
161
+
162
+ return sql
163
+ end
164
+
165
+ end
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-code-sql - A Ruby DSL for crafting SQL Injections.
4
+ #
5
+ # Copyright (c) 2007-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # ronin-code-sql is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-code-sql is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-code-sql. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/code/sql/binary_expr'
22
+ require 'ronin/code/sql/literals'
23
+ require 'ronin/code/sql/fields'
24
+ require 'ronin/code/sql/functions'
25
+ require 'ronin/code/sql/statements'
26
+ require 'ronin/code/sql/emittable'
27
+
28
+ module Ronin
29
+ module Code
30
+ module SQL
31
+ #
32
+ # @api private
33
+ #
34
+ # @since 1.1.0
35
+ #
36
+ class InjectionExpr
37
+
38
+ include Literals
39
+ include Fields
40
+ include Functions
41
+ include Statements
42
+ include Emittable
43
+
44
+ # The expression that will be injected
45
+ attr_reader :expression
46
+
47
+ #
48
+ # Initializes the new expression to inject.
49
+ #
50
+ # @param [String, Integer, Float, Array, Symbol] initial_value
51
+ # The initial value for the expression.
52
+ #
53
+ def initialize(initial_value)
54
+ @expression = initial_value
55
+ end
56
+
57
+ #
58
+ # Appends an `AND` expression to the injection.
59
+ #
60
+ # @yield [(self)]
61
+ # The return value of the block will be used as the right-hand side
62
+ # operand. If the block accepts an argument, it will be called with
63
+ # the injection expression.
64
+ #
65
+ # @return [self]
66
+ #
67
+ def and(&block)
68
+ value = case block.arity
69
+ when 0 then instance_eval(&block)
70
+ else block.call(self)
71
+ end
72
+
73
+ @expression = BinaryExpr.new(@expression,:AND,value)
74
+ return self
75
+ end
76
+
77
+ #
78
+ # Appends an `OR` expression to the injection.
79
+ #
80
+ # @yield [(self)]
81
+ # The return value of the block will be used as the right-hand side
82
+ # operand. If the block accepts an argument, it will be called with
83
+ # the injection expression.
84
+ #
85
+ # @return [self]
86
+ #
87
+ def or(&block)
88
+ value = case block.arity
89
+ when 0 then instance_eval(&block)
90
+ else block.call(self)
91
+ end
92
+
93
+ @expression = BinaryExpr.new(@expression,:OR,value)
94
+ return self
95
+ end
96
+
97
+ #
98
+ # Emits the injection expression.
99
+ #
100
+ # @param [Hash{Symbol => Object}] kwargs
101
+ # Additional keyword arguments for {Emitter#initialize}.
102
+ #
103
+ # @return [String]
104
+ # The raw SQL.
105
+ #
106
+ def to_sql(**kwargs)
107
+ emitter(**kwargs).emit(@expression)
108
+ end
109
+
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-code-sql - A Ruby DSL for crafting SQL Injections.
4
+ #
5
+ # Copyright (c) 2007-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # ronin-code-sql is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-code-sql is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-code-sql. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/code/sql/emittable'
22
+ require 'ronin/code/sql/operators'
23
+
24
+ module Ronin
25
+ module Code
26
+ module SQL
27
+ #
28
+ # Represents SQL literals.
29
+ #
30
+ # @api semipublic
31
+ #
32
+ class Literal < Struct.new(:value)
33
+
34
+ include Operators
35
+ include Emittable
36
+
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-code-sql - A Ruby DSL for crafting SQL Injections.
4
+ #
5
+ # Copyright (c) 2007-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # ronin-code-sql is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-code-sql is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-code-sql. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/code/sql/literal'
22
+
23
+ module Ronin
24
+ module Code
25
+ module SQL
26
+ #
27
+ # Methods for creating SQL {Literals Literal}.
28
+ #
29
+ # @api public
30
+ #
31
+ module Literals
32
+ #
33
+ # Creates a `NULL` literal.
34
+ #
35
+ # @return [Literal]
36
+ # The `NULL` literal.
37
+ #
38
+ def null
39
+ Literal.new(:NULL)
40
+ end
41
+
42
+ #
43
+ # Creates an Integer literal.
44
+ #
45
+ # @param [String, Numeric] value
46
+ # The value to convert to an Integer.
47
+ #
48
+ # @return [Literal<Integer>]
49
+ # The Integer literal.
50
+ #
51
+ def int(value)
52
+ Literal.new(value.to_i)
53
+ end
54
+
55
+ #
56
+ # Creates an Float literal.
57
+ #
58
+ # @param [String, Numeric] value
59
+ # The value to convert to a Float.
60
+ #
61
+ # @return [Literal<Float>]
62
+ # The Float literal.
63
+ #
64
+ def float(value)
65
+ Literal.new(value.to_f)
66
+ end
67
+
68
+ #
69
+ # Creates an String literal.
70
+ #
71
+ # @param [String, Numeric] value
72
+ # The value to convert to a String.
73
+ #
74
+ # @return [Literal<String>]
75
+ # The String literal.
76
+ #
77
+ def string(value)
78
+ Literal.new(value.to_s)
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end