brakeman 4.5.0 → 4.5.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of brakeman might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGES.md +15 -0
- data/README.md +6 -6
- data/bundle/load.rb +3 -3
- data/bundle/ruby/2.5.0/gems/{highline-1.7.10 → highline-2.0.2}/AUTHORS +0 -0
- data/bundle/ruby/2.5.0/gems/{highline-1.7.10 → highline-2.0.2}/COPYING +0 -0
- data/bundle/ruby/2.5.0/gems/{highline-1.7.10 → highline-2.0.2}/Changelog.md +211 -15
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/Gemfile +22 -0
- data/bundle/ruby/2.5.0/gems/{highline-1.7.10 → highline-2.0.2}/LICENSE +0 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/README.md +202 -0
- data/bundle/ruby/2.5.0/gems/{highline-1.7.10 → highline-2.0.2}/TODO +0 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/appveyor.yml +37 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/highline.gemspec +35 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline.rb +650 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/builtin_styles.rb +129 -0
- data/bundle/ruby/2.5.0/gems/{highline-1.7.10 → highline-2.0.2}/lib/highline/color_scheme.rb +49 -32
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/compatibility.rb +23 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/custom_errors.rb +57 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/import.rb +48 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/io_console_compatible.rb +37 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/list.rb +177 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/list_renderer.rb +261 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/menu.rb +576 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/menu/item.rb +32 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/paginator.rb +52 -0
- data/bundle/ruby/2.5.0/gems/{highline-1.7.10 → highline-2.0.2}/lib/highline/question.rb +281 -131
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/question/answer_converter.rb +103 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/question_asker.rb +150 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/simulate.rb +59 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/statement.rb +88 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/string.rb +36 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/string_extensions.rb +130 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/style.rb +325 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/template_renderer.rb +62 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/terminal.rb +190 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/terminal/io_console.rb +36 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/terminal/ncurses.rb +38 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/terminal/unix_stty.rb +51 -0
- data/bundle/ruby/2.5.0/gems/{highline-1.7.10 → highline-2.0.2}/lib/highline/version.rb +3 -1
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/wrapper.rb +53 -0
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/History.rdoc +32 -0
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/Manifest.txt +0 -0
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/README.rdoc +0 -0
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/compare/normalize.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/debugging.md +0 -0
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/rp_extensions.rb +1 -1
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/rp_stringscanner.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby20_parser.rb +2427 -2432
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby20_parser.y +32 -29
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby21_parser.rb +2101 -2109
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby21_parser.y +32 -29
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby22_parser.rb +2080 -2095
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby22_parser.y +32 -29
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0/lib/ruby25_parser.rb → ruby_parser-3.13.1/lib/ruby23_parser.rb} +2339 -2333
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby23_parser.y +32 -29
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby24_parser.rb +2347 -2335
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby24_parser.y +32 -23
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0/lib/ruby23_parser.rb → ruby_parser-3.13.1/lib/ruby25_parser.rb} +2349 -2337
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby25_parser.y +32 -23
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby26_parser.rb +2351 -2338
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby26_parser.y +32 -23
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby_lexer.rb +253 -161
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby_lexer.rex +25 -25
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby_lexer.rex.rb +68 -26
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby_parser.rb +3 -1
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby_parser.yy +34 -23
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby_parser_extras.rb +64 -43
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/tools/munge.rb +2 -1
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/tools/ripper.rb +6 -1
- data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.5.0 → unicode-display_width-1.6.0}/CHANGELOG.md +4 -0
- data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.5.0 → unicode-display_width-1.6.0}/MIT-LICENSE.txt +0 -0
- data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.5.0 → unicode-display_width-1.6.0}/README.md +1 -1
- data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.5.0 → unicode-display_width-1.6.0}/data/display_width.marshal.gz +0 -0
- data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.5.0 → unicode-display_width-1.6.0}/lib/unicode/display_width.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.5.0 → unicode-display_width-1.6.0}/lib/unicode/display_width/constants.rb +2 -2
- data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.5.0 → unicode-display_width-1.6.0}/lib/unicode/display_width/index.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.5.0 → unicode-display_width-1.6.0}/lib/unicode/display_width/no_string_ext.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.5.0 → unicode-display_width-1.6.0}/lib/unicode/display_width/string_ext.rb +0 -0
- data/lib/brakeman.rb +7 -0
- data/lib/brakeman/app_tree.rb +34 -22
- data/lib/brakeman/checks.rb +7 -7
- data/lib/brakeman/checks/base_check.rb +9 -9
- data/lib/brakeman/checks/check_cross_site_scripting.rb +5 -0
- data/lib/brakeman/checks/check_default_routes.rb +5 -0
- data/lib/brakeman/checks/check_deserialize.rb +52 -0
- data/lib/brakeman/checks/check_dynamic_finders.rb +1 -1
- data/lib/brakeman/checks/check_force_ssl.rb +27 -0
- data/lib/brakeman/checks/check_json_parsing.rb +5 -0
- data/lib/brakeman/checks/check_link_to_href.rb +6 -1
- data/lib/brakeman/checks/check_mail_to.rb +1 -1
- data/lib/brakeman/checks/check_model_attr_accessible.rb +1 -1
- data/lib/brakeman/checks/check_model_attributes.rb +12 -50
- data/lib/brakeman/checks/check_model_serialize.rb +1 -1
- data/lib/brakeman/checks/check_nested_attributes_bypass.rb +3 -3
- data/lib/brakeman/checks/check_secrets.rb +1 -1
- data/lib/brakeman/checks/check_session_settings.rb +10 -10
- data/lib/brakeman/checks/check_simple_format.rb +5 -0
- data/lib/brakeman/checks/check_skip_before_filter.rb +1 -1
- data/lib/brakeman/checks/check_sql.rb +15 -17
- data/lib/brakeman/checks/check_validation_regex.rb +1 -1
- data/lib/brakeman/file_parser.rb +6 -8
- data/lib/brakeman/file_path.rb +71 -0
- data/lib/brakeman/options.rb +7 -0
- data/lib/brakeman/parsers/template_parser.rb +3 -3
- data/lib/brakeman/processor.rb +3 -4
- data/lib/brakeman/processors/alias_processor.rb +12 -6
- data/lib/brakeman/processors/base_processor.rb +8 -7
- data/lib/brakeman/processors/controller_alias_processor.rb +10 -7
- data/lib/brakeman/processors/controller_processor.rb +5 -9
- data/lib/brakeman/processors/haml_template_processor.rb +5 -0
- data/lib/brakeman/processors/lib/module_helper.rb +8 -8
- data/lib/brakeman/processors/lib/processor_helper.rb +3 -3
- data/lib/brakeman/processors/lib/rails2_config_processor.rb +3 -3
- data/lib/brakeman/processors/lib/rails2_route_processor.rb +2 -2
- data/lib/brakeman/processors/lib/rails3_config_processor.rb +3 -3
- data/lib/brakeman/processors/lib/rails3_route_processor.rb +2 -2
- data/lib/brakeman/processors/lib/render_helper.rb +2 -2
- data/lib/brakeman/processors/lib/render_path.rb +18 -1
- data/lib/brakeman/processors/library_processor.rb +5 -5
- data/lib/brakeman/processors/model_processor.rb +4 -5
- data/lib/brakeman/processors/output_processor.rb +5 -0
- data/lib/brakeman/processors/template_alias_processor.rb +4 -5
- data/lib/brakeman/processors/template_processor.rb +4 -4
- data/lib/brakeman/report.rb +3 -3
- data/lib/brakeman/report/ignore/config.rb +2 -3
- data/lib/brakeman/report/ignore/interactive.rb +2 -2
- data/lib/brakeman/report/pager.rb +1 -0
- data/lib/brakeman/report/report_base.rb +51 -6
- data/lib/brakeman/report/report_codeclimate.rb +3 -3
- data/lib/brakeman/report/report_hash.rb +1 -1
- data/lib/brakeman/report/report_html.rb +2 -2
- data/lib/brakeman/report/report_json.rb +1 -24
- data/lib/brakeman/report/report_table.rb +20 -4
- data/lib/brakeman/report/report_tabs.rb +1 -1
- data/lib/brakeman/report/report_text.rb +2 -2
- data/lib/brakeman/rescanner.rb +9 -12
- data/lib/brakeman/scanner.rb +19 -14
- data/lib/brakeman/tracker.rb +4 -4
- data/lib/brakeman/tracker/collection.rb +4 -3
- data/lib/brakeman/tracker/config.rb +6 -0
- data/lib/brakeman/util.rb +1 -147
- data/lib/brakeman/version.rb +1 -1
- data/lib/brakeman/warning.rb +23 -13
- data/lib/brakeman/warning_codes.rb +1 -0
- data/lib/ruby_parser/bm_sexp_processor.rb +1 -0
- metadata +78 -61
- data/bundle/ruby/2.5.0/gems/highline-1.7.10/Gemfile +0 -11
- data/bundle/ruby/2.5.0/gems/highline-1.7.10/INSTALL +0 -59
- data/bundle/ruby/2.5.0/gems/highline-1.7.10/README.rdoc +0 -74
- data/bundle/ruby/2.5.0/gems/highline-1.7.10/highline.gemspec +0 -37
- data/bundle/ruby/2.5.0/gems/highline-1.7.10/lib/highline.rb +0 -1048
- data/bundle/ruby/2.5.0/gems/highline-1.7.10/lib/highline/compatibility.rb +0 -16
- data/bundle/ruby/2.5.0/gems/highline-1.7.10/lib/highline/import.rb +0 -41
- data/bundle/ruby/2.5.0/gems/highline-1.7.10/lib/highline/menu.rb +0 -381
- data/bundle/ruby/2.5.0/gems/highline-1.7.10/lib/highline/simulate.rb +0 -48
- data/bundle/ruby/2.5.0/gems/highline-1.7.10/lib/highline/string_extensions.rb +0 -111
- data/bundle/ruby/2.5.0/gems/highline-1.7.10/lib/highline/style.rb +0 -192
- data/bundle/ruby/2.5.0/gems/highline-1.7.10/lib/highline/system_extensions.rb +0 -254
- data/bundle/ruby/2.5.0/gems/highline-1.7.10/setup.rb +0 -1360
@@ -6,6 +6,11 @@ class Brakeman::CheckDefaultRoutes < Brakeman::BaseCheck
|
|
6
6
|
|
7
7
|
@description = "Checks for default routes"
|
8
8
|
|
9
|
+
def initialize *args
|
10
|
+
super
|
11
|
+
@actions_allowed_on_controller = nil
|
12
|
+
end
|
13
|
+
|
9
14
|
#Checks for :allow_all_actions globally and for individual routes
|
10
15
|
#if it is not enabled globally.
|
11
16
|
def run_check
|
@@ -9,6 +9,7 @@ class Brakeman::CheckDeserialize < Brakeman::BaseCheck
|
|
9
9
|
check_yaml
|
10
10
|
check_csv
|
11
11
|
check_marshal
|
12
|
+
check_oj
|
12
13
|
end
|
13
14
|
|
14
15
|
def check_yaml
|
@@ -23,6 +24,26 @@ class Brakeman::CheckDeserialize < Brakeman::BaseCheck
|
|
23
24
|
check_methods :Marshal, :load, :restore
|
24
25
|
end
|
25
26
|
|
27
|
+
def check_oj
|
28
|
+
check_methods :Oj, :object_load # Always unsafe, regardless of mode
|
29
|
+
|
30
|
+
unsafe_mode = :object
|
31
|
+
safe_default = oj_safe_default?
|
32
|
+
|
33
|
+
tracker.find_call(:target => :Oj, :method => :load).each do |result|
|
34
|
+
call = result[:call]
|
35
|
+
options = call.second_arg
|
36
|
+
|
37
|
+
if options and hash? options and mode = hash_access(options, :mode)
|
38
|
+
if symbol? mode and mode.value == unsafe_mode
|
39
|
+
check_deserialize result, :Oj
|
40
|
+
end
|
41
|
+
elsif not safe_default
|
42
|
+
check_deserialize result, :Oj
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
26
47
|
def check_methods target, *methods
|
27
48
|
tracker.find_call(:target => target, :methods => methods ).each do |result|
|
28
49
|
check_deserialize result, target
|
@@ -53,4 +74,35 @@ class Brakeman::CheckDeserialize < Brakeman::BaseCheck
|
|
53
74
|
:link_path => "unsafe_deserialization"
|
54
75
|
end
|
55
76
|
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def oj_safe_default?
|
81
|
+
safe_default = false
|
82
|
+
|
83
|
+
# TODO: Can we just index initializers already??
|
84
|
+
if tracker.check_initializers(:Oj, :mimic_JSON).any?
|
85
|
+
safe_default = true
|
86
|
+
end
|
87
|
+
|
88
|
+
if result = tracker.check_initializers(:Oj, :default_options=).first
|
89
|
+
options = result.call.first_arg
|
90
|
+
|
91
|
+
if oj_safe_mode? options
|
92
|
+
safe_default = true
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
safe_default
|
97
|
+
end
|
98
|
+
|
99
|
+
def oj_safe_mode? options
|
100
|
+
if hash? options and mode = hash_access(options, :mode)
|
101
|
+
if symbol? mode and mode != :object
|
102
|
+
return true
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
false
|
107
|
+
end
|
56
108
|
end
|
@@ -43,6 +43,6 @@ class Brakeman::CheckDynamicFinders < Brakeman::BaseCheck
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def potentially_dangerous? method_name
|
46
|
-
method_name.match
|
46
|
+
method_name.match(/^find_by_.*(token|guid|password|api_key|activation|code|private|reset)/)
|
47
47
|
end
|
48
48
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class Brakeman::CheckForceSSL < Brakeman::BaseCheck
|
2
|
+
Brakeman::Checks.add_optional self
|
3
|
+
|
4
|
+
@description = "Check that force_ssl setting is enabled in production"
|
5
|
+
|
6
|
+
def run_check
|
7
|
+
return if tracker.config.rails.empty? or tracker.config.rails_version.nil?
|
8
|
+
return if tracker.config.rails_version < "3.1.0"
|
9
|
+
|
10
|
+
force_ssl = tracker.config.rails[:force_ssl]
|
11
|
+
|
12
|
+
if false? force_ssl or force_ssl.nil?
|
13
|
+
line = if sexp? force_ssl
|
14
|
+
force_ssl.line
|
15
|
+
else
|
16
|
+
1
|
17
|
+
end
|
18
|
+
|
19
|
+
warn :warning_type => "Missing Encryption",
|
20
|
+
:warning_code => :force_ssl_disabled,
|
21
|
+
:message => msg("The application does not force use of HTTPS: ", msg_code("config.force_ssl"), " is not enabled"),
|
22
|
+
:confidence => :high,
|
23
|
+
:file => "config/environments/production.rb",
|
24
|
+
:line => line
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -5,6 +5,11 @@ class Brakeman::CheckJSONParsing < Brakeman::BaseCheck
|
|
5
5
|
|
6
6
|
@description = "Checks for JSON parsing vulnerabilities CVE-2013-0333 and CVE-2013-0269"
|
7
7
|
|
8
|
+
def initialize *args
|
9
|
+
super
|
10
|
+
@uses_json_parse = nil
|
11
|
+
end
|
12
|
+
|
8
13
|
def run_check
|
9
14
|
check_cve_2013_0333
|
10
15
|
check_cve_2013_0269
|
@@ -34,7 +34,12 @@ class Brakeman::CheckLinkToHref < Brakeman::CheckLinkTo
|
|
34
34
|
#an ignored method call by the code above.
|
35
35
|
call = result[:call] = result[:call].dup
|
36
36
|
@matched = false
|
37
|
-
|
37
|
+
|
38
|
+
url_arg = if result[:block]
|
39
|
+
process call.first_arg
|
40
|
+
else
|
41
|
+
process call.second_arg
|
42
|
+
end
|
38
43
|
|
39
44
|
if check_argument? url_arg
|
40
45
|
url_arg = url_arg.first_arg
|
@@ -24,7 +24,7 @@ class Brakeman::CheckMailTo < Brakeman::BaseCheck
|
|
24
24
|
:warning_code => :CVE_2011_0446,
|
25
25
|
:message => message,
|
26
26
|
:confidence => :high,
|
27
|
-
:gem_info => gemfile_or_environment,
|
27
|
+
:gem_info => gemfile_or_environment, # Probably ignored now
|
28
28
|
:link_path => "https://groups.google.com/d/topic/rubyonrails-security/8CpI7egxX4E/discussion"
|
29
29
|
end
|
30
30
|
end
|
@@ -25,7 +25,7 @@ class Brakeman::CheckModelAttrAccessible < Brakeman::BaseCheck
|
|
25
25
|
|
26
26
|
SUSP_ATTRS.each do |susp_attr, confidence|
|
27
27
|
if susp_attr.is_a?(Regexp) and susp_attr =~ attribute.to_s or susp_attr == attribute
|
28
|
-
warn :model =>
|
28
|
+
warn :model => model,
|
29
29
|
:file => model.file,
|
30
30
|
:warning_type => "Mass Assignment",
|
31
31
|
:warning_code => :dangerous_attr_accessible,
|
@@ -2,9 +2,6 @@ require 'brakeman/checks/base_check'
|
|
2
2
|
|
3
3
|
#Check if mass assignment is used with models
|
4
4
|
#which inherit from ActiveRecord::Base.
|
5
|
-
#
|
6
|
-
#If tracker.options[:collapse_mass_assignment] is +true+ (default), all models
|
7
|
-
#which do not use attr_accessible will be reported in a single warning
|
8
5
|
class Brakeman::CheckModelAttributes < Brakeman::BaseCheck
|
9
6
|
Brakeman::Checks.add self
|
10
7
|
|
@@ -15,26 +12,19 @@ class Brakeman::CheckModelAttributes < Brakeman::BaseCheck
|
|
15
12
|
|
16
13
|
#Roll warnings into one warning for all models
|
17
14
|
if tracker.options[:collapse_mass_assignment]
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
check_models do |name, model|
|
22
|
-
if model.attr_protected.nil?
|
23
|
-
no_accessible_names << name.to_s
|
24
|
-
elsif not tracker.options[:ignore_attr_protected]
|
25
|
-
protected_names << name.to_s
|
26
|
-
end
|
27
|
-
end
|
15
|
+
Brakeman.notify "[Notice] The `collapse_mass_assignment` option has been removed."
|
16
|
+
end
|
28
17
|
|
29
|
-
|
30
|
-
|
18
|
+
check_models do |name, model|
|
19
|
+
if model.attr_protected.nil?
|
20
|
+
warn :model => model,
|
21
|
+
:file => model.file,
|
22
|
+
:line => model.top_line,
|
31
23
|
:warning_type => "Attribute Restriction",
|
32
24
|
:warning_code => :no_attr_accessible,
|
33
25
|
:message => msg("Mass assignment is not restricted using ", msg_code("attr_accessible")),
|
34
26
|
:confidence => :high
|
35
|
-
|
36
|
-
|
37
|
-
unless protected_names.empty?
|
27
|
+
elsif not tracker.options[:ignore_attr_protected]
|
38
28
|
message, confidence, link = check_for_attr_protected_bypass
|
39
29
|
|
40
30
|
if link
|
@@ -43,41 +33,13 @@ class Brakeman::CheckModelAttributes < Brakeman::BaseCheck
|
|
43
33
|
warning_code = :attr_protected_used
|
44
34
|
end
|
45
35
|
|
46
|
-
warn :model =>
|
36
|
+
warn :model => model,
|
37
|
+
:file => model.file,
|
38
|
+
:line => model.attr_protected.first.line,
|
47
39
|
:warning_type => "Attribute Restriction",
|
48
40
|
:warning_code => warning_code,
|
49
41
|
:message => message,
|
50
|
-
:confidence => confidence
|
51
|
-
:link => link
|
52
|
-
end
|
53
|
-
else #Output one warning per model
|
54
|
-
|
55
|
-
check_models do |name, model|
|
56
|
-
if model.attr_protected.nil?
|
57
|
-
warn :model => name,
|
58
|
-
:file => model.file,
|
59
|
-
:line => model.top_line,
|
60
|
-
:warning_type => "Attribute Restriction",
|
61
|
-
:warning_code => :no_attr_accessible,
|
62
|
-
:message => msg("Mass assignment is not restricted using ", msg_code("attr_accessible")),
|
63
|
-
:confidence => :high
|
64
|
-
elsif not tracker.options[:ignore_attr_protected]
|
65
|
-
message, confidence, link = check_for_attr_protected_bypass
|
66
|
-
|
67
|
-
if link
|
68
|
-
warning_code = :CVE_2013_0276
|
69
|
-
else
|
70
|
-
warning_code = :attr_protected_used
|
71
|
-
end
|
72
|
-
|
73
|
-
warn :model => name,
|
74
|
-
:file => model.file,
|
75
|
-
:line => model.attr_protected.first.line,
|
76
|
-
:warning_type => "Attribute Restriction",
|
77
|
-
:warning_code => warning_code,
|
78
|
-
:message => message,
|
79
|
-
:confidence => confidence
|
80
|
-
end
|
42
|
+
:confidence => confidence
|
81
43
|
end
|
82
44
|
end
|
83
45
|
end
|
@@ -54,7 +54,7 @@ class Brakeman::CheckModelSerialize < Brakeman::BaseCheck
|
|
54
54
|
confidence = :high
|
55
55
|
end
|
56
56
|
|
57
|
-
warn :model => model
|
57
|
+
warn :model => model,
|
58
58
|
:warning_type => "Remote Code Execution",
|
59
59
|
:warning_code => :CVE_2013_0277,
|
60
60
|
:message => msg("Serialized attributes are vulnerable in ", msg_version(rails_version), ", upgrade to ", msg_version(@upgrade_version), " or patch"),
|
@@ -22,17 +22,17 @@ class Brakeman::CheckNestedAttributesBypass < Brakeman::BaseCheck
|
|
22
22
|
if opts = model.options[:accepts_nested_attributes_for]
|
23
23
|
opts.each do |args|
|
24
24
|
if args.any? { |a| allow_destroy? a } and args.any? { |a| reject_if? a }
|
25
|
-
warn_about_nested_attributes
|
25
|
+
warn_about_nested_attributes model, args
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
def warn_about_nested_attributes
|
32
|
+
def warn_about_nested_attributes model, args
|
33
33
|
message = msg(msg_version(rails_version), " does not call ", msg_code(":reject_if"), " option when ", msg_code(":allow_destroy"), " is ", msg_code("false"), " ", msg_cve("CVE-2015-7577"))
|
34
34
|
|
35
|
-
warn :model =>
|
35
|
+
warn :model => model,
|
36
36
|
:warning_type => "Nested Attributes",
|
37
37
|
:warning_code => :CVE_2015_7577,
|
38
38
|
:message => message,
|
@@ -35,6 +35,6 @@ class Brakeman::CheckSecrets < Brakeman::BaseCheck
|
|
35
35
|
|
36
36
|
def looks_like_secret? name
|
37
37
|
# REST_AUTH_SITE_KEY is the pepper in Devise
|
38
|
-
name.match
|
38
|
+
name.match(/password|secret|(rest_auth_site|api)_key$/i)
|
39
39
|
end
|
40
40
|
end
|
@@ -19,7 +19,7 @@ class Brakeman::CheckSessionSettings < Brakeman::BaseCheck
|
|
19
19
|
def run_check
|
20
20
|
settings = tracker.config.session_settings
|
21
21
|
|
22
|
-
check_for_issues settings, @app_tree.
|
22
|
+
check_for_issues settings, @app_tree.file_path("config/environment.rb")
|
23
23
|
|
24
24
|
["session_store.rb", "secret_token.rb"].each do |file|
|
25
25
|
if tracker.initializers[file] and not ignored? file
|
@@ -42,13 +42,13 @@ class Brakeman::CheckSessionSettings < Brakeman::BaseCheck
|
|
42
42
|
#in Rails 4.x apps
|
43
43
|
def process_attrasgn exp
|
44
44
|
if not tracker.options[:rails3] and exp.target == @session_settings and exp.method == :session=
|
45
|
-
check_for_issues exp.first_arg, @app_tree.
|
45
|
+
check_for_issues exp.first_arg, @app_tree.file_path("config/initializers/session_store.rb")
|
46
46
|
end
|
47
47
|
|
48
48
|
if tracker.options[:rails3] and settings_target?(exp.target) and
|
49
49
|
(exp.method == :secret_token= or exp.method == :secret_key_base=) and string? exp.first_arg
|
50
50
|
|
51
|
-
warn_about_secret_token exp.line, @app_tree.
|
51
|
+
warn_about_secret_token exp.line, @app_tree.file_path("config/initializers/secret_token.rb")
|
52
52
|
end
|
53
53
|
|
54
54
|
exp
|
@@ -58,7 +58,7 @@ class Brakeman::CheckSessionSettings < Brakeman::BaseCheck
|
|
58
58
|
#in Rails 3.x apps
|
59
59
|
def process_call exp
|
60
60
|
if tracker.options[:rails3] and settings_target?(exp.target) and exp.method == :session_store
|
61
|
-
check_for_rails3_issues exp.second_arg, @app_tree.
|
61
|
+
check_for_rails3_issues exp.second_arg, @app_tree.file_path("config/initializers/session_store.rb")
|
62
62
|
end
|
63
63
|
|
64
64
|
exp
|
@@ -109,10 +109,10 @@ class Brakeman::CheckSessionSettings < Brakeman::BaseCheck
|
|
109
109
|
end
|
110
110
|
|
111
111
|
def check_secrets_yaml
|
112
|
-
secrets_file = "config/secrets.yml"
|
112
|
+
secrets_file = @app_tree.file_path("config/secrets.yml")
|
113
113
|
|
114
|
-
if
|
115
|
-
yaml =
|
114
|
+
if secrets_file.exists? and not ignored? "secrets.yml" and not ignored? "config/*.yml"
|
115
|
+
yaml = secrets_file.read
|
116
116
|
require 'date' # https://github.com/dtao/safe_yaml/issues/80
|
117
117
|
require 'safe_yaml/load'
|
118
118
|
begin
|
@@ -127,7 +127,7 @@ class Brakeman::CheckSessionSettings < Brakeman::BaseCheck
|
|
127
127
|
unless secret.include? "<%="
|
128
128
|
line = yaml.lines.find_index { |l| l.include? secret } + 1
|
129
129
|
|
130
|
-
warn_about_secret_token line, @app_tree.
|
130
|
+
warn_about_secret_token line, @app_tree.file_path(secrets_file)
|
131
131
|
end
|
132
132
|
end
|
133
133
|
end
|
@@ -163,9 +163,9 @@ class Brakeman::CheckSessionSettings < Brakeman::BaseCheck
|
|
163
163
|
|
164
164
|
def ignored? file
|
165
165
|
[".", "config", "config/initializers"].each do |dir|
|
166
|
-
ignore_file = "#{dir}/.gitignore"
|
166
|
+
ignore_file = @app_tree.file_path("#{dir}/.gitignore")
|
167
167
|
if @app_tree.exists? ignore_file
|
168
|
-
input =
|
168
|
+
input = ignore_file.read
|
169
169
|
|
170
170
|
return true if input.include? file
|
171
171
|
end
|
@@ -5,6 +5,11 @@ class Brakeman::CheckSimpleFormat < Brakeman::CheckCrossSiteScripting
|
|
5
5
|
|
6
6
|
@description = "Checks for simple_format XSS vulnerability (CVE-2013-6416) in certain versions"
|
7
7
|
|
8
|
+
def initialize *args
|
9
|
+
super
|
10
|
+
@found_any = false
|
11
|
+
end
|
12
|
+
|
8
13
|
def run_check
|
9
14
|
if version_between? "4.0.0", "4.0.1"
|
10
15
|
@inspect_arguments = true
|
@@ -38,7 +38,7 @@ class Brakeman::CheckSkipBeforeFilter < Brakeman::BaseCheck
|
|
38
38
|
:message => msg("Use whitelist (", msg_code(":only => [..]"), ") when skipping authentication"),
|
39
39
|
:code => filter,
|
40
40
|
:confidence => :medium,
|
41
|
-
:
|
41
|
+
:link_path => "authentication_whitelist",
|
42
42
|
:file => controller.file
|
43
43
|
end
|
44
44
|
end
|
@@ -21,7 +21,8 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
21
21
|
@sql_targets = [:average, :calculate, :count, :count_by_sql, :delete_all, :destroy_all,
|
22
22
|
:find_by_sql, :maximum, :minimum, :pluck, :sum, :update_all]
|
23
23
|
@sql_targets.concat [:from, :group, :having, :joins, :lock, :order, :reorder, :where] if tracker.options[:rails3]
|
24
|
-
@sql_targets
|
24
|
+
@sql_targets.concat [:find_by, :find_by!, :find_or_create_by, :find_or_create_by!, :find_or_initialize_by, :not] if tracker.options[:rails4]
|
25
|
+
@sql_targets << :delete_by << :destroy_by if tracker.options[:rails6]
|
25
26
|
|
26
27
|
if version_between?("2.0.0", "3.9.9") or tracker.config.rails_version.nil?
|
27
28
|
@sql_targets << :first << :last << :all
|
@@ -71,23 +72,23 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
71
72
|
scope_calls = []
|
72
73
|
|
73
74
|
if version_between?("2.1.0", "3.0.9")
|
74
|
-
ar_scope_calls(:named_scope) do |
|
75
|
+
ar_scope_calls(:named_scope) do |model, args|
|
75
76
|
call = make_call(nil, :named_scope, args).line(args.line)
|
76
|
-
scope_calls << scope_call_hash(call,
|
77
|
+
scope_calls << scope_call_hash(call, model, :named_scope)
|
77
78
|
end
|
78
79
|
elsif version_between?("3.1.0", "9.9.9")
|
79
|
-
ar_scope_calls(:scope) do |
|
80
|
+
ar_scope_calls(:scope) do |model, args|
|
80
81
|
second_arg = args[2]
|
81
82
|
next unless sexp? second_arg
|
82
83
|
|
83
84
|
if second_arg.node_type == :iter and node_type? second_arg.block, :block, :call, :safe_call
|
84
|
-
process_scope_with_block(
|
85
|
+
process_scope_with_block(model, args)
|
85
86
|
elsif call? second_arg
|
86
87
|
call = second_arg
|
87
|
-
scope_calls << scope_call_hash(call,
|
88
|
+
scope_calls << scope_call_hash(call, model, call.method)
|
88
89
|
else
|
89
90
|
call = make_call(nil, :scope, args).line(args.line)
|
90
|
-
scope_calls << scope_call_hash(call,
|
91
|
+
scope_calls << scope_call_hash(call, model, :scope)
|
91
92
|
end
|
92
93
|
end
|
93
94
|
end
|
@@ -96,37 +97,34 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
96
97
|
end
|
97
98
|
|
98
99
|
def ar_scope_calls(symbol_name = :named_scope, &block)
|
99
|
-
return_array = []
|
100
100
|
active_record_models.each do |name, model|
|
101
101
|
model_args = model.options[symbol_name]
|
102
102
|
if model_args
|
103
103
|
model_args.each do |args|
|
104
|
-
yield
|
105
|
-
return_array << [name, args]
|
104
|
+
yield model, args
|
106
105
|
end
|
107
106
|
end
|
108
107
|
end
|
109
|
-
return_array
|
110
108
|
end
|
111
109
|
|
112
|
-
def scope_call_hash(call,
|
113
|
-
{ :call => call, :location => { :type => :class, :class => name }, :method => :named_scope }
|
110
|
+
def scope_call_hash(call, model, method)
|
111
|
+
{ :call => call, :location => { :type => :class, :class => model.name, :file => model.file }, :method => :named_scope }
|
114
112
|
end
|
115
113
|
|
116
114
|
|
117
|
-
def process_scope_with_block
|
115
|
+
def process_scope_with_block model, args
|
118
116
|
scope_name = args[1][1]
|
119
117
|
block = args[-1][-1]
|
120
118
|
|
121
119
|
# Search lambda for calls to query methods
|
122
120
|
if block.node_type == :block
|
123
121
|
find_calls = Brakeman::FindAllCalls.new(tracker)
|
124
|
-
find_calls.process_source(block, :class =>
|
122
|
+
find_calls.process_source(block, :class => model.name, :method => scope_name, :file => model.file)
|
125
123
|
find_calls.calls.each { |call| process_result(call) if @sql_targets.include?(call[:method]) }
|
126
124
|
elsif call? block
|
127
125
|
while call? block
|
128
126
|
process_result :target => block.target, :method => block.method, :call => block,
|
129
|
-
|
127
|
+
:location => { :type => :class, :class => model.name, :method => scope_name, :file => model.file }
|
130
128
|
|
131
129
|
block = block.target
|
132
130
|
end
|
@@ -187,7 +185,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
187
185
|
else
|
188
186
|
check_find_arguments call.last_arg
|
189
187
|
end
|
190
|
-
when :where, :having, :find_by, :find_by!, :not
|
188
|
+
when :where, :having, :find_by, :find_by!, :find_or_create_by, :find_or_create_by!, :find_or_initialize_by,:not, :delete_by, :destroy_by
|
191
189
|
check_query_arguments call.arglist
|
192
190
|
when :order, :group, :reorder
|
193
191
|
check_order_arguments call.arglist
|