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,101 @@
|
|
|
1
|
+
require 'brakeman/checks/base_check'
|
|
2
|
+
|
|
3
|
+
class Brakeman::CheckSQLCVEs < Brakeman::BaseCheck
|
|
4
|
+
Brakeman::Checks.add self
|
|
5
|
+
|
|
6
|
+
@description = "Checks for several SQL CVEs"
|
|
7
|
+
|
|
8
|
+
def run_check
|
|
9
|
+
check_rails_versions_against_cve_issues
|
|
10
|
+
check_cve_2014_0080
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def check_rails_versions_against_cve_issues
|
|
14
|
+
issues = [
|
|
15
|
+
{
|
|
16
|
+
:cve => "CVE-2012-2660",
|
|
17
|
+
:versions => [%w[2.0.0 2.3.14 2.3.17], %w[3.0.0 3.0.12 3.0.13], %w[3.1.0 3.1.4 3.1.5], %w[3.2.0 3.2.3 3.2.4]],
|
|
18
|
+
:url => "https://groups.google.com/d/topic/rubyonrails-security/8SA-M3as7A8/discussion"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
:cve => "CVE-2012-2661",
|
|
22
|
+
:versions => [%w[3.0.0 3.0.12 3.0.13], %w[3.1.0 3.1.4 3.1.5], %w[3.2.0 3.2.3 3.2.5]],
|
|
23
|
+
:url => "https://groups.google.com/d/topic/rubyonrails-security/dUaiOOGWL1k/discussion"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
:cve => "CVE-2012-2695",
|
|
27
|
+
:versions => [%w[2.0.0 2.3.14 2.3.15], %w[3.0.0 3.0.13 3.0.14], %w[3.1.0 3.1.5 3.1.6], %w[3.2.0 3.2.5 3.2.6]],
|
|
28
|
+
:url => "https://groups.google.com/d/topic/rubyonrails-security/l4L0TEVAz1k/discussion"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
:cve => "CVE-2012-5664",
|
|
32
|
+
:versions => [%w[2.0.0 2.3.14 2.3.15], %w[3.0.0 3.0.17 3.0.18], %w[3.1.0 3.1.8 3.1.9], %w[3.2.0 3.2.9 3.2.18]],
|
|
33
|
+
:url => "https://groups.google.com/d/topic/rubyonrails-security/DCNTNp_qjFM/discussion"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
:cve => "CVE-2013-0155",
|
|
37
|
+
:versions => [%w[2.0.0 2.3.15 2.3.16], %w[3.0.0 3.0.18 3.0.19], %w[3.1.0 3.1.9 3.1.10], %w[3.2.0 3.2.10 3.2.11]],
|
|
38
|
+
:url => "https://groups.google.com/d/topic/rubyonrails-security/c7jT-EeN9eI/discussion"
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
unless lts_version? '2.3.18.6'
|
|
44
|
+
issues << {
|
|
45
|
+
:cve => "CVE-2013-6417",
|
|
46
|
+
:versions => [%w[2.0.0 3.2.15 3.2.16], %w[4.0.0 4.0.1 4.0.2]],
|
|
47
|
+
:url => "https://groups.google.com/d/msg/ruby-security-ann/niK4drpSHT4/g8JW8ZsayRkJ"
|
|
48
|
+
}
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
if tracker.config.has_gem? :pg
|
|
52
|
+
issues << {
|
|
53
|
+
:cve => "CVE-2014-3482",
|
|
54
|
+
:versions => [%w[2.0.0 2.9.9 3.2.19], %w[3.0.0 3.2.18 3.2.19], %w[4.0.0 4.0.6 4.0.7], %w[4.1.0 4.1.2 4.1.3]],
|
|
55
|
+
:url => "https://groups.google.com/d/msg/rubyonrails-security/wDxePLJGZdI/WP7EasCJTA4J"
|
|
56
|
+
} <<
|
|
57
|
+
{
|
|
58
|
+
:cve => "CVE-2014-3483",
|
|
59
|
+
:versions => [%w[2.0.0 2.9.9 3.2.19], %w[3.0.0 3.2.18 3.2.19], %w[4.0.0 4.0.6 4.0.7], %w[4.1.0 4.1.2 4.1.3]],
|
|
60
|
+
:url => "https://groups.google.com/d/msg/rubyonrails-security/wDxePLJGZdI/WP7EasCJTA4J" }
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
issues.each do |cve_issue|
|
|
64
|
+
cve_warning_for cve_issue[:versions], cve_issue[:cve], cve_issue[:url]
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def cve_warning_for versions, cve, link
|
|
69
|
+
upgrade_version = upgrade_version? versions
|
|
70
|
+
return unless upgrade_version
|
|
71
|
+
|
|
72
|
+
code = cve.tr('-', '_').to_sym
|
|
73
|
+
|
|
74
|
+
warn :warning_type => 'SQL Injection',
|
|
75
|
+
:warning_code => code,
|
|
76
|
+
:message => "Rails #{rails_version} contains a SQL injection vulnerability (#{cve}). Upgrade to #{upgrade_version}",
|
|
77
|
+
:confidence => CONFIDENCE[:high],
|
|
78
|
+
:gem_info => gemfile_or_environment,
|
|
79
|
+
:link_path => link
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def upgrade_version? versions
|
|
83
|
+
versions.each do |low, high, upgrade|
|
|
84
|
+
return upgrade if version_between? low, high
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
false
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def check_cve_2014_0080
|
|
91
|
+
return unless version_between? "4.0.0", "4.0.2" and
|
|
92
|
+
@tracker.config.has_gem? :pg
|
|
93
|
+
|
|
94
|
+
warn :warning_type => 'SQL Injection',
|
|
95
|
+
:warning_code => :CVE_2014_0080,
|
|
96
|
+
:message => "Rails #{rails_version} contains a SQL injection vulnerability (CVE-2014-0080) with PostgreSQL. Upgrade to 4.0.3",
|
|
97
|
+
:confidence => CONFIDENCE[:high],
|
|
98
|
+
:gem_info => gemfile_or_environment(:pg),
|
|
99
|
+
:link_path => "https://groups.google.com/d/msg/rubyonrails-security/Wu96YkTUR6s/pPLBMZrlwvYJ"
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require 'brakeman/checks/base_check'
|
|
2
|
+
|
|
3
|
+
# Checks if verify_mode= is called with OpenSSL::SSL::VERIFY_NONE
|
|
4
|
+
|
|
5
|
+
class Brakeman::CheckSSLVerify < Brakeman::BaseCheck
|
|
6
|
+
Brakeman::Checks.add self
|
|
7
|
+
|
|
8
|
+
SSL_VERIFY_NONE = s(:colon2, s(:colon2, s(:const, :OpenSSL), :SSL), :VERIFY_NONE)
|
|
9
|
+
|
|
10
|
+
@description = "Checks for OpenSSL::SSL::VERIFY_NONE"
|
|
11
|
+
|
|
12
|
+
def run_check
|
|
13
|
+
check_open_ssl_verify_none
|
|
14
|
+
check_http_start
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def check_open_ssl_verify_none
|
|
18
|
+
tracker.find_call(:method => :verify_mode=).each {|call| process_verify_mode_result(call) }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def process_verify_mode_result result
|
|
22
|
+
if result[:call].last_arg == SSL_VERIFY_NONE
|
|
23
|
+
warn_about_ssl_verification_bypass result
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def check_http_start
|
|
28
|
+
tracker.find_call(:target => :'Net::HTTP', :method => :start).each { |call| process_http_start_result call }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def process_http_start_result result
|
|
32
|
+
arg = result[:call].last_arg
|
|
33
|
+
|
|
34
|
+
if hash? arg and hash_access(arg, :verify_mode) == SSL_VERIFY_NONE
|
|
35
|
+
warn_about_ssl_verification_bypass result
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def warn_about_ssl_verification_bypass result
|
|
40
|
+
return if duplicate?(result)
|
|
41
|
+
add_result result
|
|
42
|
+
|
|
43
|
+
warn :result => result,
|
|
44
|
+
:warning_type => "SSL Verification Bypass",
|
|
45
|
+
:warning_code => :ssl_verification_bypass,
|
|
46
|
+
:message => "SSL certificate verification was bypassed",
|
|
47
|
+
:confidence => CONFIDENCE[:high]
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
require 'brakeman/checks/base_check'
|
|
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
|
|
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
|
|
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
|
|
11
|
+
class Brakeman::CheckStripTags < Brakeman::BaseCheck
|
|
12
|
+
Brakeman::Checks.add self
|
|
13
|
+
|
|
14
|
+
@description = "Report strip_tags vulnerabilities"
|
|
15
|
+
|
|
16
|
+
def run_check
|
|
17
|
+
if uses_strip_tags?
|
|
18
|
+
cve_2011_2931
|
|
19
|
+
cve_2012_3465
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
cve_2015_7579
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def cve_2011_2931
|
|
26
|
+
if version_between?('2.0.0', '2.3.12') or version_between?('3.0.0', '3.0.9')
|
|
27
|
+
if rails_version =~ /^3/
|
|
28
|
+
message = "Versions before 3.0.10 have a vulnerability in strip_tags (CVE-2011-2931)"
|
|
29
|
+
else
|
|
30
|
+
message = "Versions before 2.3.13 have a vulnerability in strip_tags (CVE-2011-2931)"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
warn :warning_type => "Cross Site Scripting",
|
|
34
|
+
:warning_code => :CVE_2011_2931,
|
|
35
|
+
:message => message,
|
|
36
|
+
:gem_info => gemfile_or_environment,
|
|
37
|
+
:confidence => CONFIDENCE[:high],
|
|
38
|
+
:link_path => "https://groups.google.com/d/topic/rubyonrails-security/K5EwdJt06hI/discussion"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def cve_2012_3465
|
|
43
|
+
case
|
|
44
|
+
when (version_between?('2.0.0', '2.3.14') and tracker.config.escape_html?)
|
|
45
|
+
message = "All Rails 2.x versions have a vulnerability in strip_tags (CVE-2012-3465)"
|
|
46
|
+
when version_between?('3.0.10', '3.0.16')
|
|
47
|
+
message = "Rails #{rails_version} has a vulnerability in strip_tags (CVE-2012-3465). Upgrade to 3.0.17"
|
|
48
|
+
when version_between?('3.1.0', '3.1.7')
|
|
49
|
+
message = "Rails #{rails_version} has a vulnerability in strip_tags (CVE-2012-3465). Upgrade to 3.1.8"
|
|
50
|
+
when version_between?('3.2.0', '3.2.7')
|
|
51
|
+
message = "Rails #{rails_version} has a vulnerability in strip_tags (CVE-2012-3465). Upgrade to 3.2.8"
|
|
52
|
+
else
|
|
53
|
+
return
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
warn :warning_type => "Cross Site Scripting",
|
|
57
|
+
:warning_code => :CVE_2012_3465,
|
|
58
|
+
:message => message,
|
|
59
|
+
:confidence => CONFIDENCE[:high],
|
|
60
|
+
:gem_info => gemfile_or_environment,
|
|
61
|
+
:link_path => "https://groups.google.com/d/topic/rubyonrails-security/FgVEtBajcTY/discussion"
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def cve_2015_7579
|
|
65
|
+
if tracker.config.gem_version(:'rails-html-sanitizer') == '1.0.2'
|
|
66
|
+
if uses_strip_tags?
|
|
67
|
+
confidence = CONFIDENCE[:high]
|
|
68
|
+
else
|
|
69
|
+
confidence = CONFIDENCE[:med]
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
message = "rails-html-sanitizer 1.0.2 is vulnerable (CVE-2015-7579). Upgrade to 1.0.3"
|
|
73
|
+
|
|
74
|
+
warn :warning_type => "Cross Site Scripting",
|
|
75
|
+
:warning_code => :CVE_2015_7579,
|
|
76
|
+
:message => message,
|
|
77
|
+
:confidence => confidence,
|
|
78
|
+
:gem_info => gemfile_or_environment,
|
|
79
|
+
:link_path => "https://groups.google.com/d/msg/rubyonrails-security/OU9ugTZcbjc/PjEP46pbFQAJ"
|
|
80
|
+
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def uses_strip_tags?
|
|
85
|
+
Brakeman.debug "Finding calls to strip_tags()"
|
|
86
|
+
|
|
87
|
+
not tracker.find_call(:target => false, :method => :strip_tags, :nested => true).empty?
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
require 'brakeman/checks/base_check'
|
|
2
|
+
|
|
3
|
+
class Brakeman::CheckSymbolDoS < Brakeman::BaseCheck
|
|
4
|
+
Brakeman::Checks.add_optional self
|
|
5
|
+
|
|
6
|
+
UNSAFE_METHODS = [:to_sym, :literal_to_sym, :intern, :symbolize_keys, :symbolize_keys!]
|
|
7
|
+
|
|
8
|
+
@description = "Checks for symbol denial of service"
|
|
9
|
+
|
|
10
|
+
def run_check
|
|
11
|
+
return if rails_version > "5.0.0"
|
|
12
|
+
|
|
13
|
+
tracker.find_call(:methods => UNSAFE_METHODS, :nested => true).each do |result|
|
|
14
|
+
check_unsafe_symbol_creation(result)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def check_unsafe_symbol_creation result
|
|
19
|
+
return if duplicate? result or result[:call].original_line
|
|
20
|
+
|
|
21
|
+
add_result result
|
|
22
|
+
|
|
23
|
+
call = result[:call]
|
|
24
|
+
|
|
25
|
+
if result[:method] == :literal_to_sym
|
|
26
|
+
args = call.select { |e| sexp? e }
|
|
27
|
+
else
|
|
28
|
+
args = [call.target]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
if input = args.map{ |arg| has_immediate_user_input?(arg) }.compact.first
|
|
32
|
+
confidence = CONFIDENCE[:high]
|
|
33
|
+
elsif input = args.map{ |arg| include_user_input?(arg) }.compact.first
|
|
34
|
+
confidence = CONFIDENCE[:med]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
if confidence
|
|
38
|
+
return if safe_parameter? input.match
|
|
39
|
+
|
|
40
|
+
message = "Symbol conversion from unsafe string (#{friendly_type_of input})"
|
|
41
|
+
|
|
42
|
+
warn :result => result,
|
|
43
|
+
:warning_type => "Denial of Service",
|
|
44
|
+
:warning_code => :unsafe_symbol_creation,
|
|
45
|
+
:message => message,
|
|
46
|
+
:user_input => input,
|
|
47
|
+
:confidence => confidence
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def safe_parameter? input
|
|
52
|
+
if call? input
|
|
53
|
+
if node_type? input.target, :params
|
|
54
|
+
input.method == :[] and
|
|
55
|
+
symbol? input.first_arg and
|
|
56
|
+
[:controller, :action].include? input.first_arg.value
|
|
57
|
+
else
|
|
58
|
+
safe_parameter? input.target
|
|
59
|
+
end
|
|
60
|
+
else
|
|
61
|
+
false
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'brakeman/checks/base_check'
|
|
2
|
+
|
|
3
|
+
class Brakeman::CheckSymbolDoSCVE < Brakeman::BaseCheck
|
|
4
|
+
Brakeman::Checks.add self
|
|
5
|
+
|
|
6
|
+
@description = "Checks for versions with ActiveRecord symbol denial of service vulnerability"
|
|
7
|
+
|
|
8
|
+
def run_check
|
|
9
|
+
fix_version = case
|
|
10
|
+
when version_between?('2.0.0', '2.3.17')
|
|
11
|
+
'2.3.18'
|
|
12
|
+
when version_between?('3.1.0', '3.1.11')
|
|
13
|
+
'3.1.12'
|
|
14
|
+
when version_between?('3.2.0', '3.2.12')
|
|
15
|
+
'3.2.13'
|
|
16
|
+
else
|
|
17
|
+
nil
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
if fix_version && active_record_models.any?
|
|
21
|
+
warn :warning_type => "Denial of Service",
|
|
22
|
+
:warning_code => :CVE_2013_1854,
|
|
23
|
+
:message => "Rails #{rails_version} has a denial of service vulnerability in ActiveRecord: upgrade to #{fix_version} or patch",
|
|
24
|
+
:confidence => CONFIDENCE[:med],
|
|
25
|
+
:gem_info => gemfile_or_environment,
|
|
26
|
+
:link => "https://groups.google.com/d/msg/rubyonrails-security/jgJ4cjjS8FE/BGbHRxnDRTIJ"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require 'brakeman/checks/base_check'
|
|
2
|
+
|
|
3
|
+
#Check for vulnerability in translate() helper that allows cross-site scripting
|
|
4
|
+
class Brakeman::CheckTranslateBug < Brakeman::BaseCheck
|
|
5
|
+
Brakeman::Checks.add self
|
|
6
|
+
|
|
7
|
+
@description = "Report XSS vulnerability in translate helper"
|
|
8
|
+
|
|
9
|
+
def run_check
|
|
10
|
+
return if lts_version? '2.3.18.6'
|
|
11
|
+
if (version_between?('2.3.0', '2.3.99') and tracker.config.escape_html?) or
|
|
12
|
+
version_between?('3.0.0', '3.0.10') or
|
|
13
|
+
version_between?('3.1.0', '3.1.1')
|
|
14
|
+
|
|
15
|
+
confidence = if uses_translate?
|
|
16
|
+
CONFIDENCE[:high]
|
|
17
|
+
else
|
|
18
|
+
CONFIDENCE[:med]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
description = "have a vulnerability in the translate helper with keys ending in _html"
|
|
22
|
+
|
|
23
|
+
message = if rails_version =~ /^3\.1/
|
|
24
|
+
"Versions before 3.1.2 #{description}."
|
|
25
|
+
elsif rails_version =~ /^3\.0/
|
|
26
|
+
"Versions before 3.0.11 #{description}."
|
|
27
|
+
else
|
|
28
|
+
"Rails 2.3.x using the rails_xss plugin #{description}."
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
warn :warning_type => "Cross Site Scripting",
|
|
32
|
+
:warning_code => :translate_vuln,
|
|
33
|
+
:message => message,
|
|
34
|
+
:confidence => confidence,
|
|
35
|
+
:gem_info => gemfile_or_environment,
|
|
36
|
+
:link_path => "http://groups.google.com/group/rubyonrails-security/browse_thread/thread/2b61d70fb73c7cc5"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def uses_translate?
|
|
41
|
+
Brakeman.debug "Finding calls to translate() or t()"
|
|
42
|
+
|
|
43
|
+
tracker.find_call(:target => nil, :methods => [:t, :translate]).any?
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'brakeman/checks/base_check'
|
|
2
|
+
|
|
3
|
+
# Checks for string interpolation and parameters in calls to
|
|
4
|
+
# String#constantize, String#safe_constantize, Module#const_get and Module#qualified_const_get.
|
|
5
|
+
#
|
|
6
|
+
# Exploit examples at: http://blog.conviso.com.br/2013/02/exploiting-unsafe-reflection-in.html
|
|
7
|
+
class Brakeman::CheckUnsafeReflection < Brakeman::BaseCheck
|
|
8
|
+
Brakeman::Checks.add self
|
|
9
|
+
|
|
10
|
+
@description = "Checks for unsafe reflection"
|
|
11
|
+
|
|
12
|
+
def run_check
|
|
13
|
+
reflection_methods = [:constantize, :safe_constantize, :const_get, :qualified_const_get]
|
|
14
|
+
|
|
15
|
+
tracker.find_call(:methods => reflection_methods, :nested => true).each do |result|
|
|
16
|
+
check_unsafe_reflection result
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def check_unsafe_reflection result
|
|
21
|
+
return if duplicate? result or result[:call].original_line
|
|
22
|
+
add_result result
|
|
23
|
+
|
|
24
|
+
call = result[:call]
|
|
25
|
+
method = call.method
|
|
26
|
+
|
|
27
|
+
case method
|
|
28
|
+
when :constantize, :safe_constantize
|
|
29
|
+
arg = call.target
|
|
30
|
+
else
|
|
31
|
+
arg = call.first_arg
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
if input = has_immediate_user_input?(arg)
|
|
35
|
+
confidence = CONFIDENCE[:high]
|
|
36
|
+
elsif input = include_user_input?(arg)
|
|
37
|
+
confidence = CONFIDENCE[:med]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
if confidence
|
|
41
|
+
message = "Unsafe reflection method #{method} called with #{friendly_type_of input}"
|
|
42
|
+
|
|
43
|
+
warn :result => result,
|
|
44
|
+
:warning_type => "Remote Code Execution",
|
|
45
|
+
:warning_code => :unsafe_constantize,
|
|
46
|
+
:message => message,
|
|
47
|
+
:user_input => input,
|
|
48
|
+
:confidence => confidence
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require 'brakeman/checks/base_check'
|
|
2
|
+
|
|
3
|
+
# Checks for unscoped calls to models' #find and #find_by_id methods.
|
|
4
|
+
class Brakeman::CheckUnscopedFind < Brakeman::BaseCheck
|
|
5
|
+
Brakeman::Checks.add_optional self
|
|
6
|
+
|
|
7
|
+
@description = "Check for unscoped ActiveRecord queries"
|
|
8
|
+
|
|
9
|
+
def run_check
|
|
10
|
+
Brakeman.debug("Finding instances of #find on models with associations")
|
|
11
|
+
|
|
12
|
+
associated_model_names = active_record_models.keys.select do |name|
|
|
13
|
+
active_record_models[name].associations[:belongs_to]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
calls = tracker.find_call :method => [:find, :find_by_id, :find_by_id!],
|
|
17
|
+
:targets => associated_model_names
|
|
18
|
+
|
|
19
|
+
calls.each do |call|
|
|
20
|
+
process_result call
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def process_result result
|
|
25
|
+
return if duplicate? result or result[:call].original_line
|
|
26
|
+
|
|
27
|
+
# Not interested unless argument is user controlled.
|
|
28
|
+
inputs = result[:call].args.map { |arg| include_user_input?(arg) }
|
|
29
|
+
return unless input = inputs.compact.first
|
|
30
|
+
|
|
31
|
+
add_result result
|
|
32
|
+
|
|
33
|
+
warn :result => result,
|
|
34
|
+
:warning_type => "Unscoped Find",
|
|
35
|
+
:warning_code => :unscoped_find,
|
|
36
|
+
:message => "Unscoped call to #{result[:target]}##{result[:method]}",
|
|
37
|
+
:code => result[:call],
|
|
38
|
+
:confidence => CONFIDENCE[:low],
|
|
39
|
+
:user_input => input
|
|
40
|
+
end
|
|
41
|
+
end
|