brakeman-lib 3.3.1
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 +7 -0
- data/CHANGES +872 -0
- data/FEATURES +16 -0
- data/README.md +169 -0
- data/WARNING_TYPES +95 -0
- data/bin/brakeman +89 -0
- data/lib/brakeman.rb +495 -0
- data/lib/brakeman/app_tree.rb +161 -0
- data/lib/brakeman/brakeman.rake +17 -0
- data/lib/brakeman/call_index.rb +219 -0
- data/lib/brakeman/checks.rb +191 -0
- data/lib/brakeman/checks/base_check.rb +518 -0
- data/lib/brakeman/checks/check_basic_auth.rb +88 -0
- data/lib/brakeman/checks/check_basic_auth_timing_attack.rb +33 -0
- data/lib/brakeman/checks/check_content_tag.rb +160 -0
- data/lib/brakeman/checks/check_create_with.rb +75 -0
- data/lib/brakeman/checks/check_cross_site_scripting.rb +385 -0
- data/lib/brakeman/checks/check_default_routes.rb +86 -0
- data/lib/brakeman/checks/check_deserialize.rb +57 -0
- data/lib/brakeman/checks/check_detailed_exceptions.rb +55 -0
- data/lib/brakeman/checks/check_digest_dos.rb +38 -0
- data/lib/brakeman/checks/check_dynamic_finders.rb +49 -0
- data/lib/brakeman/checks/check_escape_function.rb +21 -0
- data/lib/brakeman/checks/check_evaluation.rb +36 -0
- data/lib/brakeman/checks/check_execute.rb +167 -0
- data/lib/brakeman/checks/check_file_access.rb +63 -0
- data/lib/brakeman/checks/check_file_disclosure.rb +35 -0
- data/lib/brakeman/checks/check_filter_skipping.rb +31 -0
- data/lib/brakeman/checks/check_forgery_setting.rb +74 -0
- data/lib/brakeman/checks/check_header_dos.rb +31 -0
- data/lib/brakeman/checks/check_i18n_xss.rb +48 -0
- data/lib/brakeman/checks/check_jruby_xml.rb +38 -0
- data/lib/brakeman/checks/check_json_encoding.rb +47 -0
- data/lib/brakeman/checks/check_json_parsing.rb +107 -0
- data/lib/brakeman/checks/check_link_to.rb +132 -0
- data/lib/brakeman/checks/check_link_to_href.rb +115 -0
- data/lib/brakeman/checks/check_mail_to.rb +49 -0
- data/lib/brakeman/checks/check_mass_assignment.rb +198 -0
- data/lib/brakeman/checks/check_mime_type_dos.rb +39 -0
- data/lib/brakeman/checks/check_model_attr_accessible.rb +55 -0
- data/lib/brakeman/checks/check_model_attributes.rb +119 -0
- data/lib/brakeman/checks/check_model_serialize.rb +67 -0
- data/lib/brakeman/checks/check_nested_attributes.rb +38 -0
- data/lib/brakeman/checks/check_nested_attributes_bypass.rb +58 -0
- data/lib/brakeman/checks/check_number_to_currency.rb +74 -0
- data/lib/brakeman/checks/check_quote_table_name.rb +40 -0
- data/lib/brakeman/checks/check_redirect.rb +215 -0
- data/lib/brakeman/checks/check_regex_dos.rb +69 -0
- data/lib/brakeman/checks/check_render.rb +92 -0
- data/lib/brakeman/checks/check_render_dos.rb +37 -0
- data/lib/brakeman/checks/check_render_inline.rb +54 -0
- data/lib/brakeman/checks/check_response_splitting.rb +21 -0
- data/lib/brakeman/checks/check_route_dos.rb +42 -0
- data/lib/brakeman/checks/check_safe_buffer_manipulation.rb +31 -0
- data/lib/brakeman/checks/check_sanitize_methods.rb +79 -0
- data/lib/brakeman/checks/check_secrets.rb +40 -0
- data/lib/brakeman/checks/check_select_tag.rb +60 -0
- data/lib/brakeman/checks/check_select_vulnerability.rb +60 -0
- data/lib/brakeman/checks/check_send.rb +48 -0
- data/lib/brakeman/checks/check_send_file.rb +19 -0
- data/lib/brakeman/checks/check_session_manipulation.rb +36 -0
- data/lib/brakeman/checks/check_session_settings.rb +170 -0
- data/lib/brakeman/checks/check_simple_format.rb +59 -0
- data/lib/brakeman/checks/check_single_quotes.rb +101 -0
- data/lib/brakeman/checks/check_skip_before_filter.rb +60 -0
- data/lib/brakeman/checks/check_sql.rb +660 -0
- data/lib/brakeman/checks/check_sql_cves.rb +101 -0
- data/lib/brakeman/checks/check_ssl_verify.rb +49 -0
- data/lib/brakeman/checks/check_strip_tags.rb +89 -0
- data/lib/brakeman/checks/check_symbol_dos.rb +64 -0
- data/lib/brakeman/checks/check_symbol_dos_cve.rb +30 -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_unscoped_find.rb +41 -0
- data/lib/brakeman/checks/check_validation_regex.rb +116 -0
- data/lib/brakeman/checks/check_weak_hash.rb +151 -0
- data/lib/brakeman/checks/check_without_protection.rb +80 -0
- data/lib/brakeman/checks/check_xml_dos.rb +51 -0
- data/lib/brakeman/checks/check_yaml_parsing.rb +121 -0
- data/lib/brakeman/differ.rb +66 -0
- data/lib/brakeman/file_parser.rb +50 -0
- data/lib/brakeman/format/style.css +133 -0
- data/lib/brakeman/options.rb +301 -0
- data/lib/brakeman/parsers/rails2_erubis.rb +6 -0
- data/lib/brakeman/parsers/rails2_xss_plugin_erubis.rb +48 -0
- data/lib/brakeman/parsers/rails3_erubis.rb +74 -0
- data/lib/brakeman/parsers/template_parser.rb +89 -0
- data/lib/brakeman/processor.rb +102 -0
- data/lib/brakeman/processors/alias_processor.rb +1013 -0
- data/lib/brakeman/processors/base_processor.rb +277 -0
- data/lib/brakeman/processors/config_processor.rb +14 -0
- data/lib/brakeman/processors/controller_alias_processor.rb +273 -0
- data/lib/brakeman/processors/controller_processor.rb +326 -0
- data/lib/brakeman/processors/erb_template_processor.rb +80 -0
- data/lib/brakeman/processors/erubis_template_processor.rb +104 -0
- data/lib/brakeman/processors/gem_processor.rb +57 -0
- data/lib/brakeman/processors/haml_template_processor.rb +190 -0
- data/lib/brakeman/processors/lib/basic_processor.rb +37 -0
- data/lib/brakeman/processors/lib/find_all_calls.rb +223 -0
- data/lib/brakeman/processors/lib/find_call.rb +183 -0
- data/lib/brakeman/processors/lib/find_return_value.rb +134 -0
- data/lib/brakeman/processors/lib/processor_helper.rb +75 -0
- data/lib/brakeman/processors/lib/rails2_config_processor.rb +145 -0
- data/lib/brakeman/processors/lib/rails2_route_processor.rb +313 -0
- data/lib/brakeman/processors/lib/rails3_config_processor.rb +132 -0
- data/lib/brakeman/processors/lib/rails3_route_processor.rb +308 -0
- data/lib/brakeman/processors/lib/render_helper.rb +181 -0
- data/lib/brakeman/processors/lib/render_path.rb +107 -0
- data/lib/brakeman/processors/lib/route_helper.rb +68 -0
- data/lib/brakeman/processors/lib/safe_call_helper.rb +16 -0
- data/lib/brakeman/processors/library_processor.rb +119 -0
- data/lib/brakeman/processors/model_processor.rb +191 -0
- data/lib/brakeman/processors/output_processor.rb +171 -0
- data/lib/brakeman/processors/route_processor.rb +17 -0
- data/lib/brakeman/processors/slim_template_processor.rb +107 -0
- data/lib/brakeman/processors/template_alias_processor.rb +116 -0
- data/lib/brakeman/processors/template_processor.rb +74 -0
- data/lib/brakeman/report.rb +78 -0
- data/lib/brakeman/report/config/remediation.yml +71 -0
- data/lib/brakeman/report/ignore/config.rb +135 -0
- data/lib/brakeman/report/ignore/interactive.rb +311 -0
- data/lib/brakeman/report/renderer.rb +24 -0
- data/lib/brakeman/report/report_base.rb +286 -0
- data/lib/brakeman/report/report_codeclimate.rb +70 -0
- data/lib/brakeman/report/report_csv.rb +55 -0
- data/lib/brakeman/report/report_hash.rb +23 -0
- data/lib/brakeman/report/report_html.rb +216 -0
- data/lib/brakeman/report/report_json.rb +42 -0
- data/lib/brakeman/report/report_markdown.rb +156 -0
- data/lib/brakeman/report/report_table.rb +107 -0
- data/lib/brakeman/report/report_tabs.rb +17 -0
- data/lib/brakeman/report/templates/controller_overview.html.erb +22 -0
- data/lib/brakeman/report/templates/controller_warnings.html.erb +21 -0
- data/lib/brakeman/report/templates/error_overview.html.erb +29 -0
- data/lib/brakeman/report/templates/header.html.erb +58 -0
- data/lib/brakeman/report/templates/ignored_warnings.html.erb +25 -0
- data/lib/brakeman/report/templates/model_warnings.html.erb +21 -0
- data/lib/brakeman/report/templates/overview.html.erb +38 -0
- data/lib/brakeman/report/templates/security_warnings.html.erb +23 -0
- data/lib/brakeman/report/templates/template_overview.html.erb +21 -0
- data/lib/brakeman/report/templates/view_warnings.html.erb +34 -0
- data/lib/brakeman/report/templates/warning_overview.html.erb +17 -0
- data/lib/brakeman/rescanner.rb +483 -0
- data/lib/brakeman/scanner.rb +317 -0
- data/lib/brakeman/tracker.rb +347 -0
- data/lib/brakeman/tracker/collection.rb +93 -0
- data/lib/brakeman/tracker/config.rb +101 -0
- data/lib/brakeman/tracker/constants.rb +101 -0
- data/lib/brakeman/tracker/controller.rb +161 -0
- data/lib/brakeman/tracker/library.rb +17 -0
- data/lib/brakeman/tracker/model.rb +90 -0
- data/lib/brakeman/tracker/template.rb +33 -0
- data/lib/brakeman/util.rb +481 -0
- data/lib/brakeman/version.rb +3 -0
- data/lib/brakeman/warning.rb +255 -0
- data/lib/brakeman/warning_codes.rb +111 -0
- data/lib/ruby_parser/bm_sexp.rb +610 -0
- data/lib/ruby_parser/bm_sexp_processor.rb +116 -0
- metadata +362 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
class Brakeman::CheckRenderInline < Brakeman::CheckCrossSiteScripting
|
|
2
|
+
Brakeman::Checks.add self
|
|
3
|
+
|
|
4
|
+
@description = "Checks for cross site scripting in render calls"
|
|
5
|
+
|
|
6
|
+
def run_check
|
|
7
|
+
setup
|
|
8
|
+
|
|
9
|
+
tracker.find_call(:target => nil, :method => :render).each do |result|
|
|
10
|
+
check_render result
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def check_render result
|
|
15
|
+
return if duplicate? result
|
|
16
|
+
add_result result
|
|
17
|
+
|
|
18
|
+
call = result[:call]
|
|
19
|
+
|
|
20
|
+
if node_type? call, :render and
|
|
21
|
+
(call.render_type == :text or call.render_type == :inline)
|
|
22
|
+
|
|
23
|
+
unless call.render_type == :text and content_type_set? call[3]
|
|
24
|
+
render_value = call[2]
|
|
25
|
+
|
|
26
|
+
if input = has_immediate_user_input?(render_value)
|
|
27
|
+
warn :result => result,
|
|
28
|
+
:warning_type => "Cross Site Scripting",
|
|
29
|
+
:warning_code => :cross_site_scripting_inline,
|
|
30
|
+
:message => "Unescaped #{friendly_type_of input} rendered inline",
|
|
31
|
+
:user_input => input,
|
|
32
|
+
:confidence => CONFIDENCE[:high]
|
|
33
|
+
elsif input = has_immediate_model?(render_value)
|
|
34
|
+
warn :result => result,
|
|
35
|
+
:warning_type => "Cross Site Scripting",
|
|
36
|
+
:warning_code => :cross_site_scripting_inline,
|
|
37
|
+
:message => "Unescaped model attribute rendered inline",
|
|
38
|
+
:user_input => input,
|
|
39
|
+
:confidence => CONFIDENCE[:med]
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
CONTENT_TYPES = ["text/html", "text/javascript", "application/javascript"]
|
|
46
|
+
|
|
47
|
+
def content_type_set? opts
|
|
48
|
+
if hash? opts
|
|
49
|
+
content_type = hash_access(opts, :content_type)
|
|
50
|
+
|
|
51
|
+
string? content_type and not CONTENT_TYPES.include? content_type.value
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
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
|
+
:gem_info => 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,42 @@
|
|
|
1
|
+
require 'brakeman/checks/base_check'
|
|
2
|
+
|
|
3
|
+
class Brakeman::CheckRouteDoS < Brakeman::BaseCheck
|
|
4
|
+
Brakeman::Checks.add self
|
|
5
|
+
|
|
6
|
+
@description = "Checks for route DoS (CVE-2015-7581)"
|
|
7
|
+
|
|
8
|
+
def run_check
|
|
9
|
+
fix_version = case
|
|
10
|
+
when version_between?("4.0.0", "4.1.14")
|
|
11
|
+
"4.1.14.1"
|
|
12
|
+
when version_between?("4.2.0", "4.2.5")
|
|
13
|
+
"4.2.5.1"
|
|
14
|
+
else
|
|
15
|
+
return
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
if controller_wildcards?
|
|
19
|
+
message = "Rails #{rails_version} has a denial of service vulnerability with :controller routes (CVE-2015-7581). Upgrade to Rails #{fix_version}"
|
|
20
|
+
|
|
21
|
+
warn :warning_type => "Denial of Service",
|
|
22
|
+
:warning_code => :CVE_2015_7581,
|
|
23
|
+
:message => message,
|
|
24
|
+
:confidence => CONFIDENCE[:med],
|
|
25
|
+
:gem_info => gemfile_or_environment,
|
|
26
|
+
:link_path => "https://groups.google.com/d/msg/rubyonrails-security/dthJ5wL69JE/YzPnFelbFQAJ"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def controller_wildcards?
|
|
31
|
+
tracker.routes.each do |name, actions|
|
|
32
|
+
if name == :':controllerController'
|
|
33
|
+
# awful hack for routes with :controller in them
|
|
34
|
+
return true
|
|
35
|
+
elsif string? actions and actions.value.include? ":controller"
|
|
36
|
+
return true
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
false
|
|
41
|
+
end
|
|
42
|
+
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 #{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
|
+
:gem_info => gemfile_or_environment
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
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
|
+
end
|
|
21
|
+
|
|
22
|
+
if @fix_version
|
|
23
|
+
check_cve_2013_1855
|
|
24
|
+
check_cve_2013_1857
|
|
25
|
+
elsif tracker.config.has_gem? :'rails-html-sanitizer' and
|
|
26
|
+
version_between? "1.0.0", "1.0.2", tracker.config.gem_version(:'rails-html-sanitizer')
|
|
27
|
+
|
|
28
|
+
warn_sanitizer_cve "CVE-2015-7578", "https://groups.google.com/d/msg/rubyonrails-security/uh--W4TDwmI/JbvSRpdbFQAJ"
|
|
29
|
+
warn_sanitizer_cve "CVE-2015-7580", "https://groups.google.com/d/msg/rubyonrails-security/uh--W4TDwmI/m_CVZtdbFQAJ"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def check_cve_2013_1855
|
|
34
|
+
check_for_cve :sanitize_css, :CVE_2013_1855, "https://groups.google.com/d/msg/rubyonrails-security/4_QHo4BqnN8/_RrdfKk12I4J"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def check_cve_2013_1857
|
|
38
|
+
check_for_cve :sanitize, :CVE_2013_1857, "https://groups.google.com/d/msg/rubyonrails-security/zAAU7vGTPvI/1vZDWXqBuXgJ"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def check_for_cve method, code, link
|
|
42
|
+
tracker.find_call(:target => false, :method => method).each do |result|
|
|
43
|
+
next if duplicate? result
|
|
44
|
+
add_result result
|
|
45
|
+
|
|
46
|
+
message = "Rails #{rails_version} has a vulnerability in #{method}: upgrade to #{@fix_version} or patch"
|
|
47
|
+
|
|
48
|
+
if include_user_input? result[:call]
|
|
49
|
+
confidence = CONFIDENCE[:high]
|
|
50
|
+
else
|
|
51
|
+
confidence = CONFIDENCE[:medium]
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
warn :result => result,
|
|
55
|
+
:warning_type => "Cross Site Scripting",
|
|
56
|
+
:warning_code => code,
|
|
57
|
+
:message => message,
|
|
58
|
+
:confidence => CONFIDENCE[:high],
|
|
59
|
+
:link_path => link
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def warn_sanitizer_cve cve, link
|
|
64
|
+
message = "rails-html-sanitizer #{tracker.config.gem_version(:'rails-html-sanitizer')} is vulnerable (#{cve}). Upgrade to 1.0.3"
|
|
65
|
+
|
|
66
|
+
if tracker.find_call(:target => false, :method => :sanitize).any?
|
|
67
|
+
confidence = CONFIDENCE[:high]
|
|
68
|
+
else
|
|
69
|
+
confidence = CONFIDENCE[:med]
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
warn :warning_type => "Cross Site Scripting",
|
|
73
|
+
:warning_code => cve.tr('-', '_').to_sym,
|
|
74
|
+
:message => message,
|
|
75
|
+
:gem_info => gemfile_or_environment,
|
|
76
|
+
:confidence => confidence,
|
|
77
|
+
:link_path => link
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require 'brakeman/checks/base_check'
|
|
2
|
+
|
|
3
|
+
class Brakeman::CheckSecrets < Brakeman::BaseCheck
|
|
4
|
+
Brakeman::Checks.add_optional self
|
|
5
|
+
|
|
6
|
+
@description = "Checks for secrets stored in source code"
|
|
7
|
+
|
|
8
|
+
def run_check
|
|
9
|
+
check_constants
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def check_constants
|
|
13
|
+
@warned = Set.new
|
|
14
|
+
|
|
15
|
+
@tracker.constants.each do |constant|
|
|
16
|
+
name = constant.name.last
|
|
17
|
+
value = constant.value
|
|
18
|
+
|
|
19
|
+
if string? value and not value.value.empty? and looks_like_secret? name
|
|
20
|
+
match = [name, value, value.line]
|
|
21
|
+
|
|
22
|
+
unless @warned.include? match
|
|
23
|
+
@warned << match
|
|
24
|
+
|
|
25
|
+
warn :warning_code => :secret_in_source,
|
|
26
|
+
:warning_type => "Authentication",
|
|
27
|
+
:message => "Hardcoded value for #{name} in source code",
|
|
28
|
+
:confidence => CONFIDENCE[:med],
|
|
29
|
+
:file => constant.file,
|
|
30
|
+
:line => constant.line
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def looks_like_secret? name
|
|
37
|
+
# REST_AUTH_SITE_KEY is the pepper in Devise
|
|
38
|
+
name.match /password|secret|(rest_auth_site|api)_key$/i
|
|
39
|
+
end
|
|
40
|
+
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}, #{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,
|
|
56
|
+
:link_path => "https://groups.google.com/d/topic/rubyonrails-security/fV3QUToSMSw/discussion"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
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 lts_version? "2.3.18.7"
|
|
13
|
+
return
|
|
14
|
+
elsif version_between? "3.0.0", "3.0.11"
|
|
15
|
+
suggested_version = "3.0.12"
|
|
16
|
+
elsif version_between? "3.1.0", "3.1.3"
|
|
17
|
+
suggested_version = "3.1.4"
|
|
18
|
+
elsif version_between? "3.2.0", "3.2.1"
|
|
19
|
+
suggested_version = "3.2.2"
|
|
20
|
+
elsif version_between? "2.0.0", "2.3.14"
|
|
21
|
+
suggested_version = "3 or use options_for_select"
|
|
22
|
+
else
|
|
23
|
+
return
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
@message = "Upgrade to Rails #{suggested_version}, #{rails_version} select() helper is vulnerable"
|
|
27
|
+
|
|
28
|
+
calls = tracker.find_call(:target => nil, :method => :select).select do |result|
|
|
29
|
+
result[:location][:type] == :template
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
calls.each do |result|
|
|
33
|
+
process_result result
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def process_result result
|
|
38
|
+
return if duplicate? result
|
|
39
|
+
|
|
40
|
+
third_arg = result[:call].third_arg
|
|
41
|
+
|
|
42
|
+
#Check for user input in options parameter
|
|
43
|
+
if sexp? third_arg and include_user_input? third_arg
|
|
44
|
+
add_result result
|
|
45
|
+
|
|
46
|
+
if string_interp? third_arg
|
|
47
|
+
confidence = CONFIDENCE[:med]
|
|
48
|
+
else
|
|
49
|
+
confidence = CONFIDENCE[:low]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
warn :template => result[:location][:template],
|
|
53
|
+
:warning_type => "Cross Site Scripting",
|
|
54
|
+
:warning_code => :select_options_vuln,
|
|
55
|
+
:result => result,
|
|
56
|
+
:message => @message,
|
|
57
|
+
:confidence => confidence
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
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
|
+
@send_methods = [:send, :try, :__send__, :public_send]
|
|
11
|
+
Brakeman.debug("Finding instances of #send")
|
|
12
|
+
calls = tracker.find_call :methods => @send_methods, :nested => true
|
|
13
|
+
|
|
14
|
+
calls.each do |call|
|
|
15
|
+
process_result call
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def process_result result
|
|
20
|
+
return if duplicate? result or result[:call].original_line
|
|
21
|
+
add_result result
|
|
22
|
+
|
|
23
|
+
send_call = get_send result[:call]
|
|
24
|
+
process_call_args send_call
|
|
25
|
+
process send_call.target
|
|
26
|
+
|
|
27
|
+
if input = has_immediate_user_input?(send_call.first_arg)
|
|
28
|
+
warn :result => result,
|
|
29
|
+
:warning_type => "Dangerous Send",
|
|
30
|
+
:warning_code => :dangerous_send,
|
|
31
|
+
:message => "User controlled method execution",
|
|
32
|
+
:code => result[:call],
|
|
33
|
+
:user_input => input,
|
|
34
|
+
:confidence => CONFIDENCE[:high]
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Recursively check call chain for send call
|
|
39
|
+
def get_send exp
|
|
40
|
+
if call? exp
|
|
41
|
+
if @send_methods.include? exp.method
|
|
42
|
+
return exp
|
|
43
|
+
else
|
|
44
|
+
get_send exp.target
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
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
|