Class: Contrast::Agent::Protect::Rule::DefaultScanner Deprecated
- Defined in:
- lib/contrast/agent/protect/rule/default_scanner.rb
Overview
RUBY-356: this class and those that extend it are being phased out in favor of the more performant code in the Service.
The base class used to determine if a user input crosses a token boundary or state, indicating a successful attack using SQL or NoSQL Injection.
Direct Known Subclasses
Constant Summary collapse
- OPERATOR_PATTERN =
%r{[+=*^/%><!-]}.cs__freeze
Instance Method Summary collapse
-
#crosses_boundary(query, index, input) ⇒ Object
Potential states :STATE_INSIDE_TOKEN :STATE_INSIDE_NUMBER :STATE_EXPECTING_TOKEN :STATE_INSIDE_DOUBLEQUOTE :STATE_INSIDE_SINGLEQUOTE :STATE_INSIDE_STRING_ESCAPE_BLOCK :STATE_INSIDE_LINE_COMMENT # inside a comment that will continue to the end of the line :STATE_INSIDE_BLOCK_COMMENT # inside a commend that will end with a closing tag :STATE_SKIP_NEXT_CHARACTER.
- #double_quote?(query, index) ⇒ Boolean
-
#double_quote_escape_in_double_quote? ⇒ Boolean
Indicates if ‘“”’ inside of double quotes is the equivalent of ‘"’ We assume no by default.
-
#end_block_comment?(char, index, query) ⇒ Boolean
Is the current character / sequence of characters the end of a block comment We assume ‘*/’ ends the comment by default.
-
#escape_char?(char) ⇒ Boolean
Is the character provided an escape character? By default, we’ll assume.
-
#escape_sequence_end?(_char) ⇒ Boolean
Is this the end of a string escape sequence? Since escape sequences aren’t supported, the answer is always false.
-
#escape_sequence_start?(_char) ⇒ Boolean
Is this the start of a string escape sequence? Since escape sequences aren’t supported, the answer is always false.
- #find_block_comment_boundary(query, index) ⇒ Object
- #find_escape_sequence_boundary(query, index) ⇒ Object
- #find_new_line_boundary(query, index) ⇒ Object
- #operator?(char) ⇒ Boolean
- #process_double_quote(boundaries, char, index, query) ⇒ Object
- #process_expecting_token(boundaries, char, index, query) ⇒ Object
- #process_inside_token(boundaries, char, index, query) ⇒ Object
- #process_number(boundaries, char, index, _query) ⇒ Object
- #process_single_quote(boundaries, char, index, query) ⇒ Object
- #process_state(boundaries, current_state, char, index, query) ⇒ Object
- #scan_token_boundaries(query) ⇒ Object
-
#singe_quote_escape_in_singe_quote? ⇒ Boolean
Indicates if “”” inside of single quotes is the equivalent of “'” We assume yes by default.
- #single_quote?(query, index) ⇒ Boolean
-
#start_block_comment?(char, index, query) ⇒ Boolean
Is the current character / sequence of characters the start of a block comment We assume ‘/*’ starts the comment by default.
-
#start_line_comment?(char, index, query) ⇒ Boolean
@note: Any class extending this module should override these methods as needed Are the current and subsequent characters both ‘-’ ?.
- #token_boundaries(query) ⇒ Object
Instance Method Details
#crosses_boundary(query, index, input) ⇒ Object
Potential states :STATE_INSIDE_TOKEN :STATE_INSIDE_NUMBER :STATE_EXPECTING_TOKEN :STATE_INSIDE_DOUBLEQUOTE :STATE_INSIDE_SINGLEQUOTE :STATE_INSIDE_STRING_ESCAPE_BLOCK :STATE_INSIDE_LINE_COMMENT # inside a comment that will continue to the end of the line :STATE_INSIDE_BLOCK_COMMENT # inside a commend that will end with a closing tag :STATE_SKIP_NEXT_CHARACTER
21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/contrast/agent/protect/rule/default_scanner.rb', line 21 def crosses_boundary query, index, input last_boundary = 0 token_boundaries(query).each do |boundary| if boundary > index return last_boundary, boundary if boundary < index + input.length break end last_boundary = boundary end nil end |
#double_quote?(query, index) ⇒ Boolean
180 181 182 183 184 |
# File 'lib/contrast/agent/protect/rule/default_scanner.rb', line 180 def double_quote? query, index return false unless index >= 0 && index < query.length query[index] == Contrast::Utils::ObjectShare::DOUBLE_QUOTE end |
#double_quote_escape_in_double_quote? ⇒ Boolean
Indicates if ‘“”’ inside of double quotes is the equivalent of ‘"’ We assume no by default
260 261 262 |
# File 'lib/contrast/agent/protect/rule/default_scanner.rb', line 260 def double_quote_escape_in_double_quote? false end |
#end_block_comment?(char, index, query) ⇒ Boolean
Is the current character / sequence of characters the end of a block comment We assume ‘*/’ ends the comment by default
251 252 253 254 255 256 |
# File 'lib/contrast/agent/protect/rule/default_scanner.rb', line 251 def end_block_comment? char, index, query return false unless char == Contrast::Utils::ObjectShare::ASTERISK return false unless (query.length - 2) >= index query[index + 1] == Contrast::Utils::ObjectShare::SLASH end |
#escape_char?(char) ⇒ Boolean
Is the character provided an escape character? By default, we’ll assume
272 273 274 |
# File 'lib/contrast/agent/protect/rule/default_scanner.rb', line 272 def escape_char? char char == Contrast::Utils::ObjectShare::BACK_SLASH end |
#escape_sequence_end?(_char) ⇒ Boolean
Is this the end of a string escape sequence? Since escape sequences aren’t supported, the answer is always false
284 285 286 |
# File 'lib/contrast/agent/protect/rule/default_scanner.rb', line 284 def escape_sequence_end? _char false end |
#escape_sequence_start?(_char) ⇒ Boolean
Is this the start of a string escape sequence? Since escape sequences aren’t supported, the answer is always false
278 279 280 |
# File 'lib/contrast/agent/protect/rule/default_scanner.rb', line 278 def escape_sequence_start? _char false end |
#find_block_comment_boundary(query, index) ⇒ Object
203 204 205 206 207 208 209 210 211 212 |
# File 'lib/contrast/agent/protect/rule/default_scanner.rb', line 203 def find_block_comment_boundary query, index idx = index while idx < query.length char = query[idx] break if end_block_comment?(char, idx, query) idx += 1 end idx end |
#find_escape_sequence_boundary(query, index) ⇒ Object
192 193 194 195 196 197 198 199 200 201 |
# File 'lib/contrast/agent/protect/rule/default_scanner.rb', line 192 def find_escape_sequence_boundary query, index idx = index while idx < query.length char = query[idx] break if escape_sequence_end?(char) idx += 1 end idx end |
#find_new_line_boundary(query, index) ⇒ Object
214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/contrast/agent/protect/rule/default_scanner.rb', line 214 def find_new_line_boundary query, index idx = index while idx < query.length char = query[idx] break if char == Contrast::Utils::ObjectShare::NEW_LINE break if char == Contrast::Utils::ObjectShare::RETURN idx += 1 end idx end |
#operator?(char) ⇒ Boolean
227 228 229 |
# File 'lib/contrast/agent/protect/rule/default_scanner.rb', line 227 def operator? char char.match?(OPERATOR_PATTERN) end |
#process_double_quote(boundaries, char, index, query) ⇒ Object
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/contrast/agent/protect/rule/default_scanner.rb', line 146 def process_double_quote boundaries, char, index, query if escape_char?(char) :STATE_SKIP_NEXT_CHARACTER elsif escape_sequence_start?(char) :STATE_INSIDE_STRING_ESCAPE_BLOCK elsif char == Contrast::Utils::ObjectShare::DOUBLE_QUOTE if double_quote_escape_in_double_quote? && double_quote?(query, index + 1) :STATE_SKIP_NEXT_CHARACTER else boundaries << index :STATE_EXPECTING_TOKEN end else :STATE_INSIDE_DOUBLEQUOTE end end |
#process_expecting_token(boundaries, char, index, query) ⇒ Object
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/contrast/agent/protect/rule/default_scanner.rb', line 89 def process_expecting_token boundaries, char, index, query if char == Contrast::Utils::ObjectShare::SINGLE_QUOTE boundaries << index :STATE_INSIDE_SINGLEQUOTE elsif char == Contrast::Utils::ObjectShare::DOUBLE_QUOTE boundaries << index :STATE_INSIDE_DOUBLEQUOTE elsif char.match?(Contrast::Utils::ObjectShare::DIGIT_REGEXP) boundaries << index :STATE_INSIDE_NUMBER elsif start_line_comment?(char, index, query) boundaries << index :STATE_INSIDE_LINE_COMMENT elsif start_block_comment?(char, index, query) boundaries << index :STATE_INSIDE_BLOCK_COMMENT elsif char.match?(Contrast::Utils::ObjectShare::NOT_WHITE_SPACE_REGEXP) boundaries << index :STATE_INSIDE_TOKEN else :STATE_EXPECTING_TOKEN end end |
#process_inside_token(boundaries, char, index, query) ⇒ Object
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/contrast/agent/protect/rule/default_scanner.rb', line 113 def process_inside_token boundaries, char, index, query if char == Contrast::Utils::ObjectShare::SINGLE_QUOTE boundaries << index :STATE_INSIDE_SINGLEQUOTE elsif char == Contrast::Utils::ObjectShare::DOUBLE_QUOTE boundaries << index :STATE_INSIDE_DOUBLEQUOTE elsif start_line_comment?(char, index, query) boundaries << index :STATE_INSIDE_LINE_COMMENT elsif start_block_comment?(char, index, query) boundaries << index :STATE_INSIDE_BLOCK_COMMENT elsif operator?(char) boundaries << index :STATE_EXPECTING_TOKEN elsif char.match?(Contrast::Utils::ObjectShare::WHITE_SPACE_REGEXP) boundaries << index :STATE_EXPECTING_TOKEN else :STATE_INSIDE_TOKEN end end |
#process_number(boundaries, char, index, _query) ⇒ Object
137 138 139 140 141 142 143 144 |
# File 'lib/contrast/agent/protect/rule/default_scanner.rb', line 137 def process_number boundaries, char, index, _query if char.match?(Contrast::Utils::ObjectShare::DIGIT_REGEXP) || char == Contrast::Utils::ObjectShare::PERIOD :STATE_INSIDE_NUMBER else boundaries << index :STATE_EXPECTING_TOKEN end end |
#process_single_quote(boundaries, char, index, query) ⇒ Object
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/contrast/agent/protect/rule/default_scanner.rb', line 163 def process_single_quote boundaries, char, index, query if escape_char?(char) :STATE_SKIP_NEXT_CHARACTER elsif escape_sequence_start?(char) :STATE_INSIDE_STRING_ESCAPE_BLOCK elsif char == Contrast::Utils::ObjectShare::SINGLE_QUOTE if singe_quote_escape_in_singe_quote? && single_quote?(query, index + 1) :STATE_SKIP_NEXT_CHARACTER else boundaries << index :STATE_EXPECTING_TOKEN end else :STATE_INSIDE_SINGLEQUOTE end end |
#process_state(boundaries, current_state, char, index, query) ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/contrast/agent/protect/rule/default_scanner.rb', line 74 def process_state boundaries, current_state, char, index, query case current_state when :STATE_EXPECTING_TOKEN process_expecting_token(boundaries, char, index, query) when :STATE_INSIDE_NUMBER process_number(boundaries, char, index, query) when :STATE_INSIDE_TOKEN process_inside_token(boundaries, char, index, query) when :STATE_INSIDE_DOUBLEQUOTE process_double_quote(boundaries, char, index, query) when :STATE_INSIDE_SINGLEQUOTE process_single_quote(boundaries, char, index, query) end end |
#scan_token_boundaries(query) ⇒ Object
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/contrast/agent/protect/rule/default_scanner.rb', line 38 def scan_token_boundaries query boundaries = [] return boundaries unless query && !query.empty? state = :STATE_EXPECTING_TOKEN index = 0 while index < query.length char = query[index] previous_state = state state = process_state(boundaries, state, char, index, query) case state when :STATE_SKIP_NEXT_CHARACTER index += 1 state = previous_state when :STATE_INSIDE_STRING_ESCAPE_BLOCK index = find_escape_sequence_boundary(query, index + 1) state = previous_state when :STATE_INSIDE_BLOCK_COMMENT index = find_block_comment_boundary(query, index + 2) index += 1 state = previous_state boundaries << index when :STATE_INSIDE_LINE_COMMENT index = find_new_line_boundary(query, index + 1) state = previous_state boundaries << index end index += 1 end boundaries end |
#singe_quote_escape_in_singe_quote? ⇒ Boolean
Indicates if “”” inside of single quotes is the equivalent of “'” We assume yes by default
266 267 268 |
# File 'lib/contrast/agent/protect/rule/default_scanner.rb', line 266 def singe_quote_escape_in_singe_quote? true end |
#single_quote?(query, index) ⇒ Boolean
186 187 188 189 190 |
# File 'lib/contrast/agent/protect/rule/default_scanner.rb', line 186 def single_quote? query, index return false unless index >= 0 && index < query.length query[index] == Contrast::Utils::ObjectShare::SINGLE_QUOTE end |
#start_block_comment?(char, index, query) ⇒ Boolean
Is the current character / sequence of characters the start of a block comment We assume ‘/*’ starts the comment by default
242 243 244 245 246 247 |
# File 'lib/contrast/agent/protect/rule/default_scanner.rb', line 242 def start_block_comment? char, index, query return false unless char == Contrast::Utils::ObjectShare::SLASH return false unless (query.length - 2) >= index query[index + 1] == Contrast::Utils::ObjectShare::ASTERISK end |
#start_line_comment?(char, index, query) ⇒ Boolean
@note: Any class extending this module should override these methods as needed Are the current and subsequent characters both ‘-’ ?
233 234 235 236 237 238 |
# File 'lib/contrast/agent/protect/rule/default_scanner.rb', line 233 def start_line_comment? char, index, query return false unless char == Contrast::Utils::ObjectShare::DASH return false unless (query.length - 2) >= index query[index + 1] == Contrast::Utils::ObjectShare::DASH end |
#token_boundaries(query) ⇒ Object
34 35 36 |
# File 'lib/contrast/agent/protect/rule/default_scanner.rb', line 34 def token_boundaries query @_token_boundaries ||= scan_token_boundaries(query) end |