brakeman-min 0.5.2 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (152) hide show
  1. data/CHANGES +529 -0
  2. data/README.md +74 -28
  3. data/bin/brakeman +60 -266
  4. data/lib/brakeman.rb +422 -0
  5. data/lib/brakeman/app_tree.rb +101 -0
  6. data/lib/brakeman/brakeman.rake +10 -0
  7. data/lib/brakeman/call_index.rb +215 -0
  8. data/lib/brakeman/checks.rb +180 -0
  9. data/lib/brakeman/checks/base_check.rb +538 -0
  10. data/lib/brakeman/checks/check_basic_auth.rb +89 -0
  11. data/lib/brakeman/checks/check_content_tag.rb +162 -0
  12. data/lib/brakeman/checks/check_cross_site_scripting.rb +334 -0
  13. data/lib/{checks → brakeman/checks}/check_default_routes.rb +13 -6
  14. data/lib/brakeman/checks/check_deserialize.rb +57 -0
  15. data/lib/brakeman/checks/check_digest_dos.rb +38 -0
  16. data/lib/brakeman/checks/check_escape_function.rb +21 -0
  17. data/lib/brakeman/checks/check_evaluation.rb +33 -0
  18. data/lib/brakeman/checks/check_execute.rb +98 -0
  19. data/lib/brakeman/checks/check_file_access.rb +62 -0
  20. data/lib/brakeman/checks/check_filter_skipping.rb +31 -0
  21. data/lib/brakeman/checks/check_forgery_setting.rb +54 -0
  22. data/lib/brakeman/checks/check_jruby_xml.rb +38 -0
  23. data/lib/brakeman/checks/check_json_parsing.rb +102 -0
  24. data/lib/brakeman/checks/check_link_to.rb +132 -0
  25. data/lib/brakeman/checks/check_link_to_href.rb +92 -0
  26. data/lib/{checks → brakeman/checks}/check_mail_to.rb +14 -13
  27. data/lib/brakeman/checks/check_mass_assignment.rb +143 -0
  28. data/lib/brakeman/checks/check_model_attr_accessible.rb +48 -0
  29. data/lib/brakeman/checks/check_model_attributes.rb +118 -0
  30. data/lib/brakeman/checks/check_model_serialize.rb +66 -0
  31. data/lib/{checks → brakeman/checks}/check_nested_attributes.rb +10 -6
  32. data/lib/brakeman/checks/check_quote_table_name.rb +40 -0
  33. data/lib/brakeman/checks/check_redirect.rb +177 -0
  34. data/lib/brakeman/checks/check_render.rb +62 -0
  35. data/lib/brakeman/checks/check_response_splitting.rb +21 -0
  36. data/lib/brakeman/checks/check_safe_buffer_manipulation.rb +31 -0
  37. data/lib/brakeman/checks/check_sanitize_methods.rb +54 -0
  38. data/lib/brakeman/checks/check_select_tag.rb +60 -0
  39. data/lib/brakeman/checks/check_select_vulnerability.rb +58 -0
  40. data/lib/brakeman/checks/check_send.rb +35 -0
  41. data/lib/brakeman/checks/check_send_file.rb +19 -0
  42. data/lib/brakeman/checks/check_session_settings.rb +145 -0
  43. data/lib/brakeman/checks/check_single_quotes.rb +101 -0
  44. data/lib/brakeman/checks/check_skip_before_filter.rb +62 -0
  45. data/lib/brakeman/checks/check_sql.rb +577 -0
  46. data/lib/brakeman/checks/check_strip_tags.rb +64 -0
  47. data/lib/brakeman/checks/check_symbol_dos.rb +67 -0
  48. data/lib/brakeman/checks/check_translate_bug.rb +45 -0
  49. data/lib/brakeman/checks/check_unsafe_reflection.rb +51 -0
  50. data/lib/brakeman/checks/check_validation_regex.rb +88 -0
  51. data/lib/brakeman/checks/check_without_protection.rb +64 -0
  52. data/lib/brakeman/checks/check_yaml_parsing.rb +121 -0
  53. data/lib/brakeman/differ.rb +66 -0
  54. data/lib/{format → brakeman/format}/style.css +28 -0
  55. data/lib/brakeman/options.rb +256 -0
  56. data/lib/brakeman/parsers/rails2_erubis.rb +6 -0
  57. data/lib/brakeman/parsers/rails2_xss_plugin_erubis.rb +48 -0
  58. data/lib/{scanner_erubis.rb → brakeman/parsers/rails3_erubis.rb} +8 -21
  59. data/lib/brakeman/processor.rb +102 -0
  60. data/lib/brakeman/processors/alias_processor.rb +780 -0
  61. data/lib/{processors → brakeman/processors}/base_processor.rb +90 -74
  62. data/lib/brakeman/processors/config_processor.rb +14 -0
  63. data/lib/brakeman/processors/controller_alias_processor.rb +334 -0
  64. data/lib/brakeman/processors/controller_processor.rb +265 -0
  65. data/lib/{processors → brakeman/processors}/erb_template_processor.rb +21 -19
  66. data/lib/brakeman/processors/erubis_template_processor.rb +96 -0
  67. data/lib/brakeman/processors/gem_processor.rb +59 -0
  68. data/lib/{processors → brakeman/processors}/haml_template_processor.rb +26 -21
  69. data/lib/brakeman/processors/lib/find_all_calls.rb +185 -0
  70. data/lib/{processors → brakeman/processors}/lib/find_call.rb +23 -28
  71. data/lib/brakeman/processors/lib/find_return_value.rb +134 -0
  72. data/lib/brakeman/processors/lib/processor_helper.rb +82 -0
  73. data/lib/{processors/config_processor.rb → brakeman/processors/lib/rails2_config_processor.rb} +32 -35
  74. data/lib/{processors → brakeman/processors}/lib/rails2_route_processor.rb +60 -52
  75. data/lib/brakeman/processors/lib/rails3_config_processor.rb +129 -0
  76. data/lib/brakeman/processors/lib/rails3_route_processor.rb +282 -0
  77. data/lib/{processors → brakeman/processors}/lib/render_helper.rb +54 -20
  78. data/lib/brakeman/processors/lib/route_helper.rb +62 -0
  79. data/lib/{processors → brakeman/processors}/library_processor.rb +24 -17
  80. data/lib/{processors → brakeman/processors}/model_processor.rb +46 -22
  81. data/lib/{processors → brakeman/processors}/output_processor.rb +34 -40
  82. data/lib/brakeman/processors/route_processor.rb +17 -0
  83. data/lib/brakeman/processors/slim_template_processor.rb +113 -0
  84. data/lib/brakeman/processors/template_alias_processor.rb +120 -0
  85. data/lib/{processors → brakeman/processors}/template_processor.rb +10 -7
  86. data/lib/brakeman/report.rb +68 -0
  87. data/lib/brakeman/report/ignore/config.rb +130 -0
  88. data/lib/brakeman/report/ignore/interactive.rb +311 -0
  89. data/lib/brakeman/report/initializers/faster_csv.rb +7 -0
  90. data/lib/brakeman/report/initializers/multi_json.rb +29 -0
  91. data/lib/brakeman/report/renderer.rb +24 -0
  92. data/lib/brakeman/report/report_base.rb +279 -0
  93. data/lib/brakeman/report/report_csv.rb +56 -0
  94. data/lib/brakeman/report/report_hash.rb +22 -0
  95. data/lib/brakeman/report/report_html.rb +203 -0
  96. data/lib/brakeman/report/report_json.rb +46 -0
  97. data/lib/brakeman/report/report_table.rb +109 -0
  98. data/lib/brakeman/report/report_tabs.rb +17 -0
  99. data/lib/brakeman/report/templates/controller_overview.html.erb +18 -0
  100. data/lib/brakeman/report/templates/controller_warnings.html.erb +17 -0
  101. data/lib/brakeman/report/templates/error_overview.html.erb +25 -0
  102. data/lib/brakeman/report/templates/header.html.erb +44 -0
  103. data/lib/brakeman/report/templates/ignored_warnings.html.erb +21 -0
  104. data/lib/brakeman/report/templates/model_warnings.html.erb +17 -0
  105. data/lib/brakeman/report/templates/overview.html.erb +34 -0
  106. data/lib/brakeman/report/templates/security_warnings.html.erb +19 -0
  107. data/lib/brakeman/report/templates/template_overview.html.erb +17 -0
  108. data/lib/brakeman/report/templates/view_warnings.html.erb +30 -0
  109. data/lib/brakeman/report/templates/warning_overview.html.erb +13 -0
  110. data/lib/brakeman/rescanner.rb +446 -0
  111. data/lib/brakeman/scanner.rb +362 -0
  112. data/lib/brakeman/tracker.rb +296 -0
  113. data/lib/brakeman/util.rb +413 -0
  114. data/lib/brakeman/version.rb +3 -0
  115. data/lib/brakeman/warning.rb +217 -0
  116. data/lib/brakeman/warning_codes.rb +68 -0
  117. data/lib/ruby_parser/bm_sexp.rb +562 -0
  118. data/lib/ruby_parser/bm_sexp_processor.rb +230 -0
  119. metadata +152 -66
  120. data/lib/checks.rb +0 -71
  121. data/lib/checks/base_check.rb +0 -357
  122. data/lib/checks/check_cross_site_scripting.rb +0 -336
  123. data/lib/checks/check_evaluation.rb +0 -27
  124. data/lib/checks/check_execute.rb +0 -110
  125. data/lib/checks/check_file_access.rb +0 -46
  126. data/lib/checks/check_forgery_setting.rb +0 -42
  127. data/lib/checks/check_mass_assignment.rb +0 -74
  128. data/lib/checks/check_model_attributes.rb +0 -36
  129. data/lib/checks/check_redirect.rb +0 -98
  130. data/lib/checks/check_render.rb +0 -65
  131. data/lib/checks/check_send_file.rb +0 -15
  132. data/lib/checks/check_session_settings.rb +0 -79
  133. data/lib/checks/check_sql.rb +0 -146
  134. data/lib/checks/check_validation_regex.rb +0 -60
  135. data/lib/processor.rb +0 -86
  136. data/lib/processors/alias_processor.rb +0 -384
  137. data/lib/processors/controller_alias_processor.rb +0 -237
  138. data/lib/processors/controller_processor.rb +0 -202
  139. data/lib/processors/erubis_template_processor.rb +0 -85
  140. data/lib/processors/lib/find_model_call.rb +0 -39
  141. data/lib/processors/lib/processor_helper.rb +0 -36
  142. data/lib/processors/lib/rails3_route_processor.rb +0 -184
  143. data/lib/processors/lib/route_helper.rb +0 -34
  144. data/lib/processors/params_processor.rb +0 -77
  145. data/lib/processors/route_processor.rb +0 -11
  146. data/lib/processors/template_alias_processor.rb +0 -86
  147. data/lib/report.rb +0 -680
  148. data/lib/scanner.rb +0 -227
  149. data/lib/tracker.rb +0 -144
  150. data/lib/util.rb +0 -141
  151. data/lib/version.rb +0 -1
  152. data/lib/warning.rb +0 -99
@@ -0,0 +1,62 @@
1
+ require 'brakeman/checks/base_check'
2
+
3
+ #Check calls to +render()+ for dangerous values
4
+ class Brakeman::CheckRender < Brakeman::BaseCheck
5
+ Brakeman::Checks.add self
6
+
7
+ @description = "Finds calls to render that might allow file access"
8
+
9
+ def run_check
10
+ tracker.find_call(:target => nil, :method => :render).each do |result|
11
+ process_render result
12
+ end
13
+ end
14
+
15
+ def process_render result
16
+ return unless node_type? result[:call], :render
17
+
18
+ case result[:call].render_type
19
+ when :partial, :template, :action, :file
20
+ check_for_dynamic_path result
21
+ when :inline
22
+ when :js
23
+ when :json
24
+ when :text
25
+ when :update
26
+ when :xml
27
+ end
28
+ end
29
+
30
+ #Check if path to action or file is determined dynamically
31
+ def check_for_dynamic_path result
32
+ view = result[:call][2]
33
+
34
+ if sexp? view and not duplicate? result
35
+ add_result result
36
+
37
+
38
+ if input = has_immediate_user_input?(view)
39
+ confidence = CONFIDENCE[:high]
40
+ elsif input = include_user_input?(view)
41
+ if node_type? view, :string_interp, :dstr
42
+ confidence = CONFIDENCE[:med]
43
+ else
44
+ confidence = CONFIDENCE[:low]
45
+ end
46
+ else
47
+ return
48
+ end
49
+
50
+ return if input.type == :model #skip models
51
+
52
+ message = "Render path contains #{friendly_type_of input}"
53
+
54
+ warn :result => result,
55
+ :warning_type => "Dynamic Render Path",
56
+ :warning_code => :dynamic_render_path,
57
+ :message => message,
58
+ :user_input => input.match,
59
+ :confidence => confidence
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,21 @@
1
+ require 'brakeman/checks/base_check'
2
+
3
+ #Warn about response splitting in Rails versions before 2.3.13
4
+ #http://groups.google.com/group/rubyonrails-security/browse_thread/thread/6ffc93bde0298768
5
+ class Brakeman::CheckResponseSplitting < Brakeman::BaseCheck
6
+ Brakeman::Checks.add self
7
+
8
+ @description = "Report response splitting in Rails 2.3.0 - 2.3.13"
9
+
10
+ def run_check
11
+ if version_between?('2.3.0', '2.3.13')
12
+
13
+ warn :warning_type => "Response Splitting",
14
+ :warning_code => :CVE_2011_3186,
15
+ :message => "Versions before 2.3.14 have a vulnerability content type handling allowing injection of headers: CVE-2011-3186",
16
+ :confidence => CONFIDENCE[:med],
17
+ :file => gemfile_or_environment,
18
+ :link_path => "https://groups.google.com/d/topic/rubyonrails-security/b_yTveAph2g/discussion"
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,31 @@
1
+ require 'brakeman/checks/base_check'
2
+
3
+ #Check for unsafe manipulation of strings
4
+ #Right now this is just a version check for
5
+ #https://groups.google.com/group/rubyonrails-security/browse_thread/thread/edd28f1e3d04e913?pli=1
6
+ class Brakeman::CheckSafeBufferManipulation < Brakeman::BaseCheck
7
+ Brakeman::Checks.add self
8
+
9
+ @description = "Check for Rails versions with SafeBuffer bug"
10
+
11
+ def run_check
12
+
13
+ if version_between? "3.0.0", "3.0.11"
14
+ suggested_version = "3.0.12"
15
+ elsif version_between? "3.1.0", "3.1.3"
16
+ suggested_version = "3.1.4"
17
+ elsif version_between? "3.2.0", "3.2.1"
18
+ suggested_version = "3.2.2"
19
+ else
20
+ return
21
+ end
22
+
23
+ message = "Rails #{tracker.config[:rails_version]} has a vulnerabilty in SafeBuffer. Upgrade to #{suggested_version} or apply patches."
24
+
25
+ warn :warning_type => "Cross Site Scripting",
26
+ :warning_code => :safe_buffer_vuln,
27
+ :message => message,
28
+ :confidence => CONFIDENCE[:med],
29
+ :file => gemfile_or_environment
30
+ end
31
+ end
@@ -0,0 +1,54 @@
1
+ require 'brakeman/checks/base_check'
2
+
3
+ #sanitize and sanitize_css are vulnerable:
4
+ #CVE-2013-1855 and CVE-2013-1857
5
+ class Brakeman::CheckSanitizeMethods < Brakeman::BaseCheck
6
+ Brakeman::Checks.add self
7
+
8
+ @description = "Checks for versions with vulnerable sanitize and sanitize_css"
9
+
10
+ def run_check
11
+ @fix_version = case
12
+ when version_between?('2.0.0', '2.3.17')
13
+ '2.3.18'
14
+ when version_between?('3.0.0', '3.0.99')
15
+ '3.2.13'
16
+ when version_between?('3.1.0', '3.1.11')
17
+ '3.1.12'
18
+ when version_between?('3.2.0', '3.2.12')
19
+ '3.2.13'
20
+ else
21
+ return
22
+ end
23
+
24
+ check_cve_2013_1855
25
+ check_cve_2013_1857
26
+ end
27
+
28
+ def check_cve_2013_1855
29
+ check_for_cve :sanitize_css, :CVE_2013_1855, "https://groups.google.com/d/msg/rubyonrails-security/4_QHo4BqnN8/_RrdfKk12I4J"
30
+ end
31
+
32
+ def check_cve_2013_1857
33
+ check_for_cve :sanitize, :CVE_2013_1857, "https://groups.google.com/d/msg/rubyonrails-security/zAAU7vGTPvI/1vZDWXqBuXgJ"
34
+ end
35
+
36
+ def check_for_cve method, code, link
37
+ tracker.find_call(:target => false, :method => method).each do |result|
38
+ message = "Rails #{tracker.config[:rails_version]} has a vulnerability in #{method}: upgrade to #{@fix_version} or patch"
39
+
40
+ if include_user_input? result[:call]
41
+ confidence = CONFIDENCE[:high]
42
+ else
43
+ confidence = CONFIDENCE[:medium]
44
+ end
45
+
46
+ warn :result => result,
47
+ :warning_type => "Cross Site Scripting",
48
+ :warning_code => code,
49
+ :message => message,
50
+ :confidence => CONFIDENCE[:high],
51
+ :link_path => link
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,60 @@
1
+ require 'brakeman/checks/base_check'
2
+
3
+ #Checks for CVE-2012-3463, unescaped input in :prompt option of select_tag:
4
+ #https://groups.google.com/d/topic/rubyonrails-security/fV3QUToSMSw/discussion
5
+ class Brakeman::CheckSelectTag < Brakeman::BaseCheck
6
+ Brakeman::Checks.add self
7
+
8
+ @description = "Looks for unsafe uses of select_tag() in some versions of Rails 3.x"
9
+
10
+ def run_check
11
+
12
+ if version_between? "3.0.0", "3.0.16"
13
+ suggested_version = "3.0.17"
14
+ elsif version_between? "3.1.0", "3.1.7"
15
+ suggested_version = "3.1.8"
16
+ elsif version_between? "3.2.0", "3.2.7"
17
+ suggested_version = "3.2.8"
18
+ else
19
+ return
20
+ end
21
+
22
+ @ignore_methods = Set[:escapeHTML, :escape_once, :h].merge tracker.options[:safe_methods]
23
+
24
+ @message = "Upgrade to Rails #{suggested_version}, #{tracker.config[:rails_version]} select_tag is vulnerable (CVE-2012-3463)"
25
+
26
+ calls = tracker.find_call(:target => nil, :method => :select_tag).select do |result|
27
+ result[:location][:type] == :template
28
+ end
29
+
30
+ calls.each do |result|
31
+ process_result result
32
+ end
33
+ end
34
+
35
+ #Check if select_tag is called with user input in :prompt option
36
+ def process_result result
37
+ return if duplicate? result
38
+ add_result result
39
+
40
+ #Only concerned if user input is supplied for :prompt option
41
+ last_arg = result[:call].last_arg
42
+
43
+ if hash? last_arg
44
+ prompt_option = hash_access last_arg, :prompt
45
+
46
+ if call? prompt_option and @ignore_methods.include? prompt_option.method
47
+ return
48
+ elsif sexp? prompt_option and input = include_user_input?(prompt_option)
49
+
50
+ warn :warning_type => "Cross Site Scripting",
51
+ :warning_code => :CVE_2012_3463,
52
+ :result => result,
53
+ :message => @message,
54
+ :confidence => CONFIDENCE[:high],
55
+ :user_input => input.match,
56
+ :link_path => "https://groups.google.com/d/topic/rubyonrails-security/fV3QUToSMSw/discussion"
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,58 @@
1
+ require 'brakeman/checks/base_check'
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
5
+ class Brakeman::CheckSelectVulnerability < Brakeman::BaseCheck
6
+ Brakeman::Checks.add self
7
+
8
+ @description = "Looks for unsafe uses of select() helper"
9
+
10
+ def run_check
11
+
12
+ if version_between? "3.0.0", "3.0.11"
13
+ suggested_version = "3.0.12"
14
+ elsif version_between? "3.1.0", "3.1.3"
15
+ suggested_version = "3.1.4"
16
+ elsif version_between? "3.2.0", "3.2.1"
17
+ suggested_version = "3.2.2"
18
+ elsif version_between? "2.0.0", "2.3.14"
19
+ suggested_version = "3 or use options_for_select"
20
+ else
21
+ return
22
+ end
23
+
24
+ @message = "Upgrade to Rails #{suggested_version}, #{tracker.config[:rails_version]} select() helper is vulnerable"
25
+
26
+ calls = tracker.find_call(:target => nil, :method => :select).select do |result|
27
+ result[:location][:type] == :template
28
+ end
29
+
30
+ calls.each do |result|
31
+ process_result result
32
+ end
33
+ end
34
+
35
+ def process_result result
36
+ return if duplicate? result
37
+
38
+ third_arg = result[:call].third_arg
39
+
40
+ #Check for user input in options parameter
41
+ if sexp? third_arg and include_user_input? third_arg
42
+ add_result result
43
+
44
+ if node_type? third_arg, :string_interp, :dstr
45
+ confidence = CONFIDENCE[:med]
46
+ else
47
+ confidence = CONFIDENCE[:low]
48
+ end
49
+
50
+ warn :template => result[:location][:template],
51
+ :warning_type => "Cross Site Scripting",
52
+ :warning_code => :select_options_vuln,
53
+ :result => result,
54
+ :message => @message,
55
+ :confidence => confidence
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,35 @@
1
+ require 'brakeman/checks/base_check'
2
+
3
+ #Checks if user supplied data is passed to send
4
+ class Brakeman::CheckSend < Brakeman::BaseCheck
5
+ Brakeman::Checks.add self
6
+
7
+ @description = "Check for unsafe use of Object#send"
8
+
9
+ def run_check
10
+ Brakeman.debug("Finding instances of #send")
11
+ calls = tracker.find_call :methods => [:send, :try, :__send__, :public_send]
12
+
13
+ calls.each do |call|
14
+ process_result call
15
+ end
16
+ end
17
+
18
+ def process_result result
19
+ return if duplicate? result or result[:call].original_line
20
+ add_result result
21
+
22
+ process_call_args result[:call]
23
+ target = process result[:call].target
24
+
25
+ if input = has_immediate_user_input?(result[:call].first_arg)
26
+ warn :result => result,
27
+ :warning_type => "Dangerous Send",
28
+ :warning_code => :dangerous_send,
29
+ :message => "User controlled method execution",
30
+ :code => result[:call],
31
+ :user_input => input.match,
32
+ :confidence => CONFIDENCE[:high]
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,19 @@
1
+ require 'brakeman/checks/check_file_access'
2
+ require 'brakeman/processors/lib/processor_helper'
3
+
4
+ #Checks for user input in send_file()
5
+ class Brakeman::CheckSendFile < Brakeman::CheckFileAccess
6
+ Brakeman::Checks.add self
7
+
8
+ @description = "Check for user input in uses of send_file"
9
+
10
+ def run_check
11
+ Brakeman.debug "Finding all calls to send_file()"
12
+
13
+ methods = tracker.find_call :target => false, :method => :send_file
14
+
15
+ methods.each do |call|
16
+ process_result call
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,145 @@
1
+ require 'brakeman/checks/base_check'
2
+
3
+ #Checks for session key length and http_only settings
4
+ class Brakeman::CheckSessionSettings < Brakeman::BaseCheck
5
+ Brakeman::Checks.add self
6
+
7
+ @description = "Checks for session key length and http_only settings"
8
+
9
+ def initialize *args
10
+ super
11
+
12
+ unless tracker.options[:rails3]
13
+ @session_settings = Sexp.new(:colon2, Sexp.new(:const, :ActionController), :Base)
14
+ else
15
+ @session_settings = nil
16
+ end
17
+ end
18
+
19
+ def run_check
20
+ settings = tracker.config[:rails][:action_controller] &&
21
+ tracker.config[:rails][:action_controller][:session]
22
+
23
+ check_for_issues settings, "#{tracker.options[:app_path]}/config/environment.rb"
24
+
25
+ ["session_store.rb", "secret_token.rb"].each do |file|
26
+ if tracker.initializers[file] and not ignored? file
27
+ process tracker.initializers[file]
28
+ end
29
+ end
30
+ end
31
+
32
+ #Looks for ActionController::Base.session = { ... }
33
+ #in Rails 2.x apps
34
+ #
35
+ #and App::Application.config.secret_token =
36
+ #in Rails 3.x apps
37
+ #
38
+ #and App::Application.config.secret_key_base =
39
+ #in Rails 4.x apps
40
+ def process_attrasgn exp
41
+ if not tracker.options[:rails3] and exp.target == @session_settings and exp.method == :session=
42
+ check_for_issues exp.first_arg, "#{tracker.options[:app_path]}/config/initializers/session_store.rb"
43
+ end
44
+
45
+ if tracker.options[:rails3] and settings_target?(exp.target) and
46
+ (exp.method == :secret_token= or exp.method == :secret_key_base=) and string? exp.first_arg
47
+
48
+ warn_about_secret_token exp, "#{tracker.options[:app_path]}/config/initializers/secret_token.rb"
49
+ end
50
+
51
+ exp
52
+ end
53
+
54
+ #Looks for Rails3::Application.config.session_store :cookie_store, { ... }
55
+ #in Rails 3.x apps
56
+ def process_call exp
57
+ if tracker.options[:rails3] and settings_target?(exp.target) and exp.method == :session_store
58
+ check_for_rails3_issues exp.second_arg, "#{tracker.options[:app_path]}/config/initializers/session_store.rb"
59
+ end
60
+
61
+ exp
62
+ end
63
+
64
+ private
65
+
66
+ def settings_target? exp
67
+ call? exp and
68
+ exp.method == :config and
69
+ node_type? exp.target, :colon2 and
70
+ exp.target.rhs == :Application
71
+ end
72
+
73
+ def check_for_issues settings, file
74
+ if settings and hash? settings
75
+ if value = (hash_access(settings, :session_http_only) ||
76
+ hash_access(settings, :http_only) ||
77
+ hash_access(settings, :httponly))
78
+
79
+ if false? value
80
+ warn_about_http_only value, file
81
+ end
82
+ end
83
+
84
+ if value = hash_access(settings, :secret)
85
+ if string? value
86
+ warn_about_secret_token value, file
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ def check_for_rails3_issues settings, file
93
+ if settings and hash? settings
94
+ if value = hash_access(settings, :httponly)
95
+ if false? value
96
+ warn_about_http_only value, file
97
+ end
98
+ end
99
+
100
+ if value = hash_access(settings, :secure)
101
+ if false? value
102
+ warn_about_secure_only value, file
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ def warn_about_http_only value, file
109
+ warn :warning_type => "Session Setting",
110
+ :warning_code => :http_cookies,
111
+ :message => "Session cookies should be set to HTTP only",
112
+ :confidence => CONFIDENCE[:high],
113
+ :line => value.line,
114
+ :file => file
115
+
116
+ end
117
+
118
+ def warn_about_secret_token value, file
119
+ warn :warning_type => "Session Setting",
120
+ :warning_code => :session_secret,
121
+ :message => "Session secret should not be included in version control",
122
+ :confidence => CONFIDENCE[:high],
123
+ :line => value.line,
124
+ :file => file
125
+ end
126
+
127
+ def warn_about_secure_only value, file
128
+ warn :warning_type => "Session Setting",
129
+ :warning_code => :secure_cookies,
130
+ :message => "Session cookie should be set to secure only",
131
+ :confidence => CONFIDENCE[:high],
132
+ :line => value.line,
133
+ :file => file
134
+ end
135
+
136
+ def ignored? file
137
+ if @app_tree.exists? ".gitignore"
138
+ input = @app_tree.read(".gitignore")
139
+
140
+ input.include? file
141
+ else
142
+ false
143
+ end
144
+ end
145
+ end