railroader 4.3.5 → 4.3.7
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.
- checksums.yaml +4 -4
- data/CHANGES.md +16 -0
- data/README.md +15 -0
- data/bin/railroader +1 -1
- data/lib/railroader/call_index.rb +11 -11
- data/lib/railroader/checks/base_check.rb +43 -43
- data/lib/railroader/checks/check_basic_auth.rb +3 -3
- data/lib/railroader/checks/check_content_tag.rb +9 -9
- data/lib/railroader/checks/check_create_with.rb +2 -2
- data/lib/railroader/checks/check_cross_site_scripting.rb +24 -24
- data/lib/railroader/checks/check_default_routes.rb +5 -5
- data/lib/railroader/checks/check_deserialize.rb +1 -1
- data/lib/railroader/checks/check_dynamic_finders.rb +1 -1
- data/lib/railroader/checks/check_escape_function.rb +3 -3
- data/lib/railroader/checks/check_evaluation.rb +4 -4
- data/lib/railroader/checks/check_execute.rb +8 -8
- data/lib/railroader/checks/check_file_access.rb +2 -2
- data/lib/railroader/checks/check_filter_skipping.rb +2 -2
- data/lib/railroader/checks/check_forgery_setting.rb +3 -3
- data/lib/railroader/checks/check_jruby_xml.rb +1 -1
- data/lib/railroader/checks/check_json_parsing.rb +2 -2
- data/lib/railroader/checks/check_link_to.rb +12 -12
- data/lib/railroader/checks/check_link_to_href.rb +9 -9
- data/lib/railroader/checks/check_mail_to.rb +4 -4
- data/lib/railroader/checks/check_mass_assignment.rb +5 -5
- data/lib/railroader/checks/check_model_attributes.rb +6 -6
- data/lib/railroader/checks/check_model_serialize.rb +2 -2
- data/lib/railroader/checks/check_nested_attributes.rb +2 -2
- data/lib/railroader/checks/check_nested_attributes_bypass.rb +1 -1
- data/lib/railroader/checks/check_quote_table_name.rb +3 -3
- data/lib/railroader/checks/check_redirect.rb +19 -19
- data/lib/railroader/checks/check_regex_dos.rb +3 -3
- data/lib/railroader/checks/check_render.rb +4 -4
- data/lib/railroader/checks/check_response_splitting.rb +2 -2
- data/lib/railroader/checks/check_safe_buffer_manipulation.rb +4 -4
- data/lib/railroader/checks/check_sanitize_methods.rb +2 -2
- data/lib/railroader/checks/check_select_tag.rb +4 -4
- data/lib/railroader/checks/check_select_vulnerability.rb +3 -3
- data/lib/railroader/checks/check_send.rb +1 -1
- data/lib/railroader/checks/check_send_file.rb +1 -1
- data/lib/railroader/checks/check_session_settings.rb +10 -10
- data/lib/railroader/checks/check_single_quotes.rb +8 -8
- data/lib/railroader/checks/check_skip_before_filter.rb +5 -5
- data/lib/railroader/checks/check_sql.rb +41 -41
- data/lib/railroader/checks/check_strip_tags.rb +6 -6
- data/lib/railroader/checks/check_symbol_dos_cve.rb +0 -1
- data/lib/railroader/checks/check_translate_bug.rb +4 -4
- data/lib/railroader/checks/check_unsafe_reflection.rb +1 -1
- data/lib/railroader/checks/check_validation_regex.rb +7 -7
- data/lib/railroader/checks/check_weak_hash.rb +1 -1
- data/lib/railroader/checks/check_without_protection.rb +9 -9
- data/lib/railroader/checks/check_yaml_parsing.rb +5 -5
- data/lib/railroader/checks.rb +18 -18
- data/lib/railroader/commandline.rb +1 -1
- data/lib/railroader/differ.rb +2 -2
- data/lib/railroader/options.rb +7 -7
- data/lib/railroader/parsers/rails2_erubis.rb +1 -1
- data/lib/railroader/parsers/rails2_xss_plugin_erubis.rb +4 -4
- data/lib/railroader/parsers/template_parser.rb +1 -1
- data/lib/railroader/processor.rb +17 -17
- data/lib/railroader/processors/alias_processor.rb +72 -72
- data/lib/railroader/processors/base_processor.rb +31 -31
- data/lib/railroader/processors/controller_alias_processor.rb +31 -31
- data/lib/railroader/processors/controller_processor.rb +29 -29
- data/lib/railroader/processors/erb_template_processor.rb +8 -8
- data/lib/railroader/processors/erubis_template_processor.rb +6 -6
- data/lib/railroader/processors/gem_processor.rb +1 -1
- data/lib/railroader/processors/haml_template_processor.rb +14 -14
- data/lib/railroader/processors/lib/call_conversion_helper.rb +1 -1
- data/lib/railroader/processors/lib/find_all_calls.rb +15 -15
- data/lib/railroader/processors/lib/find_call.rb +26 -26
- data/lib/railroader/processors/lib/find_return_value.rb +11 -11
- data/lib/railroader/processors/lib/module_helper.rb +1 -1
- data/lib/railroader/processors/lib/processor_helper.rb +4 -4
- data/lib/railroader/processors/lib/rails2_config_processor.rb +20 -20
- data/lib/railroader/processors/lib/rails2_route_processor.rb +38 -38
- data/lib/railroader/processors/lib/rails3_config_processor.rb +14 -14
- data/lib/railroader/processors/lib/rails3_route_processor.rb +16 -16
- data/lib/railroader/processors/lib/render_helper.rb +32 -32
- data/lib/railroader/processors/lib/route_helper.rb +12 -12
- data/lib/railroader/processors/library_processor.rb +1 -1
- data/lib/railroader/processors/model_processor.rb +9 -9
- data/lib/railroader/processors/output_processor.rb +3 -3
- data/lib/railroader/processors/slim_template_processor.rb +4 -4
- data/lib/railroader/processors/template_alias_processor.rb +10 -10
- data/lib/railroader/processors/template_processor.rb +7 -7
- data/lib/railroader/report/renderer.rb +1 -1
- data/lib/railroader/report/report_base.rb +12 -12
- data/lib/railroader/report/report_csv.rb +2 -2
- data/lib/railroader/report/report_html.rb +5 -5
- data/lib/railroader/report/report_markdown.rb +2 -2
- data/lib/railroader/report/report_table.rb +3 -3
- data/lib/railroader/report/report_tabs.rb +2 -2
- data/lib/railroader/report/report_text.rb +3 -4
- data/lib/railroader/report.rb +3 -3
- data/lib/railroader/rescanner.rb +36 -36
- data/lib/railroader/scanner.rb +23 -23
- data/lib/railroader/tracker/config.rb +3 -3
- data/lib/railroader/tracker/controller.rb +2 -2
- data/lib/railroader/tracker.rb +42 -42
- data/lib/railroader/util.rb +47 -47
- data/lib/railroader/version.rb +1 -1
- data/lib/railroader/warning.rb +9 -10
- data/lib/railroader.rb +32 -32
- data/lib/ruby_parser/bm_sexp.rb +63 -63
- data/lib/ruby_parser/bm_sexp_processor.rb +3 -3
- metadata +4 -4
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'railroader/checks/base_check'
|
2
2
|
|
3
|
-
#Checks for select() helper vulnerability in some versions of Rails 3
|
4
|
-
#http://groups.google.com/group/rubyonrails-security/browse_thread/thread/9da0c515a6c4664
|
3
|
+
# Checks for select() helper vulnerability in some versions of Rails 3
|
4
|
+
# http://groups.google.com/group/rubyonrails-security/browse_thread/thread/9da0c515a6c4664
|
5
5
|
class Railroader::CheckSelectVulnerability < Railroader::BaseCheck
|
6
6
|
Railroader::Checks.add self
|
7
7
|
|
@@ -39,7 +39,7 @@ class Railroader::CheckSelectVulnerability < Railroader::BaseCheck
|
|
39
39
|
|
40
40
|
third_arg = result[:call].third_arg
|
41
41
|
|
42
|
-
#Check for user input in options parameter
|
42
|
+
# Check for user input in options parameter
|
43
43
|
if sexp? third_arg and include_user_input? third_arg
|
44
44
|
add_result result
|
45
45
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'railroader/checks/check_file_access'
|
2
2
|
require 'railroader/processors/lib/processor_helper'
|
3
3
|
|
4
|
-
#Checks for user input in send_file()
|
4
|
+
# Checks for user input in send_file()
|
5
5
|
class Railroader::CheckSendFile < Railroader::CheckFileAccess
|
6
6
|
Railroader::Checks.add self
|
7
7
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'railroader/checks/base_check'
|
2
2
|
|
3
|
-
#Checks for session key length and http_only settings
|
3
|
+
# Checks for session key length and http_only settings
|
4
4
|
class Railroader::CheckSessionSettings < Railroader::BaseCheck
|
5
5
|
Railroader::Checks.add self
|
6
6
|
|
@@ -17,7 +17,7 @@ class Railroader::CheckSessionSettings < Railroader::BaseCheck
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def run_check
|
20
|
-
settings = tracker.config.session_settings
|
20
|
+
settings = tracker.config.session_settings
|
21
21
|
|
22
22
|
check_for_issues settings, @app_tree.expand_path("config/environment.rb")
|
23
23
|
|
@@ -32,14 +32,14 @@ class Railroader::CheckSessionSettings < Railroader::BaseCheck
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
#Looks for ActionController::Base.session = { ... }
|
36
|
-
#in Rails 2.x apps
|
35
|
+
# Looks for ActionController::Base.session = { ... }
|
36
|
+
# in Rails 2.x apps
|
37
37
|
#
|
38
|
-
#and App::Application.config.secret_token =
|
39
|
-
#in Rails 3.x apps
|
38
|
+
# and App::Application.config.secret_token =
|
39
|
+
# in Rails 3.x apps
|
40
40
|
#
|
41
|
-
#and App::Application.config.secret_key_base =
|
42
|
-
#in Rails 4.x apps
|
41
|
+
# and App::Application.config.secret_key_base =
|
42
|
+
# in Rails 4.x apps
|
43
43
|
def process_attrasgn exp
|
44
44
|
if not tracker.options[:rails3] and exp.target == @session_settings and exp.method == :session=
|
45
45
|
check_for_issues exp.first_arg, @app_tree.expand_path("config/initializers/session_store.rb")
|
@@ -54,8 +54,8 @@ class Railroader::CheckSessionSettings < Railroader::BaseCheck
|
|
54
54
|
exp
|
55
55
|
end
|
56
56
|
|
57
|
-
#Looks for Rails3::Application.config.session_store :cookie_store, { ... }
|
58
|
-
#in Rails 3.x apps
|
57
|
+
# Looks for Rails3::Application.config.session_store :cookie_store, { ... }
|
58
|
+
# in Rails 3.x apps
|
59
59
|
def process_call exp
|
60
60
|
if tracker.options[:rails3] and settings_target?(exp.target) and exp.method == :session_store
|
61
61
|
check_for_rails3_issues exp.second_arg, @app_tree.expand_path("config/initializers/session_store.rb")
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'railroader/checks/base_check'
|
2
2
|
|
3
|
-
#Checks for versions which do not escape single quotes.
|
4
|
-
#https://groups.google.com/d/topic/rubyonrails-security/kKGNeMrnmiY/discussion
|
3
|
+
# Checks for versions which do not escape single quotes.
|
4
|
+
# https://groups.google.com/d/topic/rubyonrails-security/kKGNeMrnmiY/discussion
|
5
5
|
class Railroader::CheckSingleQuotes < Railroader::BaseCheck
|
6
6
|
Railroader::Checks.add self
|
7
7
|
RACK_UTILS = Sexp.new(:colon2, Sexp.new(:const, :Rack), :Utils)
|
@@ -37,8 +37,8 @@ class Railroader::CheckSingleQuotes < Railroader::BaseCheck
|
|
37
37
|
:link_path => "https://groups.google.com/d/topic/rubyonrails-security/kKGNeMrnmiY/discussion"
|
38
38
|
end
|
39
39
|
|
40
|
-
#Process initializers to see if they use workaround
|
41
|
-
#by replacing Erb::Util.html_escape
|
40
|
+
# Process initializers to see if they use workaround
|
41
|
+
# by replacing Erb::Util.html_escape
|
42
42
|
def uses_rack_escape?
|
43
43
|
@tracker.initializers.each do |_name, src|
|
44
44
|
process src
|
@@ -47,7 +47,7 @@ class Railroader::CheckSingleQuotes < Railroader::BaseCheck
|
|
47
47
|
@uses_rack_escape
|
48
48
|
end
|
49
49
|
|
50
|
-
#Look for
|
50
|
+
# Look for
|
51
51
|
#
|
52
52
|
# class ERB
|
53
53
|
def process_class exp
|
@@ -60,7 +60,7 @@ class Railroader::CheckSingleQuotes < Railroader::BaseCheck
|
|
60
60
|
exp
|
61
61
|
end
|
62
62
|
|
63
|
-
#Look for
|
63
|
+
# Look for
|
64
64
|
#
|
65
65
|
# module Util
|
66
66
|
def process_module exp
|
@@ -73,7 +73,7 @@ class Railroader::CheckSingleQuotes < Railroader::BaseCheck
|
|
73
73
|
exp
|
74
74
|
end
|
75
75
|
|
76
|
-
#Look for
|
76
|
+
# Look for
|
77
77
|
#
|
78
78
|
# def html_escape
|
79
79
|
def process_defn exp
|
@@ -86,7 +86,7 @@ class Railroader::CheckSingleQuotes < Railroader::BaseCheck
|
|
86
86
|
exp
|
87
87
|
end
|
88
88
|
|
89
|
-
#Look for
|
89
|
+
# Look for
|
90
90
|
#
|
91
91
|
# Rack::Utils.escape_html
|
92
92
|
def process_call exp
|
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'railroader/checks/base_check'
|
2
2
|
|
3
|
-
#At the moment, this looks for
|
3
|
+
# At the moment, this looks for
|
4
4
|
#
|
5
5
|
# skip_before_filter :verify_authenticity_token, :except => [...]
|
6
6
|
#
|
7
|
-
#which is essentially a blacklist approach (no actions are checked EXCEPT the
|
8
|
-
#ones listed) versus a whitelist approach (ONLY the actions listed will skip
|
9
|
-
#the check)
|
7
|
+
# which is essentially a blacklist approach (no actions are checked EXCEPT the
|
8
|
+
# ones listed) versus a whitelist approach (ONLY the actions listed will skip
|
9
|
+
# the check)
|
10
10
|
class Railroader::CheckSkipBeforeFilter < Railroader::BaseCheck
|
11
11
|
Railroader::Checks.add self
|
12
12
|
|
@@ -23,7 +23,7 @@ class Railroader::CheckSkipBeforeFilter < Railroader::BaseCheck
|
|
23
23
|
def process_skip_filter filter, controller
|
24
24
|
case skip_except_value filter
|
25
25
|
when :verify_authenticity_token
|
26
|
-
warn :class => controller.name, #ugh this should be a controller warning, too
|
26
|
+
warn :class => controller.name, # ugh this should be a controller warning, too
|
27
27
|
:warning_type => "Cross-Site Request Forgery",
|
28
28
|
:warning_code => :csrf_blacklist,
|
29
29
|
:message => "Use whitelist (:only => [..]) when skipping CSRF check",
|
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'railroader/checks/base_check'
|
2
2
|
|
3
|
-
#This check tests for find calls which do not use Rails' auto SQL escaping
|
3
|
+
# This check tests for find calls which do not use Rails' auto SQL escaping
|
4
4
|
#
|
5
|
-
#For example:
|
5
|
+
# For example:
|
6
6
|
# Project.find(:all, :conditions => "name = '" + params[:name] + "'")
|
7
7
|
#
|
8
8
|
# Project.find(:all, :conditions => "name = '#{params[:name]}'")
|
@@ -62,8 +62,8 @@ class Railroader::CheckSQL < Railroader::BaseCheck
|
|
62
62
|
calls.each { |call| process_result call }
|
63
63
|
end
|
64
64
|
|
65
|
-
#Find calls to named_scope() or scope() in models
|
66
|
-
#RP 3 TODO
|
65
|
+
# Find calls to named_scope() or scope() in models
|
66
|
+
# RP 3 TODO
|
67
67
|
def find_scope_calls
|
68
68
|
scope_calls = []
|
69
69
|
|
@@ -130,7 +130,7 @@ class Railroader::CheckSQL < Railroader::BaseCheck
|
|
130
130
|
end
|
131
131
|
end
|
132
132
|
|
133
|
-
#Process possible SQL injection sites:
|
133
|
+
# Process possible SQL injection sites:
|
134
134
|
#
|
135
135
|
# Model#find
|
136
136
|
#
|
@@ -253,7 +253,7 @@ class Railroader::CheckSQL < Railroader::BaseCheck
|
|
253
253
|
end
|
254
254
|
|
255
255
|
|
256
|
-
#The 'find' methods accept a number of different types of parameters:
|
256
|
+
# The 'find' methods accept a number of different types of parameters:
|
257
257
|
#
|
258
258
|
# * The first argument might be :all, :first, or :last
|
259
259
|
# * The first argument might be an integer ID or an array of IDs
|
@@ -263,7 +263,7 @@ class Railroader::CheckSQL < Railroader::BaseCheck
|
|
263
263
|
# * The second argument might contain properly parameterized SQL fragments in arrays
|
264
264
|
# * The second argument might contain improperly parameterized SQL fragments in arrays
|
265
265
|
#
|
266
|
-
#This method should only be passed the second argument.
|
266
|
+
# This method should only be passed the second argument.
|
267
267
|
def check_find_arguments arg
|
268
268
|
return nil if not sexp? arg or node_type? arg, :lit, :string, :str, :true, :false, :nil
|
269
269
|
|
@@ -271,7 +271,7 @@ class Railroader::CheckSQL < Railroader::BaseCheck
|
|
271
271
|
end
|
272
272
|
|
273
273
|
def check_scope_arguments call
|
274
|
-
scope_arg = call.second_arg #first arg is name of scope
|
274
|
+
scope_arg = call.second_arg # first arg is name of scope
|
275
275
|
|
276
276
|
node_type?(scope_arg, :iter) ? unsafe_sql?(scope_arg.block) : unsafe_sql?(scope_arg)
|
277
277
|
end
|
@@ -295,19 +295,19 @@ class Railroader::CheckSQL < Railroader::BaseCheck
|
|
295
295
|
arg
|
296
296
|
end
|
297
297
|
elsif hash? arg
|
298
|
-
#This is generally going to be a hash of column names and values, which
|
299
|
-
#would escape the values. But the keys _could_ be user input.
|
298
|
+
# This is generally going to be a hash of column names and values, which
|
299
|
+
# would escape the values. But the keys _could_ be user input.
|
300
300
|
check_hash_keys arg
|
301
301
|
elsif node_type? arg, :lit, :str
|
302
302
|
nil
|
303
303
|
else
|
304
|
-
#Hashes are safe...but we check above for hash, so...?
|
304
|
+
# Hashes are safe...but we check above for hash, so...?
|
305
305
|
unsafe_sql? arg, :ignore_hash
|
306
306
|
end
|
307
307
|
end
|
308
308
|
|
309
|
-
#Checks each argument to order/reorder/group for possible SQL.
|
310
|
-
#Anything used with these methods is passed in verbatim.
|
309
|
+
# Checks each argument to order/reorder/group for possible SQL.
|
310
|
+
# Anything used with these methods is passed in verbatim.
|
311
311
|
def check_order_arguments args
|
312
312
|
return unless sexp? args
|
313
313
|
|
@@ -318,18 +318,18 @@ class Railroader::CheckSQL < Railroader::BaseCheck
|
|
318
318
|
end
|
319
319
|
end
|
320
320
|
|
321
|
-
#find_by_sql and count_by_sql can take either a straight SQL string
|
322
|
-
#or an array with values to bind.
|
321
|
+
# find_by_sql and count_by_sql can take either a straight SQL string
|
322
|
+
# or an array with values to bind.
|
323
323
|
def check_by_sql_arguments arg
|
324
324
|
return unless sexp? arg
|
325
325
|
|
326
|
-
#This is kind of unnecessary, because unsafe_sql? will handle an array
|
327
|
-
#correctly, but might be better to be explicit.
|
326
|
+
# This is kind of unnecessary, because unsafe_sql? will handle an array
|
327
|
+
# correctly, but might be better to be explicit.
|
328
328
|
array?(arg) ? unsafe_sql?(arg[1]) : unsafe_sql?(arg)
|
329
329
|
end
|
330
330
|
|
331
|
-
#joins can take a string, hash of associations, or an array of both(?)
|
332
|
-
#We only care about the possible string values.
|
331
|
+
# joins can take a string, hash of associations, or an array of both(?)
|
332
|
+
# We only care about the possible string values.
|
333
333
|
def check_joins_arguments arg
|
334
334
|
return unless sexp? arg and not node_type? arg, :hash, :string, :str
|
335
335
|
|
@@ -354,9 +354,9 @@ class Railroader::CheckSQL < Railroader::BaseCheck
|
|
354
354
|
nil
|
355
355
|
end
|
356
356
|
|
357
|
-
#Model#lock essentially only cares about strings. But those strings can be
|
358
|
-
#any SQL fragment. This does not apply to all databases. (For those who do not
|
359
|
-
#support it, the lock method does nothing).
|
357
|
+
# Model#lock essentially only cares about strings. But those strings can be
|
358
|
+
# any SQL fragment. This does not apply to all databases. (For those who do not
|
359
|
+
# support it, the lock method does nothing).
|
360
360
|
def check_lock_arguments arg
|
361
361
|
return unless sexp? arg and not node_type? arg, :hash, :array, :string, :str
|
362
362
|
|
@@ -364,9 +364,9 @@ class Railroader::CheckSQL < Railroader::BaseCheck
|
|
364
364
|
end
|
365
365
|
|
366
366
|
|
367
|
-
#Check hash keys for user input.
|
368
|
-
#(Seems unlikely, but if a user can control the column names queried, that
|
369
|
-
#could be bad)
|
367
|
+
# Check hash keys for user input.
|
368
|
+
# (Seems unlikely, but if a user can control the column names queried, that
|
369
|
+
# could be bad)
|
370
370
|
def check_hash_keys exp
|
371
371
|
hash_iterate(exp) do |key, _value|
|
372
372
|
unless symbol?(key)
|
@@ -378,10 +378,10 @@ class Railroader::CheckSQL < Railroader::BaseCheck
|
|
378
378
|
false
|
379
379
|
end
|
380
380
|
|
381
|
-
#Check an interpolated string for dangerous values.
|
381
|
+
# Check an interpolated string for dangerous values.
|
382
382
|
#
|
383
|
-
#This method assumes values interpolated into strings are unsafe by default,
|
384
|
-
#unless safe_value? explicitly returns true.
|
383
|
+
# This method assumes values interpolated into strings are unsafe by default,
|
384
|
+
# unless safe_value? explicitly returns true.
|
385
385
|
def check_string_interp arg
|
386
386
|
arg.each do |exp|
|
387
387
|
if dangerous = unsafe_string_interp?(exp)
|
@@ -392,7 +392,7 @@ class Railroader::CheckSQL < Railroader::BaseCheck
|
|
392
392
|
nil
|
393
393
|
end
|
394
394
|
|
395
|
-
#Returns value if interpolated value is not something safe
|
395
|
+
# Returns value if interpolated value is not something safe
|
396
396
|
def unsafe_string_interp? exp
|
397
397
|
if node_type? exp, :evstr
|
398
398
|
value = exp.value
|
@@ -426,10 +426,10 @@ class Railroader::CheckSQL < Railroader::BaseCheck
|
|
426
426
|
end
|
427
427
|
end
|
428
428
|
|
429
|
-
#Checks the given expression for unsafe SQL values. If an unsafe value is
|
430
|
-
#found, returns that value (may be the given _exp_ or a subexpression).
|
429
|
+
# Checks the given expression for unsafe SQL values. If an unsafe value is
|
430
|
+
# found, returns that value (may be the given _exp_ or a subexpression).
|
431
431
|
#
|
432
|
-
#Otherwise, returns false/nil.
|
432
|
+
# Otherwise, returns false/nil.
|
433
433
|
def unsafe_sql? exp, ignore_hash = false
|
434
434
|
return unless sexp?(exp)
|
435
435
|
|
@@ -437,17 +437,17 @@ class Railroader::CheckSQL < Railroader::BaseCheck
|
|
437
437
|
safe_value?(dangerous_value) ? false : dangerous_value
|
438
438
|
end
|
439
439
|
|
440
|
-
#Check _exp_ for dangerous values. Used by unsafe_sql?
|
440
|
+
# Check _exp_ for dangerous values. Used by unsafe_sql?
|
441
441
|
def find_dangerous_value exp, ignore_hash
|
442
442
|
case exp.node_type
|
443
443
|
when :lit, :str, :const, :colon2, :true, :false, :nil
|
444
444
|
nil
|
445
445
|
when :array
|
446
|
-
#Assume this is an array like
|
446
|
+
# Assume this is an array like
|
447
447
|
#
|
448
448
|
# ["blah = ? AND thing = ?", ...]
|
449
449
|
#
|
450
|
-
#and check first value
|
450
|
+
# and check first value
|
451
451
|
unsafe_sql? exp[1]
|
452
452
|
when :dstr
|
453
453
|
check_string_interp exp
|
@@ -482,7 +482,7 @@ class Railroader::CheckSQL < Railroader::BaseCheck
|
|
482
482
|
end
|
483
483
|
end
|
484
484
|
|
485
|
-
#Checks hash values associated with these keys:
|
485
|
+
# Checks hash values associated with these keys:
|
486
486
|
#
|
487
487
|
# * conditions
|
488
488
|
# * order
|
@@ -627,7 +627,7 @@ class Railroader::CheckSQL < Railroader::BaseCheck
|
|
627
627
|
call? exp and (AREL_METHODS.include? exp.method or arel? exp.target)
|
628
628
|
end
|
629
629
|
|
630
|
-
#Check call for string building
|
630
|
+
# Check call for string building
|
631
631
|
def check_call exp
|
632
632
|
return unless call? exp
|
633
633
|
unsafe = check_for_string_building exp
|
@@ -649,10 +649,10 @@ class Railroader::CheckSQL < Railroader::BaseCheck
|
|
649
649
|
end
|
650
650
|
end
|
651
651
|
|
652
|
-
#Prior to Rails 2.1.1, the :offset and :limit parameters were not
|
653
|
-
#escaping input properly.
|
652
|
+
# Prior to Rails 2.1.1, the :offset and :limit parameters were not
|
653
|
+
# escaping input properly.
|
654
654
|
#
|
655
|
-
#http://www.rorsecurity.info/2008/09/08/sql-injection-issue-in-limit-and-offset-parameter/
|
655
|
+
# http://www.rorsecurity.info/2008/09/08/sql-injection-issue-in-limit-and-offset-parameter/
|
656
656
|
def check_for_limit_or_offset_vulnerability options
|
657
657
|
return false if rails_version.nil? or rails_version >= "2.1.1" or not hash?(options)
|
658
658
|
|
@@ -661,7 +661,7 @@ class Railroader::CheckSQL < Railroader::BaseCheck
|
|
661
661
|
false
|
662
662
|
end
|
663
663
|
|
664
|
-
#Look for something like this:
|
664
|
+
# Look for something like this:
|
665
665
|
#
|
666
666
|
# params[:x].constantize.find('something')
|
667
667
|
#
|
@@ -1,13 +1,13 @@
|
|
1
1
|
require 'railroader/checks/base_check'
|
2
2
|
|
3
|
-
#Check for uses of strip_tags in Rails versions before 3.0.17, 3.1.8, 3.2.8 (including 2.3.x):
|
4
|
-
#https://groups.google.com/d/topic/rubyonrails-security/FgVEtBajcTY/discussion
|
3
|
+
# Check for uses of strip_tags in Rails versions before 3.0.17, 3.1.8, 3.2.8 (including 2.3.x):
|
4
|
+
# https://groups.google.com/d/topic/rubyonrails-security/FgVEtBajcTY/discussion
|
5
5
|
#
|
6
|
-
#Check for uses of strip_tags in Rails versions before 2.3.13 and 3.0.10:
|
7
|
-
#http://groups.google.com/group/rubyonrails-security/browse_thread/thread/2b9130749b74ea12
|
6
|
+
# Check for uses of strip_tags in Rails versions before 2.3.13 and 3.0.10:
|
7
|
+
# http://groups.google.com/group/rubyonrails-security/browse_thread/thread/2b9130749b74ea12
|
8
8
|
#
|
9
|
-
#Check for user of strip_tags with rails-html-sanitizer 1.0.2:
|
10
|
-
#https://groups.google.com/d/msg/rubyonrails-security/OU9ugTZcbjc/PjEP46pbFQAJ
|
9
|
+
# Check for user of strip_tags with rails-html-sanitizer 1.0.2:
|
10
|
+
# https://groups.google.com/d/msg/rubyonrails-security/OU9ugTZcbjc/PjEP46pbFQAJ
|
11
11
|
class Railroader::CheckStripTags < Railroader::BaseCheck
|
12
12
|
Railroader::Checks.add self
|
13
13
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'railroader/checks/base_check'
|
2
2
|
|
3
|
-
#Check for vulnerability in translate() helper that allows cross-site scripting
|
3
|
+
# Check for vulnerability in translate() helper that allows cross-site scripting
|
4
4
|
class Railroader::CheckTranslateBug < Railroader::BaseCheck
|
5
5
|
Railroader::Checks.add self
|
6
6
|
|
@@ -14,7 +14,7 @@ class Railroader::CheckTranslateBug < Railroader::BaseCheck
|
|
14
14
|
|
15
15
|
confidence = if uses_translate?
|
16
16
|
:high
|
17
|
-
|
17
|
+
else
|
18
18
|
:medium
|
19
19
|
end
|
20
20
|
|
@@ -22,9 +22,9 @@ class Railroader::CheckTranslateBug < Railroader::BaseCheck
|
|
22
22
|
|
23
23
|
message = if rails_version =~ /^3\.1/
|
24
24
|
"Versions before 3.1.2 #{description}."
|
25
|
-
|
25
|
+
elsif rails_version =~ /^3\.0/
|
26
26
|
"Versions before 3.0.11 #{description}."
|
27
|
-
|
27
|
+
else
|
28
28
|
"Rails 2.3.x using the rails_xss plugin #{description}."
|
29
29
|
end
|
30
30
|
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'railroader/checks/base_check'
|
2
2
|
|
3
|
-
#Reports any calls to +validates_format_of+ which do not use +\A+ and +\z+
|
4
|
-
#as anchors in the given regular expression.
|
3
|
+
# Reports any calls to +validates_format_of+ which do not use +\A+ and +\z+
|
4
|
+
# as anchors in the given regular expression.
|
5
5
|
#
|
6
|
-
#For example:
|
6
|
+
# For example:
|
7
7
|
#
|
8
8
|
# #Allows anything after new line
|
9
9
|
# validates_format_of :user_name, :with => /^\w+$/
|
@@ -36,14 +36,14 @@ class Railroader::CheckValidationRegex < Railroader::BaseCheck
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
#Check validates_format_of
|
39
|
+
# Check validates_format_of
|
40
40
|
def process_validates_format_of validator
|
41
41
|
if value = hash_access(validator.last, WITH)
|
42
42
|
check_regex value, validator
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
-
#Check validates ..., :format => ...
|
46
|
+
# Check validates ..., :format => ...
|
47
47
|
def process_validates validator
|
48
48
|
hash_arg = validator.last
|
49
49
|
return unless hash? hash_arg
|
@@ -79,7 +79,7 @@ class Railroader::CheckValidationRegex < Railroader::BaseCheck
|
|
79
79
|
\z
|
80
80
|
}mx
|
81
81
|
|
82
|
-
#Issue warning if the regular expression does not use
|
82
|
+
# Issue warning if the regular expression does not use
|
83
83
|
#+\A+ and +\z+
|
84
84
|
def check_regex value, validator
|
85
85
|
return unless regexp? value
|
@@ -95,7 +95,7 @@ class Railroader::CheckValidationRegex < Railroader::BaseCheck
|
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
98
|
-
#Get the name of the attribute being validated.
|
98
|
+
# Get the name of the attribute being validated.
|
99
99
|
def get_name validator
|
100
100
|
name = validator[1]
|
101
101
|
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'railroader/checks/base_check'
|
2
2
|
|
3
|
-
#Check for bypassing mass assignment protection
|
4
|
-
#with without_protection => true
|
3
|
+
# Check for bypassing mass assignment protection
|
4
|
+
# with without_protection => true
|
5
5
|
#
|
6
|
-
#Only for Rails 3.1
|
6
|
+
# Only for Rails 3.1
|
7
7
|
class Railroader::CheckWithoutProtection < Railroader::BaseCheck
|
8
8
|
Railroader::Checks.add self
|
9
9
|
|
@@ -18,8 +18,8 @@ class Railroader::CheckWithoutProtection < Railroader::BaseCheck
|
|
18
18
|
|
19
19
|
Railroader.debug "Finding all mass assignments"
|
20
20
|
calls = tracker.find_call :targets => active_record_models.keys, :methods => [:new,
|
21
|
-
:attributes=,
|
22
|
-
:update_attributes,
|
21
|
+
:attributes=,
|
22
|
+
:update_attributes,
|
23
23
|
:update_attributes!,
|
24
24
|
:create,
|
25
25
|
:create!]
|
@@ -30,7 +30,7 @@ class Railroader::CheckWithoutProtection < Railroader::BaseCheck
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
#All results should be Model.new(...) or Model.attributes=() calls
|
33
|
+
# All results should be Model.new(...) or Model.attributes=() calls
|
34
34
|
def process_result res
|
35
35
|
call = res[:call]
|
36
36
|
last_arg = call.last_arg
|
@@ -49,11 +49,11 @@ class Railroader::CheckWithoutProtection < Railroader::BaseCheck
|
|
49
49
|
confidence = :medium
|
50
50
|
end
|
51
51
|
|
52
|
-
warn :result => res,
|
53
|
-
:warning_type => "Mass Assignment",
|
52
|
+
warn :result => res,
|
53
|
+
:warning_type => "Mass Assignment",
|
54
54
|
:warning_code => :mass_assign_without_protection,
|
55
55
|
:message => "Unprotected mass assignment",
|
56
|
-
:code => call,
|
56
|
+
:code => call,
|
57
57
|
:user_input => input,
|
58
58
|
:confidence => confidence
|
59
59
|
|
@@ -32,7 +32,7 @@ class Railroader::CheckYAMLParsing < Railroader::BaseCheck
|
|
32
32
|
:link_path => "https://groups.google.com/d/topic/rubyonrails-security/61bkgvnSGTQ/discussion"
|
33
33
|
end
|
34
34
|
|
35
|
-
#Warn if app accepts YAML
|
35
|
+
# Warn if app accepts YAML
|
36
36
|
if version_between?("0.0.0", "2.3.14") and enabled_yaml_parser?
|
37
37
|
message = "Parsing YAML request parameters enables remote code execution: disable YAML parser"
|
38
38
|
|
@@ -47,14 +47,14 @@ class Railroader::CheckYAMLParsing < Railroader::BaseCheck
|
|
47
47
|
|
48
48
|
def disabled_xml_parser?
|
49
49
|
if version_between? "0.0.0", "2.3.14"
|
50
|
-
#Look for ActionController::Base.param_parsers.delete(Mime::XML)
|
50
|
+
# Look for ActionController::Base.param_parsers.delete(Mime::XML)
|
51
51
|
params_parser = s(:call,
|
52
52
|
s(:colon2, s(:const, :ActionController), :Base),
|
53
53
|
:param_parsers)
|
54
54
|
|
55
55
|
matches = tracker.check_initializers(params_parser, :delete)
|
56
56
|
else
|
57
|
-
#Look for ActionDispatch::ParamsParser::DEFAULT_PARSERS.delete(Mime::XML)
|
57
|
+
# Look for ActionDispatch::ParamsParser::DEFAULT_PARSERS.delete(Mime::XML)
|
58
58
|
matches = tracker.check_initializers(:"ActionDispatch::ParamsParser::DEFAULT_PARSERS", :delete)
|
59
59
|
end
|
60
60
|
|
@@ -71,8 +71,8 @@ class Railroader::CheckYAMLParsing < Railroader::BaseCheck
|
|
71
71
|
false
|
72
72
|
end
|
73
73
|
|
74
|
-
#Look for ActionController::Base.param_parsers[Mime::YAML] = :yaml
|
75
|
-
#in Rails 2.x apps
|
74
|
+
# Look for ActionController::Base.param_parsers[Mime::YAML] = :yaml
|
75
|
+
# in Rails 2.x apps
|
76
76
|
def enabled_yaml_parser?
|
77
77
|
param_parsers = s(:call,
|
78
78
|
s(:colon2, s(:const, :ActionController), :Base),
|