ronin-code-sql 2.0.0.beta1

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 (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