Class: Ronin::Code::SQL::Injection

Inherits:
StatementList show all
Includes:
Clauses, Literals
Defined in:
lib/ronin/code/sql/injection.rb

Overview

Represents a SQL injection (SQLi).

Constant Summary collapse

PLACE_HOLDERS =

Default place holder values.

{
  integer: 1,
  decimal: 1.0,
  string:  '1',
  list:    [nil],
  column:  :id
}

Instance Attribute Summary collapse

Attributes inherited from StatementList

#statements

Instance Method Summary collapse

Methods included from Clauses

#clause, #clauses, #default_values, #from, #full_join, #group_by, #having, #indexed_by, #inner_join, #into, #join, #left_join, #limit, #not_indexed, #offset, #on, #order_by, #right_join, #set, #top, #union, #union_all, #values, #where

Methods included from Literals

#float, #int, #null, #string

Methods inherited from StatementList

#<<, #statement

Methods included from Emittable

#emitter, #inspect, #to_s

Methods included from Statements

#delete, #drop_table, #insert, #select, #statement, #update

Methods included from Functions

#abs, #acos, #ascii, #asin, #atan, #atan2, #avg, #bin, #bit_and, #bit_count, #bit_length, #bit_or, #ceil, #ceiling, #char, #char_length, #character_length, #concat, #concat_ws, #conv, #cos, #cot, #count, #degrees, #elt, #exp, #export_set, #field, #find_in_set, #floor, #format, #glob, #greatest, #hex, #insert, #instr, #interval, #lcase, #least, #left, #length, #like, #load_file, #locate, #log, #log10, #lower, #lpad, #ltrim, #make_set, #max, #mid, #min, #mod, #oct, #octet_length, #ord, #pi, #position, #pow, #power, #quote, #radians, #rand, #random, #repeat, #replace, #reverse, #right, #round, #rpad, #rtrim, #sign, #sin, #sleep, #soundex, #space, #sqrt, #std, #stddev, #strcmp, #substring, #substring_index, #sum, #tan, #trim, #truncate, #ucase, #unhex, #upper

Methods included from Fields

#method_missing, #respond_to_missing?, #to_ary

Constructor Details

#initialize(escape: :integer, place_holder: PLACE_HOLDERS.fetch(escape)) {|(injection)| ... } ⇒ Injection

Initializes a new SQL injection.

Parameters:

  • escape (:integer, :decimal, :string, :column) (defaults to: :integer)

    The type of element to escape out of.

  • place_holder (String, Symbol, Integer) (defaults to: PLACE_HOLDERS.fetch(escape))

    Place-holder data.

Yields:

  • ((injection))

    If a block is given, it will be evaluated within the injection. If the block accepts an argument, the block will be called with the new injection.

Yield Parameters:

  • injection (Injection)

    The new injection.



77
78
79
80
81
82
83
84
# File 'lib/ronin/code/sql/injection.rb', line 77

def initialize(escape:       :integer,
               place_holder: PLACE_HOLDERS.fetch(escape),
               &block)
  @escape     = escape
  @expression = InjectionExpr.new(place_holder)

  super(&block)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Ronin::Code::SQL::Fields

Instance Attribute Details

#escape:integer, ... (readonly)

The type of element to escape out of

Returns:

  • (:integer, :decimal, :string, :column)


53
54
55
# File 'lib/ronin/code/sql/injection.rb', line 53

def escape
  @escape
end

#expressionInjectionExpr (readonly)

The expression that will be injected

Returns:



58
59
60
# File 'lib/ronin/code/sql/injection.rb', line 58

def expression
  @expression
end

Instance Method Details

#and {|(expr)| ... } ⇒ self

Appends an AND expression to the injection.

Yields:

  • ((expr))

    The return value of the block will be used as the right-hand side operand. If the block accepts an argument, it will be called with the injection.

Yield Parameters:

Returns:

  • (self)


98
99
100
101
# File 'lib/ronin/code/sql/injection.rb', line 98

def and(&block)
  @expression.and(&block)
  return self
end

#or {|(expr)| ... } ⇒ self

Appends an OR expression to the injection.

Yields:

  • ((expr))

    The return value of the block will be used as the right-hand side operand. If the block accepts an argument, it will be called with the injection expression.

Yield Parameters:

Returns:

  • (self)


115
116
117
118
# File 'lib/ronin/code/sql/injection.rb', line 115

def or(&block)
  @expression.or(&block)
  return self
end

#to_sql(terminate: false, **kwargs) ⇒ String

Converts the SQL injection to SQL.

Parameters:

  • terminate (Boolean) (defaults to: false)

    Specifies whether to terminate the injection with ;--.

  • kwargs (Hash{Symbol => Object})

    Additional keyword arguments for Emitter#initialize.

Returns:

  • (String)

    The raw SQL.



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/ronin/code/sql/injection.rb', line 132

def to_sql(terminate: false, **kwargs)
  emitter = emitter(**kwargs)
  sql     = @expression.to_sql(**kwargs)

  unless clauses.empty?
    sql << emitter.space << emitter.emit_clauses(clauses)
  end

  unless statements.empty?
    sql << ';' << emitter.space << emitter.emit_statement_list(self)
  end

  case @escape
  when :string, :list
    if (terminate || (sql[0,1] != sql[-1,1]))
      # terminate the expression
      sql << ';' << emitter.emit_comment
    else
      sql = sql[0..-2]
    end

    # balance the quotes
    sql = sql[1..]
  else
    if terminate
      # terminate the expression
      sql << ';' << emitter.emit_comment
    end
  end

  return sql
end