brakeman 4.10.1 → 5.0.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 +25 -0
- data/README.md +1 -1
- data/bundle/load.rb +2 -2
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/History.rdoc +6 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/Manifest.txt +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/README.rdoc +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/compare/normalize.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/debugging.md +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/lib/rp_extensions.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/lib/rp_stringscanner.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/lib/ruby20_parser.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/lib/ruby20_parser.y +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/lib/ruby21_parser.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/lib/ruby21_parser.y +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/lib/ruby22_parser.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/lib/ruby22_parser.y +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/lib/ruby23_parser.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/lib/ruby23_parser.y +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/lib/ruby24_parser.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/lib/ruby24_parser.y +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/lib/ruby25_parser.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/lib/ruby25_parser.y +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/lib/ruby26_parser.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/lib/ruby26_parser.y +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/lib/ruby27_parser.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/lib/ruby27_parser.y +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/lib/ruby_lexer.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/lib/ruby_lexer.rex +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/lib/ruby_lexer.rex.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/lib/ruby_parser.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/lib/ruby_parser.yy +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/lib/ruby_parser_extras.rb +1 -1
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/tools/munge.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{ruby_parser-3.15.0 → ruby_parser-3.15.1}/tools/ripper.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.1 → sexp_processor-4.15.2}/History.rdoc +6 -0
- data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.1 → sexp_processor-4.15.2}/Manifest.txt +0 -0
- data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.1 → sexp_processor-4.15.2}/README.rdoc +0 -0
- data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.1 → sexp_processor-4.15.2}/lib/composite_sexp_processor.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.1 → sexp_processor-4.15.2}/lib/pt_testcase.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.1 → sexp_processor-4.15.2}/lib/sexp.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.1 → sexp_processor-4.15.2}/lib/sexp_matcher.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.1 → sexp_processor-4.15.2}/lib/sexp_processor.rb +1 -1
- data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.1 → sexp_processor-4.15.2}/lib/strict_sexp.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.1 → sexp_processor-4.15.2}/lib/unique.rb +0 -0
- data/lib/brakeman.rb +6 -0
- data/lib/brakeman/app_tree.rb +36 -3
- data/lib/brakeman/checks/base_check.rb +7 -1
- data/lib/brakeman/checks/check_execute.rb +1 -0
- data/lib/brakeman/checks/check_sql.rb +1 -1
- data/lib/brakeman/checks/check_unsafe_reflection_methods.rb +68 -0
- data/lib/brakeman/checks/check_verb_confusion.rb +75 -0
- data/lib/brakeman/file_parser.rb +19 -18
- data/lib/brakeman/options.rb +5 -1
- data/lib/brakeman/parsers/template_parser.rb +2 -3
- data/lib/brakeman/processors/alias_processor.rb +18 -2
- data/lib/brakeman/processors/lib/file_type_detector.rb +64 -0
- data/lib/brakeman/processors/lib/rails3_config_processor.rb +16 -16
- data/lib/brakeman/report.rb +8 -0
- data/lib/brakeman/report/report_base.rb +0 -2
- data/lib/brakeman/report/report_csv.rb +37 -60
- data/lib/brakeman/report/report_junit.rb +2 -2
- data/lib/brakeman/report/report_sarif.rb +1 -1
- data/lib/brakeman/report/report_sonar.rb +38 -0
- data/lib/brakeman/report/report_tabs.rb +1 -1
- data/lib/brakeman/report/report_text.rb +1 -1
- data/lib/brakeman/rescanner.rb +7 -5
- data/lib/brakeman/scanner.rb +44 -18
- data/lib/brakeman/tracker.rb +6 -0
- data/lib/brakeman/tracker/config.rb +73 -0
- data/lib/brakeman/util.rb +7 -2
- data/lib/brakeman/version.rb +1 -1
- data/lib/brakeman/warning.rb +10 -2
- data/lib/brakeman/warning_codes.rb +2 -0
- metadata +48 -44
data/lib/brakeman/file_parser.rb
CHANGED
@@ -3,32 +3,31 @@ module Brakeman
|
|
3
3
|
|
4
4
|
# This class handles reading and parsing files.
|
5
5
|
class FileParser
|
6
|
-
attr_reader :file_list
|
6
|
+
attr_reader :file_list, :errors
|
7
7
|
|
8
|
-
def initialize
|
9
|
-
@
|
10
|
-
@timeout =
|
11
|
-
@
|
12
|
-
@
|
8
|
+
def initialize app_tree, timeout
|
9
|
+
@app_tree = app_tree
|
10
|
+
@timeout = timeout
|
11
|
+
@file_list = []
|
12
|
+
@errors = []
|
13
13
|
end
|
14
14
|
|
15
|
-
def parse_files list
|
16
|
-
read_files list
|
15
|
+
def parse_files list
|
16
|
+
read_files list do |path, contents|
|
17
17
|
if ast = parse_ruby(contents, path.relative)
|
18
18
|
ASTFile.new(path, ast)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
def read_files list
|
24
|
-
@file_list[type] ||= []
|
25
|
-
|
23
|
+
def read_files list
|
26
24
|
list.each do |path|
|
27
25
|
file = @app_tree.file_path(path)
|
28
26
|
|
29
27
|
result = yield file, file.read
|
28
|
+
|
30
29
|
if result
|
31
|
-
@file_list
|
30
|
+
@file_list << result
|
32
31
|
end
|
33
32
|
end
|
34
33
|
end
|
@@ -43,15 +42,17 @@ module Brakeman
|
|
43
42
|
Brakeman.debug "Parsing #{path}"
|
44
43
|
RubyParser.new.parse input, path, @timeout
|
45
44
|
rescue Racc::ParseError => e
|
46
|
-
|
47
|
-
nil
|
45
|
+
error e.exception(e.message + "\nCould not parse #{path}")
|
48
46
|
rescue Timeout::Error => e
|
49
|
-
|
50
|
-
nil
|
47
|
+
error Exception.new("Parsing #{path} took too long (> #{@timeout} seconds). Try increasing the limit with --parser-timeout")
|
51
48
|
rescue => e
|
52
|
-
|
53
|
-
nil
|
49
|
+
error e.exception(e.message + "\nWhile processing #{path}")
|
54
50
|
end
|
55
51
|
end
|
52
|
+
|
53
|
+
def error exception
|
54
|
+
@errors << exception
|
55
|
+
nil
|
56
|
+
end
|
56
57
|
end
|
57
58
|
end
|
data/lib/brakeman/options.rb
CHANGED
@@ -166,6 +166,10 @@ module Brakeman::Options
|
|
166
166
|
options[:only_files].merge files
|
167
167
|
end
|
168
168
|
|
169
|
+
opts.on "--[no-]skip-vendor", "Skip processing vendor directory (Default)" do |skip|
|
170
|
+
options[:skip_vendor] = skip
|
171
|
+
end
|
172
|
+
|
169
173
|
opts.on "--skip-libs", "Skip processing lib directory" do
|
170
174
|
options[:skip_libs] = true
|
171
175
|
end
|
@@ -229,7 +233,7 @@ module Brakeman::Options
|
|
229
233
|
|
230
234
|
opts.on "-f",
|
231
235
|
"--format TYPE",
|
232
|
-
[:pdf, :text, :html, :csv, :tabs, :json, :markdown, :codeclimate, :cc, :plain, :table, :junit, :sarif],
|
236
|
+
[:pdf, :text, :html, :csv, :tabs, :json, :markdown, :codeclimate, :cc, :plain, :table, :junit, :sarif, :sonar],
|
233
237
|
"Specify output formats. Default is text" do |type|
|
234
238
|
|
235
239
|
type = "s" if type == :text
|
@@ -9,7 +9,6 @@ module Brakeman
|
|
9
9
|
def initialize tracker, file_parser
|
10
10
|
@tracker = tracker
|
11
11
|
@file_parser = file_parser
|
12
|
-
@file_parser.file_list[:templates] ||= []
|
13
12
|
end
|
14
13
|
|
15
14
|
def parse_template path, text
|
@@ -33,7 +32,7 @@ module Brakeman
|
|
33
32
|
end
|
34
33
|
|
35
34
|
if src and ast = @file_parser.parse_ruby(src, path)
|
36
|
-
@file_parser.file_list
|
35
|
+
@file_parser.file_list << TemplateFile.new(path, ast, name, type)
|
37
36
|
end
|
38
37
|
rescue Racc::ParseError => e
|
39
38
|
tracker.error e, "Could not parse #{path}"
|
@@ -97,7 +96,7 @@ module Brakeman
|
|
97
96
|
end
|
98
97
|
|
99
98
|
def self.parse_inline_erb tracker, text
|
100
|
-
fp = Brakeman::FileParser.new(tracker)
|
99
|
+
fp = Brakeman::FileParser.new(tracker.app_tree, tracker.options[:parser_timeout])
|
101
100
|
tp = self.new(tracker, fp)
|
102
101
|
src = tp.parse_erb '_inline_', text
|
103
102
|
type = tp.erubis? ? :erubis : :erb
|
@@ -161,6 +161,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
161
161
|
ARRAY_CONST = s(:const, :Array)
|
162
162
|
HASH_CONST = s(:const, :Hash)
|
163
163
|
RAILS_TEST = s(:call, s(:call, s(:const, :Rails), :env), :test?)
|
164
|
+
RAILS_DEV = s(:call, s(:call, s(:const, :Rails), :env), :development?)
|
164
165
|
|
165
166
|
#Process a method call.
|
166
167
|
def process_call exp
|
@@ -186,7 +187,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
186
187
|
method = exp.method
|
187
188
|
first_arg = exp.first_arg
|
188
189
|
|
189
|
-
if method == :send or method == :try
|
190
|
+
if method == :send or method == :__send__ or method == :try
|
190
191
|
collapse_send_call exp, first_arg
|
191
192
|
end
|
192
193
|
|
@@ -197,7 +198,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
197
198
|
return Sexp.new(:array, *exp.args)
|
198
199
|
elsif target == HASH_CONST and method == :new and first_arg.nil? and !node_type?(@exp_context.last, :iter)
|
199
200
|
return Sexp.new(:hash)
|
200
|
-
elsif exp == RAILS_TEST
|
201
|
+
elsif exp == RAILS_TEST or exp == RAILS_DEV
|
201
202
|
return Sexp.new(:false)
|
202
203
|
end
|
203
204
|
|
@@ -346,6 +347,18 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
346
347
|
end
|
347
348
|
end
|
348
349
|
|
350
|
+
TEMP_FILE_CLASS = s(:const, :Tempfile)
|
351
|
+
|
352
|
+
def temp_file_open? exp
|
353
|
+
call? exp and
|
354
|
+
exp.target == TEMP_FILE_CLASS and
|
355
|
+
exp.method == :open
|
356
|
+
end
|
357
|
+
|
358
|
+
def temp_file_new line
|
359
|
+
s(:call, TEMP_FILE_CLASS, :new).line(line)
|
360
|
+
end
|
361
|
+
|
349
362
|
def process_iter exp
|
350
363
|
@exp_context.push exp
|
351
364
|
exp[1] = process exp.block_call
|
@@ -363,6 +376,9 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
363
376
|
# Iterating over an array of all literal values
|
364
377
|
local = Sexp.new(:lvar, block_args.last)
|
365
378
|
env.current[local] = safe_literal(exp.line)
|
379
|
+
elsif temp_file_open? call
|
380
|
+
local = Sexp.new(:lvar, block_args.last)
|
381
|
+
env.current[local] = temp_file_new(exp.line)
|
366
382
|
else
|
367
383
|
block_args.each do |e|
|
368
384
|
#Force block arg(s) to be local
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Brakeman
|
2
|
+
class FileTypeDetector < BaseProcessor
|
3
|
+
def initialize
|
4
|
+
super(nil)
|
5
|
+
reset
|
6
|
+
end
|
7
|
+
|
8
|
+
def detect_type(file)
|
9
|
+
reset
|
10
|
+
process(file.ast)
|
11
|
+
|
12
|
+
if @file_type.nil?
|
13
|
+
@file_type = guess_from_path(file.path.relative)
|
14
|
+
end
|
15
|
+
|
16
|
+
@file_type || :libs
|
17
|
+
end
|
18
|
+
|
19
|
+
MODEL_CLASSES = [
|
20
|
+
:'ActiveRecord::Base',
|
21
|
+
:ApplicationRecord
|
22
|
+
]
|
23
|
+
|
24
|
+
def process_class exp
|
25
|
+
name = class_name(exp.class_name)
|
26
|
+
parent = class_name(exp.parent_name)
|
27
|
+
|
28
|
+
if name.match(/Controller$/)
|
29
|
+
@file_type = :controllers
|
30
|
+
return exp
|
31
|
+
elsif MODEL_CLASSES.include? parent
|
32
|
+
@file_type = :models
|
33
|
+
return exp
|
34
|
+
end
|
35
|
+
|
36
|
+
super
|
37
|
+
end
|
38
|
+
|
39
|
+
def guess_from_path path
|
40
|
+
case
|
41
|
+
when path.include?('app/models')
|
42
|
+
:models
|
43
|
+
when path.include?('app/controllers')
|
44
|
+
:controllers
|
45
|
+
when path.include?('config/initializers')
|
46
|
+
:initializers
|
47
|
+
when path.include?('lib/')
|
48
|
+
:libs
|
49
|
+
when path.match?(%r{config/environments/(?!production\.rb)$})
|
50
|
+
:skip
|
51
|
+
when path.match?(%r{environments/production\.rb$})
|
52
|
+
:skip
|
53
|
+
when path.match?(%r{application\.rb$})
|
54
|
+
:skip
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def reset
|
61
|
+
@file_type = nil
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -57,6 +57,20 @@ class Brakeman::Rails3ConfigProcessor < Brakeman::BasicProcessor
|
|
57
57
|
exp
|
58
58
|
end
|
59
59
|
|
60
|
+
#Look for configuration settings that
|
61
|
+
#are just a call like
|
62
|
+
#
|
63
|
+
# config.load_defaults 5.2
|
64
|
+
def process_call exp
|
65
|
+
return exp unless @inside_config
|
66
|
+
|
67
|
+
if exp.target == RAILS_CONFIG and exp.first_arg
|
68
|
+
@tracker.config.rails[exp.method] = exp.first_arg
|
69
|
+
end
|
70
|
+
|
71
|
+
exp
|
72
|
+
end
|
73
|
+
|
60
74
|
#Look for configuration settings
|
61
75
|
def process_attrasgn exp
|
62
76
|
return exp unless @inside_config
|
@@ -71,22 +85,8 @@ class Brakeman::Rails3ConfigProcessor < Brakeman::BasicProcessor
|
|
71
85
|
@tracker.config.rails[attribute] = exp.first_arg
|
72
86
|
end
|
73
87
|
elsif include_rails_config? exp
|
74
|
-
|
75
|
-
|
76
|
-
options[0..-2].each do |o|
|
77
|
-
level[o] ||= {}
|
78
|
-
|
79
|
-
option = level[o]
|
80
|
-
|
81
|
-
if not option.is_a? Hash
|
82
|
-
Brakeman.debug "[Notice] Skipping config setting: #{options.map(&:to_s).join(".")}"
|
83
|
-
return exp
|
84
|
-
end
|
85
|
-
|
86
|
-
level = level[o]
|
87
|
-
end
|
88
|
-
|
89
|
-
level[options.last] = exp.first_arg
|
88
|
+
options_path = get_rails_config exp
|
89
|
+
@tracker.config.set_rails_config(exp.first_arg, *options_path)
|
90
90
|
end
|
91
91
|
|
92
92
|
exp
|
data/lib/brakeman/report.rb
CHANGED
@@ -45,6 +45,9 @@ class Brakeman::Report
|
|
45
45
|
Brakeman::Report::JUnit
|
46
46
|
when :to_sarif
|
47
47
|
return self.to_sarif
|
48
|
+
when :to_sonar
|
49
|
+
require_report 'sonar'
|
50
|
+
Brakeman::Report::Sonar
|
48
51
|
else
|
49
52
|
raise "Invalid format: #{format}. Should be one of #{VALID_FORMATS.inspect}"
|
50
53
|
end
|
@@ -69,6 +72,11 @@ class Brakeman::Report
|
|
69
72
|
generate Brakeman::Report::JSON
|
70
73
|
end
|
71
74
|
|
75
|
+
def to_sonar
|
76
|
+
require_report 'sonar'
|
77
|
+
generate Brakeman::Report::Sonar
|
78
|
+
end
|
79
|
+
|
72
80
|
def to_table
|
73
81
|
require_report 'table'
|
74
82
|
generate Brakeman::Report::Table
|
@@ -1,72 +1,49 @@
|
|
1
1
|
require 'csv'
|
2
|
-
require "brakeman/report/report_table"
|
3
2
|
|
4
|
-
class Brakeman::Report::CSV < Brakeman::Report::
|
3
|
+
class Brakeman::Report::CSV < Brakeman::Report::Base
|
5
4
|
def generate_report
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
output << "TEMPLATES\n\n"
|
25
|
-
output << table_to_csv(generate_templates) << "\n"
|
5
|
+
headers = [
|
6
|
+
"Confidence",
|
7
|
+
"Warning Type",
|
8
|
+
"File",
|
9
|
+
"Line",
|
10
|
+
"Message",
|
11
|
+
"Code",
|
12
|
+
"User Input",
|
13
|
+
"Check Name",
|
14
|
+
"Warning Code",
|
15
|
+
"Fingerprint",
|
16
|
+
"Link"
|
17
|
+
]
|
18
|
+
|
19
|
+
rows = tracker.filtered_warnings.sort_by do |w|
|
20
|
+
[w.confidence, w.warning_type, w.file, w.line, w.fingerprint]
|
21
|
+
end.map do |warning|
|
22
|
+
generate_row(headers, warning)
|
26
23
|
end
|
27
24
|
|
28
|
-
|
29
|
-
output << "ERRORS\n" << table_to_csv(res) << "\n" if res
|
30
|
-
|
31
|
-
res = generate_warnings
|
32
|
-
output << "SECURITY WARNINGS\n" << table_to_csv(res) << "\n" if res
|
25
|
+
table = CSV::Table.new(rows)
|
33
26
|
|
34
|
-
|
35
|
-
res = generate_controller_warnings
|
36
|
-
output << table_to_csv(res) << "\n" if res
|
37
|
-
|
38
|
-
output << "Model Warnings\n"
|
39
|
-
res = generate_model_warnings
|
40
|
-
output << table_to_csv(res) << "\n" if res
|
41
|
-
|
42
|
-
res = generate_template_warnings
|
43
|
-
output << "Template Warnings\n"
|
44
|
-
output << table_to_csv(res) << "\n" if res
|
45
|
-
|
46
|
-
output
|
27
|
+
table.to_csv
|
47
28
|
end
|
48
29
|
|
49
|
-
|
50
|
-
|
51
|
-
header = CSV.generate_line(["Application Path", "Report Generation Time", "Checks Performed", "Rails Version"])
|
52
|
-
header << CSV.generate_line([File.expand_path(tracker.app_path), Time.now.to_s, checks.checks_run.sort.join(", "), rails_version])
|
53
|
-
"BRAKEMAN REPORT\n\n" + header
|
30
|
+
def generate_row headers, warning
|
31
|
+
CSV::Row.new headers, warning_row(warning)
|
54
32
|
end
|
55
33
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
output
|
34
|
+
def warning_row warning
|
35
|
+
[
|
36
|
+
warning.confidence_name,
|
37
|
+
warning.warning_type,
|
38
|
+
warning_file(warning),
|
39
|
+
warning.line,
|
40
|
+
warning.message,
|
41
|
+
warning.code && warning.format_code(false),
|
42
|
+
warning.user_input && warning.format_user_input(false),
|
43
|
+
warning.check_name,
|
44
|
+
warning.warning_code,
|
45
|
+
warning.fingerprint,
|
46
|
+
warning.link,
|
47
|
+
]
|
71
48
|
end
|
72
49
|
end
|
@@ -47,7 +47,7 @@ class Brakeman::Report::JUnit < Brakeman::Report::Base
|
|
47
47
|
warning.add_attribute 'brakeman:file', warning_file(w)
|
48
48
|
warning.add_attribute 'brakeman:line', w.line
|
49
49
|
warning.add_attribute 'brakeman:fingerprint', w.fingerprint
|
50
|
-
warning.add_attribute 'brakeman:confidence',
|
50
|
+
warning.add_attribute 'brakeman:confidence', w.confidence_name
|
51
51
|
warning.add_attribute 'brakeman:code', w.format_code
|
52
52
|
warning.add_text w.to_s
|
53
53
|
}
|
@@ -88,7 +88,7 @@ class Brakeman::Report::JUnit < Brakeman::Report::Base
|
|
88
88
|
failure.add_attribute 'brakeman:fingerprint', warning.fingerprint
|
89
89
|
failure.add_attribute 'brakeman:file', warning_file(warning)
|
90
90
|
failure.add_attribute 'brakeman:line', warning.line
|
91
|
-
failure.add_attribute 'brakeman:confidence',
|
91
|
+
failure.add_attribute 'brakeman:confidence', warning.confidence_name
|
92
92
|
failure.add_attribute 'brakeman:code', warning.format_code
|
93
93
|
failure.add_text warning.to_s
|
94
94
|
}
|
@@ -27,7 +27,7 @@ class Brakeman::Report::SARIF < Brakeman::Report::Base
|
|
27
27
|
def rules
|
28
28
|
@rules ||= unique_warnings_by_warning_code.map do |warning|
|
29
29
|
rule_id = render_id warning
|
30
|
-
check_name = warning.
|
30
|
+
check_name = warning.check_name
|
31
31
|
check_description = render_message check_descriptions[check_name]
|
32
32
|
{
|
33
33
|
:id => rule_id,
|