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.
- data/CHANGES +529 -0
- data/README.md +74 -28
- data/bin/brakeman +60 -266
- data/lib/brakeman.rb +422 -0
- data/lib/brakeman/app_tree.rb +101 -0
- data/lib/brakeman/brakeman.rake +10 -0
- data/lib/brakeman/call_index.rb +215 -0
- data/lib/brakeman/checks.rb +180 -0
- data/lib/brakeman/checks/base_check.rb +538 -0
- data/lib/brakeman/checks/check_basic_auth.rb +89 -0
- data/lib/brakeman/checks/check_content_tag.rb +162 -0
- data/lib/brakeman/checks/check_cross_site_scripting.rb +334 -0
- data/lib/{checks → brakeman/checks}/check_default_routes.rb +13 -6
- data/lib/brakeman/checks/check_deserialize.rb +57 -0
- data/lib/brakeman/checks/check_digest_dos.rb +38 -0
- data/lib/brakeman/checks/check_escape_function.rb +21 -0
- data/lib/brakeman/checks/check_evaluation.rb +33 -0
- data/lib/brakeman/checks/check_execute.rb +98 -0
- data/lib/brakeman/checks/check_file_access.rb +62 -0
- data/lib/brakeman/checks/check_filter_skipping.rb +31 -0
- data/lib/brakeman/checks/check_forgery_setting.rb +54 -0
- data/lib/brakeman/checks/check_jruby_xml.rb +38 -0
- data/lib/brakeman/checks/check_json_parsing.rb +102 -0
- data/lib/brakeman/checks/check_link_to.rb +132 -0
- data/lib/brakeman/checks/check_link_to_href.rb +92 -0
- data/lib/{checks → brakeman/checks}/check_mail_to.rb +14 -13
- data/lib/brakeman/checks/check_mass_assignment.rb +143 -0
- data/lib/brakeman/checks/check_model_attr_accessible.rb +48 -0
- data/lib/brakeman/checks/check_model_attributes.rb +118 -0
- data/lib/brakeman/checks/check_model_serialize.rb +66 -0
- data/lib/{checks → brakeman/checks}/check_nested_attributes.rb +10 -6
- data/lib/brakeman/checks/check_quote_table_name.rb +40 -0
- data/lib/brakeman/checks/check_redirect.rb +177 -0
- data/lib/brakeman/checks/check_render.rb +62 -0
- data/lib/brakeman/checks/check_response_splitting.rb +21 -0
- data/lib/brakeman/checks/check_safe_buffer_manipulation.rb +31 -0
- data/lib/brakeman/checks/check_sanitize_methods.rb +54 -0
- data/lib/brakeman/checks/check_select_tag.rb +60 -0
- data/lib/brakeman/checks/check_select_vulnerability.rb +58 -0
- data/lib/brakeman/checks/check_send.rb +35 -0
- data/lib/brakeman/checks/check_send_file.rb +19 -0
- data/lib/brakeman/checks/check_session_settings.rb +145 -0
- data/lib/brakeman/checks/check_single_quotes.rb +101 -0
- data/lib/brakeman/checks/check_skip_before_filter.rb +62 -0
- data/lib/brakeman/checks/check_sql.rb +577 -0
- data/lib/brakeman/checks/check_strip_tags.rb +64 -0
- data/lib/brakeman/checks/check_symbol_dos.rb +67 -0
- data/lib/brakeman/checks/check_translate_bug.rb +45 -0
- data/lib/brakeman/checks/check_unsafe_reflection.rb +51 -0
- data/lib/brakeman/checks/check_validation_regex.rb +88 -0
- data/lib/brakeman/checks/check_without_protection.rb +64 -0
- data/lib/brakeman/checks/check_yaml_parsing.rb +121 -0
- data/lib/brakeman/differ.rb +66 -0
- data/lib/{format → brakeman/format}/style.css +28 -0
- data/lib/brakeman/options.rb +256 -0
- data/lib/brakeman/parsers/rails2_erubis.rb +6 -0
- data/lib/brakeman/parsers/rails2_xss_plugin_erubis.rb +48 -0
- data/lib/{scanner_erubis.rb → brakeman/parsers/rails3_erubis.rb} +8 -21
- data/lib/brakeman/processor.rb +102 -0
- data/lib/brakeman/processors/alias_processor.rb +780 -0
- data/lib/{processors → brakeman/processors}/base_processor.rb +90 -74
- data/lib/brakeman/processors/config_processor.rb +14 -0
- data/lib/brakeman/processors/controller_alias_processor.rb +334 -0
- data/lib/brakeman/processors/controller_processor.rb +265 -0
- data/lib/{processors → brakeman/processors}/erb_template_processor.rb +21 -19
- data/lib/brakeman/processors/erubis_template_processor.rb +96 -0
- data/lib/brakeman/processors/gem_processor.rb +59 -0
- data/lib/{processors → brakeman/processors}/haml_template_processor.rb +26 -21
- data/lib/brakeman/processors/lib/find_all_calls.rb +185 -0
- data/lib/{processors → brakeman/processors}/lib/find_call.rb +23 -28
- data/lib/brakeman/processors/lib/find_return_value.rb +134 -0
- data/lib/brakeman/processors/lib/processor_helper.rb +82 -0
- data/lib/{processors/config_processor.rb → brakeman/processors/lib/rails2_config_processor.rb} +32 -35
- data/lib/{processors → brakeman/processors}/lib/rails2_route_processor.rb +60 -52
- data/lib/brakeman/processors/lib/rails3_config_processor.rb +129 -0
- data/lib/brakeman/processors/lib/rails3_route_processor.rb +282 -0
- data/lib/{processors → brakeman/processors}/lib/render_helper.rb +54 -20
- data/lib/brakeman/processors/lib/route_helper.rb +62 -0
- data/lib/{processors → brakeman/processors}/library_processor.rb +24 -17
- data/lib/{processors → brakeman/processors}/model_processor.rb +46 -22
- data/lib/{processors → brakeman/processors}/output_processor.rb +34 -40
- data/lib/brakeman/processors/route_processor.rb +17 -0
- data/lib/brakeman/processors/slim_template_processor.rb +113 -0
- data/lib/brakeman/processors/template_alias_processor.rb +120 -0
- data/lib/{processors → brakeman/processors}/template_processor.rb +10 -7
- data/lib/brakeman/report.rb +68 -0
- data/lib/brakeman/report/ignore/config.rb +130 -0
- data/lib/brakeman/report/ignore/interactive.rb +311 -0
- data/lib/brakeman/report/initializers/faster_csv.rb +7 -0
- data/lib/brakeman/report/initializers/multi_json.rb +29 -0
- data/lib/brakeman/report/renderer.rb +24 -0
- data/lib/brakeman/report/report_base.rb +279 -0
- data/lib/brakeman/report/report_csv.rb +56 -0
- data/lib/brakeman/report/report_hash.rb +22 -0
- data/lib/brakeman/report/report_html.rb +203 -0
- data/lib/brakeman/report/report_json.rb +46 -0
- data/lib/brakeman/report/report_table.rb +109 -0
- data/lib/brakeman/report/report_tabs.rb +17 -0
- data/lib/brakeman/report/templates/controller_overview.html.erb +18 -0
- data/lib/brakeman/report/templates/controller_warnings.html.erb +17 -0
- data/lib/brakeman/report/templates/error_overview.html.erb +25 -0
- data/lib/brakeman/report/templates/header.html.erb +44 -0
- data/lib/brakeman/report/templates/ignored_warnings.html.erb +21 -0
- data/lib/brakeman/report/templates/model_warnings.html.erb +17 -0
- data/lib/brakeman/report/templates/overview.html.erb +34 -0
- data/lib/brakeman/report/templates/security_warnings.html.erb +19 -0
- data/lib/brakeman/report/templates/template_overview.html.erb +17 -0
- data/lib/brakeman/report/templates/view_warnings.html.erb +30 -0
- data/lib/brakeman/report/templates/warning_overview.html.erb +13 -0
- data/lib/brakeman/rescanner.rb +446 -0
- data/lib/brakeman/scanner.rb +362 -0
- data/lib/brakeman/tracker.rb +296 -0
- data/lib/brakeman/util.rb +413 -0
- data/lib/brakeman/version.rb +3 -0
- data/lib/brakeman/warning.rb +217 -0
- data/lib/brakeman/warning_codes.rb +68 -0
- data/lib/ruby_parser/bm_sexp.rb +562 -0
- data/lib/ruby_parser/bm_sexp_processor.rb +230 -0
- metadata +152 -66
- data/lib/checks.rb +0 -71
- data/lib/checks/base_check.rb +0 -357
- data/lib/checks/check_cross_site_scripting.rb +0 -336
- data/lib/checks/check_evaluation.rb +0 -27
- data/lib/checks/check_execute.rb +0 -110
- data/lib/checks/check_file_access.rb +0 -46
- data/lib/checks/check_forgery_setting.rb +0 -42
- data/lib/checks/check_mass_assignment.rb +0 -74
- data/lib/checks/check_model_attributes.rb +0 -36
- data/lib/checks/check_redirect.rb +0 -98
- data/lib/checks/check_render.rb +0 -65
- data/lib/checks/check_send_file.rb +0 -15
- data/lib/checks/check_session_settings.rb +0 -79
- data/lib/checks/check_sql.rb +0 -146
- data/lib/checks/check_validation_regex.rb +0 -60
- data/lib/processor.rb +0 -86
- data/lib/processors/alias_processor.rb +0 -384
- data/lib/processors/controller_alias_processor.rb +0 -237
- data/lib/processors/controller_processor.rb +0 -202
- data/lib/processors/erubis_template_processor.rb +0 -85
- data/lib/processors/lib/find_model_call.rb +0 -39
- data/lib/processors/lib/processor_helper.rb +0 -36
- data/lib/processors/lib/rails3_route_processor.rb +0 -184
- data/lib/processors/lib/route_helper.rb +0 -34
- data/lib/processors/params_processor.rb +0 -77
- data/lib/processors/route_processor.rb +0 -11
- data/lib/processors/template_alias_processor.rb +0 -86
- data/lib/report.rb +0 -680
- data/lib/scanner.rb +0 -227
- data/lib/tracker.rb +0 -144
- data/lib/util.rb +0 -141
- data/lib/version.rb +0 -1
- 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
|