brakeman 4.8.0 → 4.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +39 -1
- data/README.md +12 -4
- data/bundle/load.rb +4 -4
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.14.2 → ruby_parser-3.15.0}/History.rdoc +35 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.14.2 → ruby_parser-3.15.0}/Manifest.txt +2 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.14.2 → ruby_parser-3.15.0}/README.rdoc +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.14.2 → ruby_parser-3.15.0}/compare/normalize.rb +43 -3
- data/bundle/ruby/2.7.0/gems/ruby_parser-3.15.0/debugging.md +57 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.14.2 → ruby_parser-3.15.0}/lib/rp_extensions.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.14.2 → ruby_parser-3.15.0}/lib/rp_stringscanner.rb +0 -0
- data/bundle/ruby/2.7.0/gems/ruby_parser-3.15.0/lib/ruby20_parser.rb +7062 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.14.2 → ruby_parser-3.15.0}/lib/ruby20_parser.y +91 -58
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.14.2 → ruby_parser-3.15.0}/lib/ruby21_parser.rb +2603 -2576
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.14.2 → ruby_parser-3.15.0}/lib/ruby21_parser.y +91 -58
- data/bundle/ruby/2.7.0/gems/ruby_parser-3.15.0/lib/ruby22_parser.rb +7160 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.14.2 → ruby_parser-3.15.0}/lib/ruby22_parser.y +91 -58
- data/bundle/ruby/2.7.0/gems/ruby_parser-3.15.0/lib/ruby23_parser.rb +7175 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.14.2 → ruby_parser-3.15.0}/lib/ruby23_parser.y +91 -58
- data/bundle/ruby/2.7.0/gems/ruby_parser-3.15.0/lib/ruby24_parser.rb +7204 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.14.2 → ruby_parser-3.15.0}/lib/ruby24_parser.y +91 -58
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.14.2/lib/ruby23_parser.rb → ruby_parser-3.15.0/lib/ruby25_parser.rb} +2867 -2826
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.14.2 → ruby_parser-3.15.0}/lib/ruby25_parser.y +91 -58
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.14.2/lib/ruby25_parser.rb → ruby_parser-3.15.0/lib/ruby26_parser.rb} +2432 -2383
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.14.2 → ruby_parser-3.15.0}/lib/ruby26_parser.y +91 -58
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.14.2/lib/ruby24_parser.rb → ruby_parser-3.15.0/lib/ruby27_parser.rb} +2432 -2383
- data/bundle/ruby/2.7.0/gems/ruby_parser-3.15.0/lib/ruby27_parser.y +2657 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.14.2 → ruby_parser-3.15.0}/lib/ruby_lexer.rb +72 -40
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.14.2 → ruby_parser-3.15.0}/lib/ruby_lexer.rex +5 -6
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.14.2 → ruby_parser-3.15.0}/lib/ruby_lexer.rex.rb +6 -8
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.14.2 → ruby_parser-3.15.0}/lib/ruby_parser.rb +2 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.14.2 → ruby_parser-3.15.0}/lib/ruby_parser.yy +93 -58
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.14.2 → ruby_parser-3.15.0}/lib/ruby_parser_extras.rb +49 -16
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.14.2 → ruby_parser-3.15.0}/tools/munge.rb +9 -4
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.14.2 → ruby_parser-3.15.0}/tools/ripper.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{sexp_processor-4.14.1 → sexp_processor-4.15.1}/History.rdoc +12 -0
- data/bundle/ruby/2.7.0/gems/{sexp_processor-4.14.1 → sexp_processor-4.15.1}/Manifest.txt +0 -0
- data/bundle/ruby/2.7.0/gems/{sexp_processor-4.14.1 → sexp_processor-4.15.1}/README.rdoc +0 -0
- data/bundle/ruby/2.7.0/gems/{sexp_processor-4.14.1 → sexp_processor-4.15.1}/lib/composite_sexp_processor.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{sexp_processor-4.14.1 → sexp_processor-4.15.1}/lib/pt_testcase.rb +2 -2
- data/bundle/ruby/2.7.0/gems/{sexp_processor-4.14.1 → sexp_processor-4.15.1}/lib/sexp.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{sexp_processor-4.14.1 → sexp_processor-4.15.1}/lib/sexp_matcher.rb +4 -7
- data/bundle/ruby/2.7.0/gems/{sexp_processor-4.14.1 → sexp_processor-4.15.1}/lib/sexp_processor.rb +1 -1
- data/bundle/ruby/2.7.0/gems/{sexp_processor-4.14.1 → sexp_processor-4.15.1}/lib/strict_sexp.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{sexp_processor-4.14.1 → sexp_processor-4.15.1}/lib/unique.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/CHANGES +4 -0
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/Gemfile +12 -13
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/LICENSE +0 -0
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/README.jp.md +0 -0
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/README.md +0 -0
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/lib/slim.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/lib/slim/code_attributes.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/lib/slim/command.rb +13 -13
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/lib/slim/controls.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/lib/slim/do_inserter.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/lib/slim/embedded.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/lib/slim/end_inserter.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/lib/slim/engine.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/lib/slim/erb_converter.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/lib/slim/filter.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/lib/slim/grammar.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/lib/slim/include.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/lib/slim/interpolation.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/lib/slim/logic_less.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/lib/slim/logic_less/context.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/lib/slim/logic_less/filter.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/lib/slim/parser.rb +1 -1
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/lib/slim/smart.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/lib/slim/smart/escaper.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/lib/slim/smart/filter.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/lib/slim/smart/parser.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/lib/slim/splat/builder.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/lib/slim/splat/filter.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/lib/slim/template.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/lib/slim/translator.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/lib/slim/version.rb +1 -1
- data/bundle/ruby/2.7.0/gems/{slim-4.0.1 → slim-4.1.0}/slim.gemspec +0 -0
- data/bundle/ruby/2.7.0/gems/{unicode-display_width-1.6.1 → unicode-display_width-1.7.0}/CHANGELOG.md +4 -0
- data/bundle/ruby/2.7.0/gems/{unicode-display_width-1.6.1 → unicode-display_width-1.7.0}/MIT-LICENSE.txt +0 -0
- data/bundle/ruby/2.7.0/gems/{unicode-display_width-1.6.1 → unicode-display_width-1.7.0}/README.md +1 -1
- data/bundle/ruby/2.7.0/gems/unicode-display_width-1.7.0/data/display_width.marshal.gz +0 -0
- data/bundle/ruby/2.7.0/gems/{unicode-display_width-1.6.1 → unicode-display_width-1.7.0}/lib/unicode/display_width.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{unicode-display_width-1.6.1 → unicode-display_width-1.7.0}/lib/unicode/display_width/constants.rb +2 -2
- data/bundle/ruby/2.7.0/gems/{unicode-display_width-1.6.1 → unicode-display_width-1.7.0}/lib/unicode/display_width/index.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{unicode-display_width-1.6.1 → unicode-display_width-1.7.0}/lib/unicode/display_width/no_string_ext.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{unicode-display_width-1.6.1 → unicode-display_width-1.7.0}/lib/unicode/display_width/string_ext.rb +0 -0
- data/lib/brakeman.rb +20 -0
- data/lib/brakeman/checks/base_check.rb +1 -1
- data/lib/brakeman/checks/check_basic_auth.rb +2 -0
- data/lib/brakeman/checks/check_csrf_token_forgery_cve.rb +28 -0
- data/lib/brakeman/checks/check_deserialize.rb +21 -1
- data/lib/brakeman/checks/check_json_entity_escape.rb +38 -0
- data/lib/brakeman/checks/check_mass_assignment.rb +33 -3
- data/lib/brakeman/checks/check_model_attr_accessible.rb +1 -1
- data/lib/brakeman/checks/check_model_attributes.rb +1 -1
- data/lib/brakeman/checks/check_page_caching_cve.rb +37 -0
- data/lib/brakeman/checks/check_permit_attributes.rb +1 -1
- data/lib/brakeman/checks/check_skip_before_filter.rb +4 -4
- data/lib/brakeman/checks/check_sql.rb +1 -1
- data/lib/brakeman/checks/check_template_injection.rb +32 -0
- data/lib/brakeman/commandline.rb +25 -1
- data/lib/brakeman/options.rb +21 -1
- data/lib/brakeman/processors/alias_processor.rb +2 -3
- data/lib/brakeman/processors/lib/call_conversion_helper.rb +1 -1
- data/lib/brakeman/processors/lib/find_all_calls.rb +28 -13
- data/lib/brakeman/processors/lib/render_helper.rb +3 -1
- data/lib/brakeman/report.rb +7 -0
- data/lib/brakeman/report/ignore/config.rb +4 -0
- data/lib/brakeman/report/report_sarif.rb +114 -0
- data/lib/brakeman/report/report_text.rb +37 -16
- data/lib/brakeman/scanner.rb +4 -1
- data/lib/brakeman/tracker.rb +3 -1
- data/lib/brakeman/tracker/config.rb +6 -4
- data/lib/brakeman/tracker/constants.rb +8 -7
- data/lib/brakeman/util.rb +16 -0
- data/lib/brakeman/version.rb +1 -1
- data/lib/brakeman/warning_codes.rb +7 -0
- metadata +89 -82
- data/bundle/ruby/2.7.0/gems/ruby_parser-3.14.2/debugging.md +0 -18
- data/bundle/ruby/2.7.0/gems/ruby_parser-3.14.2/lib/ruby20_parser.rb +0 -7042
- data/bundle/ruby/2.7.0/gems/ruby_parser-3.14.2/lib/ruby22_parser.rb +0 -7146
- data/bundle/ruby/2.7.0/gems/ruby_parser-3.14.2/lib/ruby26_parser.rb +0 -7195
- data/bundle/ruby/2.7.0/gems/unicode-display_width-1.6.1/data/display_width.marshal.gz +0 -0
File without changes
|
File without changes
|
data/bundle/ruby/2.7.0/gems/{unicode-display_width-1.6.1 → unicode-display_width-1.7.0}/README.md
RENAMED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Determines the monospace display width of a string in Ruby. Implementation based on [EastAsianWidth.txt](https://www.unicode.org/Public/UNIDATA/EastAsianWidth.txt) and other data, 100% in Ruby. Other than [wcwidth()](https://github.com/janlelis/wcswidth-ruby), which fulfills a similar purpose, it does not rely on the OS vendor to provide an up-to-date method for measuring string width.
|
4
4
|
|
5
|
-
Unicode version: **
|
5
|
+
Unicode version: **13.0.0** (March 2020)
|
6
6
|
|
7
7
|
Supported Rubies: **2.7**, **2.6**, **2.5**, **2.4**
|
8
8
|
|
Binary file
|
File without changes
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Unicode
|
2
2
|
module DisplayWidth
|
3
|
-
VERSION = '1.
|
4
|
-
UNICODE_VERSION = "
|
3
|
+
VERSION = '1.7.0'
|
4
|
+
UNICODE_VERSION = "13.0.0".freeze
|
5
5
|
DATA_DIRECTORY = File.expand_path(File.dirname(__FILE__) + '/../../../data/').freeze
|
6
6
|
INDEX_FILENAME = (DATA_DIRECTORY + '/display_width.marshal.gz').freeze
|
7
7
|
end
|
File without changes
|
File without changes
|
File without changes
|
data/lib/brakeman.rb
CHANGED
@@ -20,6 +20,10 @@ module Brakeman
|
|
20
20
|
#option is set
|
21
21
|
Errors_Found_Exit_Code = 7
|
22
22
|
|
23
|
+
#Exit code returned when an ignored warning has no note and
|
24
|
+
#--ensure-ignore-notes is set
|
25
|
+
Empty_Ignore_Note_Exit_Code = 8
|
26
|
+
|
23
27
|
@debug = false
|
24
28
|
@quiet = false
|
25
29
|
@loaded_dependencies = []
|
@@ -233,6 +237,8 @@ module Brakeman
|
|
233
237
|
[:to_table]
|
234
238
|
when :junit, :to_junit
|
235
239
|
[:to_junit]
|
240
|
+
when :sarif, :to_sarif
|
241
|
+
[:to_sarif]
|
236
242
|
else
|
237
243
|
[:to_text]
|
238
244
|
end
|
@@ -262,6 +268,8 @@ module Brakeman
|
|
262
268
|
:to_table
|
263
269
|
when /\.junit$/i
|
264
270
|
:to_junit
|
271
|
+
when /\.sarif$/i
|
272
|
+
:to_sarif
|
265
273
|
else
|
266
274
|
:to_text
|
267
275
|
end
|
@@ -498,6 +506,18 @@ module Brakeman
|
|
498
506
|
end
|
499
507
|
end
|
500
508
|
|
509
|
+
# Returns an array of alert fingerprints for any ignored warnings without
|
510
|
+
# notes found in the specified ignore file (if it exists).
|
511
|
+
def self.ignore_file_entries_with_empty_notes file
|
512
|
+
return [] unless file
|
513
|
+
|
514
|
+
require 'brakeman/report/ignore/config'
|
515
|
+
|
516
|
+
config = IgnoreConfig.new(file, nil)
|
517
|
+
config.read_from_file
|
518
|
+
config.already_ignored_entries_with_empty_notes.map { |i| i[:fingerprint] }
|
519
|
+
end
|
520
|
+
|
501
521
|
def self.filter_warnings tracker, options
|
502
522
|
require 'brakeman/report/ignore/config'
|
503
523
|
|
@@ -467,7 +467,7 @@ class Brakeman::BaseCheck < Brakeman::SexpProcessor
|
|
467
467
|
end
|
468
468
|
|
469
469
|
def gemfile_or_environment gem_name = :rails
|
470
|
-
if gem_name and info = tracker.config.get_gem(gem_name)
|
470
|
+
if gem_name and info = tracker.config.get_gem(gem_name.to_sym)
|
471
471
|
info
|
472
472
|
elsif @app_tree.exists?("Gemfile")
|
473
473
|
@app_tree.file_path "Gemfile"
|
@@ -57,6 +57,8 @@ class Brakeman::CheckBasicAuth < Brakeman::BaseCheck
|
|
57
57
|
|
58
58
|
# Check if the block of a result contains a comparison of password to string
|
59
59
|
def include_password_literal? result
|
60
|
+
return false if result[:block_args].nil?
|
61
|
+
|
60
62
|
@password_var = result[:block_args].last
|
61
63
|
@include_password = false
|
62
64
|
process result[:block]
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'brakeman/checks/base_check'
|
2
|
+
|
3
|
+
class Brakeman::CheckCSRFTokenForgeryCVE < Brakeman::BaseCheck
|
4
|
+
Brakeman::Checks.add self
|
5
|
+
|
6
|
+
@description = "Checks for versions with CSRF token forgery vulnerability (CVE-2020-8166)"
|
7
|
+
|
8
|
+
def run_check
|
9
|
+
fix_version = case
|
10
|
+
when version_between?('0.0.0', '5.2.4.2')
|
11
|
+
'5.2.4.3'
|
12
|
+
when version_between?('6.0.0', '6.0.3')
|
13
|
+
'6.0.3.1'
|
14
|
+
else
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
|
18
|
+
if fix_version
|
19
|
+
warn :warning_type => "Cross-Site Request Forgery",
|
20
|
+
:warning_code => :CVE_2020_8166,
|
21
|
+
:message => msg(msg_version(rails_version), " has a vulnerability that may allow CSRF token forgery. Upgrade to ", msg_version(fix_version), " or patch"),
|
22
|
+
:confidence => :medium,
|
23
|
+
:gem_info => gemfile_or_environment,
|
24
|
+
:link => "https://groups.google.com/g/rubyonrails-security/c/NOjKiGeXUgw"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
@@ -13,7 +13,23 @@ class Brakeman::CheckDeserialize < Brakeman::BaseCheck
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def check_yaml
|
16
|
-
check_methods :YAML, :
|
16
|
+
check_methods :YAML, :load_documents, :load_stream, :parse_documents, :parse_stream
|
17
|
+
|
18
|
+
# Check for safe_yaml gem use with YAML.load(..., safe: true)
|
19
|
+
if uses_safe_yaml?
|
20
|
+
tracker.find_call(target: :YAML, method: :load).each do |result|
|
21
|
+
call = result[:call]
|
22
|
+
options = call.second_arg
|
23
|
+
|
24
|
+
if hash? options and true? hash_access(options, :safe)
|
25
|
+
next
|
26
|
+
else
|
27
|
+
check_deserialize result, :YAML
|
28
|
+
end
|
29
|
+
end
|
30
|
+
else
|
31
|
+
check_methods :YAML, :load
|
32
|
+
end
|
17
33
|
end
|
18
34
|
|
19
35
|
def check_csv
|
@@ -102,4 +118,8 @@ class Brakeman::CheckDeserialize < Brakeman::BaseCheck
|
|
102
118
|
|
103
119
|
false
|
104
120
|
end
|
121
|
+
|
122
|
+
def uses_safe_yaml?
|
123
|
+
tracker.config.has_gem? :safe_yaml
|
124
|
+
end
|
105
125
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'brakeman/checks/base_check'
|
2
|
+
|
3
|
+
class Brakeman::CheckJSONEntityEscape < Brakeman::BaseCheck
|
4
|
+
Brakeman::Checks.add self
|
5
|
+
|
6
|
+
@description = "Check if HTML escaping is disabled for JSON output"
|
7
|
+
|
8
|
+
def run_check
|
9
|
+
check_config_setting
|
10
|
+
check_manual_disable
|
11
|
+
end
|
12
|
+
|
13
|
+
def check_config_setting
|
14
|
+
if false? tracker.config.rails.dig(:active_support, :escape_html_entities_in_json)
|
15
|
+
warn :warning_type => "Cross-Site Scripting",
|
16
|
+
:warning_code => :json_html_escape_config,
|
17
|
+
:message => msg("HTML entities in JSON are not escaped by default"),
|
18
|
+
:confidence => :medium,
|
19
|
+
:file => "config/environments/production.rb",
|
20
|
+
:line => 1
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def check_manual_disable
|
25
|
+
tracker.find_call(targets: [:ActiveSupport, :'ActiveSupport::JSON::Encoding'], method: :escape_html_entities_in_json=).each do |result|
|
26
|
+
setting = result[:call].first_arg
|
27
|
+
|
28
|
+
if false? setting
|
29
|
+
warn :result => result,
|
30
|
+
:warning_type => "Cross-Site Scripting",
|
31
|
+
:warning_code => :json_html_escape_module,
|
32
|
+
:message => msg("HTML entities in JSON are not escaped by default"),
|
33
|
+
:confidence => :medium,
|
34
|
+
:file => "config/environments/production.rb"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -17,6 +17,7 @@ class Brakeman::CheckMassAssignment < Brakeman::BaseCheck
|
|
17
17
|
def run_check
|
18
18
|
check_mass_assignment
|
19
19
|
check_permit!
|
20
|
+
check_permit_all_parameters
|
20
21
|
end
|
21
22
|
|
22
23
|
def find_mass_assign_calls
|
@@ -159,12 +160,27 @@ class Brakeman::CheckMassAssignment < Brakeman::BaseCheck
|
|
159
160
|
# Look for and warn about uses of Parameters#permit! for mass assignment
|
160
161
|
def check_permit!
|
161
162
|
tracker.find_call(:method => :permit!, :nested => true).each do |result|
|
162
|
-
if params? result[:call].target
|
163
|
-
|
163
|
+
if params? result[:call].target
|
164
|
+
unless inside_safe_method? result or calls_slice? result
|
165
|
+
warn_on_permit! result
|
166
|
+
end
|
164
167
|
end
|
165
168
|
end
|
166
169
|
end
|
167
170
|
|
171
|
+
# Ignore blah_some_path(params.permit!)
|
172
|
+
def inside_safe_method? result
|
173
|
+
parent_call = result.dig(:parent, :call)
|
174
|
+
|
175
|
+
call? parent_call and
|
176
|
+
parent_call.method.match(/_path$/)
|
177
|
+
end
|
178
|
+
|
179
|
+
def calls_slice? result
|
180
|
+
result[:chain].include? :slice or
|
181
|
+
(result[:full_call] and result[:full_call][:chain].include? :slice)
|
182
|
+
end
|
183
|
+
|
168
184
|
# Look for actual use of params in mass assignment to avoid
|
169
185
|
# warning about uses of Parameters#permit! without any mass assignment
|
170
186
|
# or when mass assignment is restricted by model instead.
|
@@ -190,7 +206,21 @@ class Brakeman::CheckMassAssignment < Brakeman::BaseCheck
|
|
190
206
|
warn :result => result,
|
191
207
|
:warning_type => "Mass Assignment",
|
192
208
|
:warning_code => :mass_assign_permit!,
|
193
|
-
:message =>
|
209
|
+
:message => msg('Specify exact keys allowed for mass assignment instead of using ', msg_code('permit!'), ' which allows any keys'),
|
194
210
|
:confidence => confidence
|
195
211
|
end
|
212
|
+
|
213
|
+
def check_permit_all_parameters
|
214
|
+
tracker.find_call(target: :"ActionController::Parameters", method: :permit_all_parameters=).each do |result|
|
215
|
+
call = result[:call]
|
216
|
+
|
217
|
+
if true? call.first_arg
|
218
|
+
warn :result => result,
|
219
|
+
:warning_type => "Mass Assignment",
|
220
|
+
:warning_code => :mass_assign_permit_all,
|
221
|
+
:message => msg('Mass assignment is globally enabled. Disable and specify exact keys using ', msg_code('params.permit'), ' instead'),
|
222
|
+
:confidence => :high
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
196
226
|
end
|
@@ -8,7 +8,7 @@ require 'brakeman/checks/base_check'
|
|
8
8
|
class Brakeman::CheckModelAttrAccessible < Brakeman::BaseCheck
|
9
9
|
Brakeman::Checks.add self
|
10
10
|
|
11
|
-
@description = "Reports models which have dangerous attributes defined
|
11
|
+
@description = "Reports models which have dangerous attributes defined via attr_accessible"
|
12
12
|
|
13
13
|
SUSP_ATTRS = [
|
14
14
|
[:admin, :high], # Very dangerous unless some Rails authorization used
|
@@ -8,7 +8,7 @@ class Brakeman::CheckModelAttributes < Brakeman::BaseCheck
|
|
8
8
|
@description = "Reports models which do not use attr_restricted and warns on models that use attr_protected"
|
9
9
|
|
10
10
|
def run_check
|
11
|
-
return if mass_assign_disabled?
|
11
|
+
return if mass_assign_disabled? or tracker.config.has_gem?(:protected_attributes)
|
12
12
|
|
13
13
|
#Roll warnings into one warning for all models
|
14
14
|
if tracker.options[:collapse_mass_assignment]
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'brakeman/checks/base_check'
|
2
|
+
|
3
|
+
class Brakeman::CheckPageCachingCVE < Brakeman::BaseCheck
|
4
|
+
Brakeman::Checks.add self
|
5
|
+
|
6
|
+
@description = "Check for page caching vulnerability (CVE-2020-8159)"
|
7
|
+
|
8
|
+
def run_check
|
9
|
+
gem_name = 'actionpack-page_caching'
|
10
|
+
gem_version = tracker.config.gem_version(gem_name.to_sym)
|
11
|
+
upgrade_version = '1.2.2'
|
12
|
+
cve = 'CVE-2020-8159'
|
13
|
+
|
14
|
+
return unless gem_version and version_between?('0.0.0', '1.2.1', gem_version)
|
15
|
+
|
16
|
+
message = msg("Directory traversal vulnerability in ", msg_version(gem_version, gem_name), " ", msg_cve(cve), ". Upgrade to ", msg_version(upgrade_version, gem_name))
|
17
|
+
|
18
|
+
if uses_caches_page?
|
19
|
+
confidence = :high
|
20
|
+
else
|
21
|
+
confidence = :weak
|
22
|
+
end
|
23
|
+
|
24
|
+
warn :warning_type => 'Directory Traversal',
|
25
|
+
:warning_code => :CVE_2020_8159,
|
26
|
+
:message => message,
|
27
|
+
:confidence => confidence,
|
28
|
+
:link_path => 'https://groups.google.com/d/msg/rubyonrails-security/CFRVkEytdP8/c5gmICECAgAJ',
|
29
|
+
:gem_info => gemfile_or_environment(gem_name)
|
30
|
+
end
|
31
|
+
|
32
|
+
def uses_caches_page?
|
33
|
+
tracker.controllers.any? do |name, controller|
|
34
|
+
controller.options.has_key? :caches_page
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -3,7 +3,7 @@ require 'brakeman/checks/base_check'
|
|
3
3
|
class Brakeman::CheckPermitAttributes < Brakeman::BaseCheck
|
4
4
|
Brakeman::Checks.add self
|
5
5
|
|
6
|
-
@description = "Warn on potentially dangerous attributes
|
6
|
+
@description = "Warn on potentially dangerous attributes allowed via permit"
|
7
7
|
|
8
8
|
SUSPICIOUS_KEYS = {
|
9
9
|
admin: :high,
|
@@ -4,8 +4,8 @@ require 'brakeman/checks/base_check'
|
|
4
4
|
#
|
5
5
|
# skip_before_filter :verify_authenticity_token, :except => [...]
|
6
6
|
#
|
7
|
-
#which is essentially a
|
8
|
-
#ones listed) versus a
|
7
|
+
#which is essentially a skip-by-default approach (no actions are checked EXCEPT the
|
8
|
+
#ones listed) versus a enforce-by-default approach (ONLY the actions listed will skip
|
9
9
|
#the check)
|
10
10
|
class Brakeman::CheckSkipBeforeFilter < Brakeman::BaseCheck
|
11
11
|
Brakeman::Checks.add self
|
@@ -26,7 +26,7 @@ class Brakeman::CheckSkipBeforeFilter < Brakeman::BaseCheck
|
|
26
26
|
warn :class => controller.name, #ugh this should be a controller warning, too
|
27
27
|
:warning_type => "Cross-Site Request Forgery",
|
28
28
|
:warning_code => :csrf_blacklist,
|
29
|
-
:message => msg("
|
29
|
+
:message => msg("List specific actions (", msg_code(":only => [..]"), ") when skipping CSRF check"),
|
30
30
|
:code => filter,
|
31
31
|
:confidence => :medium,
|
32
32
|
:file => controller.file
|
@@ -35,7 +35,7 @@ class Brakeman::CheckSkipBeforeFilter < Brakeman::BaseCheck
|
|
35
35
|
warn :controller => controller.name,
|
36
36
|
:warning_code => :auth_blacklist,
|
37
37
|
:warning_type => "Authentication",
|
38
|
-
:message => msg("
|
38
|
+
:message => msg("List specific actions (", msg_code(":only => [..]"), ") when skipping authentication"),
|
39
39
|
:code => filter,
|
40
40
|
:confidence => :medium,
|
41
41
|
:link_path => "authentication_whitelist",
|
@@ -393,7 +393,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
393
393
|
nil
|
394
394
|
end
|
395
395
|
|
396
|
-
TO_STRING_METHODS = [:to_s, :strip_heredoc]
|
396
|
+
TO_STRING_METHODS = [:chomp, :to_s, :squish, :strip, :strip_heredoc]
|
397
397
|
|
398
398
|
#Returns value if interpolated value is not something safe
|
399
399
|
def unsafe_string_interp? exp
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'brakeman/checks/base_check'
|
2
|
+
|
3
|
+
class Brakeman::CheckTemplateInjection < Brakeman::BaseCheck
|
4
|
+
Brakeman::Checks.add self
|
5
|
+
|
6
|
+
@description = "Searches for evaluation of user input through template injection"
|
7
|
+
|
8
|
+
#Process calls
|
9
|
+
def run_check
|
10
|
+
Brakeman.debug "Finding ERB.new calls"
|
11
|
+
erb_calls = tracker.find_call :target => :ERB, :method => :new, :nested => true
|
12
|
+
|
13
|
+
Brakeman.debug "Processing ERB.new calls"
|
14
|
+
erb_calls.each do |call|
|
15
|
+
process_result call
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
#Warns if eval includes user input
|
20
|
+
def process_result result
|
21
|
+
return unless original? result
|
22
|
+
|
23
|
+
if input = include_user_input?(result[:call].arglist)
|
24
|
+
warn :result => result,
|
25
|
+
:warning_type => "Template Injection",
|
26
|
+
:warning_code => :erb_template_injection,
|
27
|
+
:message => msg(msg_input(input), " used directly in ", msg_code("ERB"), " template, which might enable remote code execution"),
|
28
|
+
:user_input => input,
|
29
|
+
:confidence => :high
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/brakeman/commandline.rb
CHANGED
@@ -102,6 +102,13 @@ module Brakeman
|
|
102
102
|
app_path = "."
|
103
103
|
end
|
104
104
|
|
105
|
+
if options[:ensure_ignore_notes] and options[:previous_results_json]
|
106
|
+
warn '[Notice] --ensure-ignore-notes may not be used at the same ' \
|
107
|
+
'time as --compare. Deactivating --ensure-ignore-notes. ' \
|
108
|
+
'Please see `brakeman --help` for valid options'
|
109
|
+
options[:ensure_ignore_notes] = false
|
110
|
+
end
|
111
|
+
|
105
112
|
return options, app_path
|
106
113
|
end
|
107
114
|
|
@@ -115,7 +122,20 @@ module Brakeman
|
|
115
122
|
|
116
123
|
# Runs a regular report based on the options provided.
|
117
124
|
def regular_report options
|
118
|
-
tracker = run_brakeman options
|
125
|
+
tracker = run_brakeman options
|
126
|
+
|
127
|
+
ensure_ignore_notes_failed = false
|
128
|
+
if tracker.options[:ensure_ignore_notes]
|
129
|
+
fingerprints = Brakeman::ignore_file_entries_with_empty_notes tracker.ignored_filter&.file
|
130
|
+
|
131
|
+
unless fingerprints.empty?
|
132
|
+
ensure_ignore_notes_failed = true
|
133
|
+
warn '[Error] Notes required for all ignored warnings when ' \
|
134
|
+
'--ensure-ignore-notes is set. No notes provided for these ' \
|
135
|
+
'warnings: '
|
136
|
+
fingerprints.each { |f| warn f }
|
137
|
+
end
|
138
|
+
end
|
119
139
|
|
120
140
|
if tracker.options[:exit_on_warn] and not tracker.filtered_warnings.empty?
|
121
141
|
quit Brakeman::Warnings_Found_Exit_Code
|
@@ -124,6 +144,10 @@ module Brakeman
|
|
124
144
|
if tracker.options[:exit_on_error] and tracker.errors.any?
|
125
145
|
quit Brakeman::Errors_Found_Exit_Code
|
126
146
|
end
|
147
|
+
|
148
|
+
if ensure_ignore_notes_failed
|
149
|
+
quit Brakeman::Empty_Ignore_Note_Exit_Code
|
150
|
+
end
|
127
151
|
end
|
128
152
|
|
129
153
|
# Actually run Brakeman.
|