brakeman-lib 4.7.2 → 4.8.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 +12 -0
- data/lib/brakeman.rb +4 -0
- data/lib/brakeman/checks/base_check.rb +12 -9
- data/lib/brakeman/checks/check_content_tag.rb +1 -2
- data/lib/brakeman/checks/check_execute.rb +40 -5
- data/lib/brakeman/checks/check_link_to.rb +1 -1
- data/lib/brakeman/checks/check_link_to_href.rb +1 -3
- data/lib/brakeman/checks/check_sql.rb +0 -11
- data/lib/brakeman/differ.rb +0 -5
- data/lib/brakeman/options.rb +1 -1
- data/lib/brakeman/processors/lib/find_all_calls.rb +3 -2
- data/lib/brakeman/report.rb +4 -1
- data/lib/brakeman/report/ignore/config.rb +6 -2
- data/lib/brakeman/report/report_junit.rb +104 -0
- data/lib/brakeman/report/report_markdown.rb +0 -1
- data/lib/brakeman/tracker/config.rb +1 -0
- data/lib/brakeman/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 34099e8abef9a4c7108905ea8d956d01afbb6037cab597d2ad0beab8790a9060
|
4
|
+
data.tar.gz: 982be6bfad0eef60f17627001fef1873bad5a23eef76f687ea434d23773ba9b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce68529ca660b85d86b9569b4f8ddfe41c4b7b3bc724d1afc9860f91fa0a945eb473bbd5bb83b4c9d8e61ac6255ab0b11a42878921671a03a0964d2440912178
|
7
|
+
data.tar.gz: 1fbd104e129d5fce136d4c4984296a7daa6c88ffd8f22edbb576613cb6519547676f38364a2f728dcc2c9a322119d0024ae845baf7383ecf38b43038e9e129c6
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
# Unreleased
|
2
|
+
|
3
|
+
* Add JUnit-XML report format (Naoki Kimura)
|
4
|
+
* Sort ignore files by fingerprint and line (Ngan Pham)
|
5
|
+
* Freeze call index results
|
6
|
+
* Fix output test when using newer Minitest
|
7
|
+
* Properly render confidence in Markdown report
|
8
|
+
* Report old warnings as fixed if zero warnings reported
|
9
|
+
* Catch dangerous concatenation in `CheckExecute` (Jacob Evelyn)
|
10
|
+
* Show user-friendly message when ignore config file has invalid JSON (D. Hicks)
|
11
|
+
* Initialize Rails version with `nil` (Carsten Wirth)
|
12
|
+
|
1
13
|
# 4.7.2 - 2019-11-25
|
2
14
|
|
3
15
|
* Remove version guard for `named_scope` vs. `scope`
|
data/lib/brakeman.rb
CHANGED
@@ -231,6 +231,8 @@ module Brakeman
|
|
231
231
|
[:to_text]
|
232
232
|
when :table, :to_table
|
233
233
|
[:to_table]
|
234
|
+
when :junit, :to_junit
|
235
|
+
[:to_junit]
|
234
236
|
else
|
235
237
|
[:to_text]
|
236
238
|
end
|
@@ -258,6 +260,8 @@ module Brakeman
|
|
258
260
|
:to_text
|
259
261
|
when /\.table$/i
|
260
262
|
:to_table
|
263
|
+
when /\.junit$/i
|
264
|
+
:to_junit
|
261
265
|
else
|
262
266
|
:to_text
|
263
267
|
end
|
@@ -280,15 +280,6 @@ class Brakeman::BaseCheck < Brakeman::SexpProcessor
|
|
280
280
|
return location, line
|
281
281
|
end
|
282
282
|
|
283
|
-
#Checks if an expression contains string interpolation.
|
284
|
-
#
|
285
|
-
#Returns Match with :interp type if found.
|
286
|
-
def include_interp? exp
|
287
|
-
@string_interp = false
|
288
|
-
process exp
|
289
|
-
@string_interp
|
290
|
-
end
|
291
|
-
|
292
283
|
#Checks if _exp_ includes user input in the form of cookies, parameters,
|
293
284
|
#request environment, or model attributes.
|
294
285
|
#
|
@@ -504,4 +495,16 @@ class Brakeman::BaseCheck < Brakeman::SexpProcessor
|
|
504
495
|
|
505
496
|
@active_record_models
|
506
497
|
end
|
498
|
+
|
499
|
+
STRING_METHODS = Set[:<<, :+, :concat, :prepend]
|
500
|
+
private_constant :STRING_METHODS
|
501
|
+
|
502
|
+
def string_building? exp
|
503
|
+
return false unless call? exp and STRING_METHODS.include? exp.method
|
504
|
+
|
505
|
+
node_type? exp.target, :str, :dstr or
|
506
|
+
node_type? exp.first_arg, :str, :dstr or
|
507
|
+
string_building? exp.target or
|
508
|
+
string_building? exp.first_arg
|
509
|
+
end
|
507
510
|
end
|
@@ -56,8 +56,20 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
|
|
56
56
|
|
57
57
|
case call.method
|
58
58
|
when :popen
|
59
|
-
|
60
|
-
|
59
|
+
# Normally, if we're in a `popen` call, we only are worried about shell
|
60
|
+
# injection when the argument is not an array, because array elements
|
61
|
+
# are always escaped by Ruby. However, an exception is when the array
|
62
|
+
# contains two values are something like "bash -c" because then the third
|
63
|
+
# element is effectively the command being run and might be a malicious
|
64
|
+
# executable if it comes (partially or fully) from user input.
|
65
|
+
if !array?(first_arg)
|
66
|
+
failure = include_user_input?(first_arg) ||
|
67
|
+
dangerous_interp?(first_arg) ||
|
68
|
+
dangerous_string_building?(first_arg)
|
69
|
+
elsif dash_c_shell_command?(first_arg[1], first_arg[2])
|
70
|
+
failure = include_user_input?(first_arg[3]) ||
|
71
|
+
dangerous_interp?(first_arg[3]) ||
|
72
|
+
dangerous_string_building?(first_arg[3])
|
61
73
|
end
|
62
74
|
when :system, :exec
|
63
75
|
# Normally, if we're in a `system` or `exec` call, we only are worried
|
@@ -67,12 +79,18 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
|
|
67
79
|
# the third argument is effectively the command being run and might be
|
68
80
|
# a malicious executable if it comes (partially or fully) from user input.
|
69
81
|
if dash_c_shell_command?(first_arg, call.second_arg)
|
70
|
-
failure = include_user_input?(args[3]) ||
|
82
|
+
failure = include_user_input?(args[3]) ||
|
83
|
+
dangerous_interp?(args[3]) ||
|
84
|
+
dangerous_string_building?(args[3])
|
71
85
|
else
|
72
|
-
failure = include_user_input?(first_arg) ||
|
86
|
+
failure = include_user_input?(first_arg) ||
|
87
|
+
dangerous_interp?(first_arg) ||
|
88
|
+
dangerous_string_building?(first_arg)
|
73
89
|
end
|
74
90
|
else
|
75
|
-
failure = include_user_input?(args) ||
|
91
|
+
failure = include_user_input?(args) ||
|
92
|
+
dangerous_interp?(args) ||
|
93
|
+
dangerous_string_building?(args)
|
76
94
|
end
|
77
95
|
|
78
96
|
if failure and original? result
|
@@ -219,6 +237,23 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
|
|
219
237
|
false
|
220
238
|
end
|
221
239
|
|
240
|
+
#Checks if an expression contains string interpolation.
|
241
|
+
#
|
242
|
+
#Returns Match with :interp type if found.
|
243
|
+
def include_interp? exp
|
244
|
+
@string_interp = false
|
245
|
+
process exp
|
246
|
+
@string_interp
|
247
|
+
end
|
248
|
+
|
249
|
+
def dangerous_string_building? exp
|
250
|
+
if string_building?(exp) && res = dangerous?(exp)
|
251
|
+
return Match.new(:interp, res)
|
252
|
+
end
|
253
|
+
|
254
|
+
false
|
255
|
+
end
|
256
|
+
|
222
257
|
def shell_escape? exp
|
223
258
|
return false unless call? exp
|
224
259
|
|
@@ -34,7 +34,7 @@ class Brakeman::CheckLinkTo < Brakeman::CheckCrossSiteScripting
|
|
34
34
|
|
35
35
|
#Have to make a copy of this, otherwise it will be changed to
|
36
36
|
#an ignored method call by the code above.
|
37
|
-
call = result[:call]
|
37
|
+
call = result[:call]
|
38
38
|
|
39
39
|
first_arg = call.first_arg
|
40
40
|
second_arg = call.second_arg
|
@@ -30,9 +30,7 @@ class Brakeman::CheckLinkToHref < Brakeman::CheckLinkTo
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def process_result result
|
33
|
-
|
34
|
-
#an ignored method call by the code above.
|
35
|
-
call = result[:call] = result[:call].dup
|
33
|
+
call = result[:call]
|
36
34
|
@matched = false
|
37
35
|
|
38
36
|
url_arg = if result[:block]
|
@@ -525,8 +525,6 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
525
525
|
false
|
526
526
|
end
|
527
527
|
|
528
|
-
STRING_METHODS = Set[:<<, :+, :concat, :prepend]
|
529
|
-
|
530
528
|
def check_for_string_building exp
|
531
529
|
return unless call? exp
|
532
530
|
|
@@ -573,15 +571,6 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
573
571
|
end
|
574
572
|
end
|
575
573
|
|
576
|
-
def string_building? exp
|
577
|
-
return false unless call? exp and STRING_METHODS.include? exp.method
|
578
|
-
|
579
|
-
node_type? exp.target, :str, :dstr or
|
580
|
-
node_type? exp.first_arg, :str, :dstr or
|
581
|
-
string_building? exp.target or
|
582
|
-
string_building? exp.first_arg
|
583
|
-
end
|
584
|
-
|
585
574
|
IGNORE_METHODS_IN_SQL = Set[:id, :merge_conditions, :table_name, :quoted_table_name,
|
586
575
|
:quoted_primary_key, :to_i, :to_f, :sanitize_sql, :sanitize_sql_array,
|
587
576
|
:sanitize_sql_for_assignment, :sanitize_sql_for_conditions, :sanitize_sql_hash,
|
data/lib/brakeman/differ.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
# extracting the diff logic to it's own class for consistency. Currently handles
|
2
2
|
# an array of Brakeman::Warnings or plain hash representations.
|
3
3
|
class Brakeman::Differ
|
4
|
-
DEFAULT_HASH = {:new => [], :fixed => []}
|
5
|
-
OLD_WARNING_KEYS = [:warning_type, :location, :code, :message, :file, :link, :confidence, :user_input]
|
6
4
|
attr_reader :old_warnings, :new_warnings
|
7
5
|
|
8
6
|
def initialize new_warnings, old_warnings
|
@@ -11,9 +9,6 @@ class Brakeman::Differ
|
|
11
9
|
end
|
12
10
|
|
13
11
|
def diff
|
14
|
-
# get the type of elements
|
15
|
-
return DEFAULT_HASH if @new_warnings.empty?
|
16
|
-
|
17
12
|
warnings = {}
|
18
13
|
warnings[:new] = @new_warnings - @old_warnings
|
19
14
|
warnings[:fixed] = @old_warnings - @new_warnings
|
data/lib/brakeman/options.rb
CHANGED
@@ -225,7 +225,7 @@ module Brakeman::Options
|
|
225
225
|
|
226
226
|
opts.on "-f",
|
227
227
|
"--format TYPE",
|
228
|
-
[:pdf, :text, :html, :csv, :tabs, :json, :markdown, :codeclimate, :cc, :plain, :table],
|
228
|
+
[:pdf, :text, :html, :csv, :tabs, :json, :markdown, :codeclimate, :cc, :plain, :table, :junit],
|
229
229
|
"Specify output formats. Default is text" do |type|
|
230
230
|
|
231
231
|
type = "s" if type == :text
|
@@ -60,7 +60,7 @@ class Brakeman::FindAllCalls < Brakeman::BasicProcessor
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def process_call exp
|
63
|
-
@calls << create_call_hash(exp)
|
63
|
+
@calls << create_call_hash(exp).freeze
|
64
64
|
exp
|
65
65
|
end
|
66
66
|
|
@@ -72,6 +72,7 @@ class Brakeman::FindAllCalls < Brakeman::BasicProcessor
|
|
72
72
|
|
73
73
|
call_hash[:block] = exp.block
|
74
74
|
call_hash[:block_args] = exp.block_args
|
75
|
+
call_hash.freeze
|
75
76
|
|
76
77
|
@calls << call_hash
|
77
78
|
|
@@ -136,7 +137,7 @@ class Brakeman::FindAllCalls < Brakeman::BasicProcessor
|
|
136
137
|
:call => exp,
|
137
138
|
:nested => false,
|
138
139
|
:location => make_location,
|
139
|
-
:parent => @current_call }
|
140
|
+
:parent => @current_call }.freeze
|
140
141
|
end
|
141
142
|
|
142
143
|
#Gets the target of a call as a Symbol
|
data/lib/brakeman/report.rb
CHANGED
@@ -6,7 +6,7 @@ require 'brakeman/report/report_base'
|
|
6
6
|
class Brakeman::Report
|
7
7
|
attr_reader :tracker
|
8
8
|
|
9
|
-
VALID_FORMATS = [:to_html, :to_pdf, :to_csv, :to_json, :to_tabs, :to_hash, :to_s, :to_markdown, :to_codeclimate, :to_plain, :to_text]
|
9
|
+
VALID_FORMATS = [:to_html, :to_pdf, :to_csv, :to_json, :to_tabs, :to_hash, :to_s, :to_markdown, :to_codeclimate, :to_plain, :to_text, :to_junit]
|
10
10
|
|
11
11
|
def initialize tracker
|
12
12
|
@app_tree = tracker.app_tree
|
@@ -40,6 +40,9 @@ class Brakeman::Report
|
|
40
40
|
return self.to_table
|
41
41
|
when :to_pdf
|
42
42
|
raise "PDF output is not yet supported."
|
43
|
+
when :to_junit
|
44
|
+
require_report 'junit'
|
45
|
+
Brakeman::Report::JUnit
|
43
46
|
else
|
44
47
|
raise "Invalid format: #{format}. Should be one of #{VALID_FORMATS.inspect}"
|
45
48
|
end
|
@@ -97,7 +97,11 @@ module Brakeman
|
|
97
97
|
# Read configuration to file
|
98
98
|
def read_from_file file = @file
|
99
99
|
if File.exist? file
|
100
|
-
|
100
|
+
begin
|
101
|
+
@already_ignored = JSON.parse(File.read(file), :symbolize_names => true)[:ignored_warnings]
|
102
|
+
rescue => e
|
103
|
+
raise e, "\nError[#{e.class}] while reading brakeman ignore file: #{file}\n"
|
104
|
+
end
|
101
105
|
else
|
102
106
|
Brakeman.notify "[Notice] Could not find ignore configuration in #{file}"
|
103
107
|
@already_ignored = []
|
@@ -118,7 +122,7 @@ module Brakeman
|
|
118
122
|
|
119
123
|
w[:note] = @notes[w[:fingerprint]] || ""
|
120
124
|
w
|
121
|
-
end.sort_by { |w| w[:fingerprint] }
|
125
|
+
end.sort_by { |w| [w[:fingerprint], w[:line]] }
|
122
126
|
|
123
127
|
output = {
|
124
128
|
:ignored_warnings => warnings,
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'time'
|
2
|
+
require "stringio"
|
3
|
+
require 'rexml/document'
|
4
|
+
|
5
|
+
class Brakeman::Report::JUnit < Brakeman::Report::Base
|
6
|
+
def generate_report
|
7
|
+
io = StringIO.new
|
8
|
+
doc = REXML::Document.new
|
9
|
+
doc.add REXML::XMLDecl.new '1.0', 'UTF-8'
|
10
|
+
|
11
|
+
test_suites = REXML::Element.new 'testsuites'
|
12
|
+
test_suites.add_attribute 'xmlns:brakeman', 'https://brakemanscanner.org/'
|
13
|
+
properties = test_suites.add_element 'brakeman:properties', { 'xml:id' => 'scan_info' }
|
14
|
+
properties.add_element 'brakeman:property', { 'brakeman:name' => 'app_path', 'brakeman:value' => tracker.app_path }
|
15
|
+
properties.add_element 'brakeman:property', { 'brakeman:name' => 'rails_version', 'brakeman:value' => rails_version }
|
16
|
+
properties.add_element 'brakeman:property', { 'brakeman:name' => 'security_warnings', 'brakeman:value' => all_warnings.length }
|
17
|
+
properties.add_element 'brakeman:property', { 'brakeman:name' => 'start_time', 'brakeman:value' => tracker.start_time.iso8601 }
|
18
|
+
properties.add_element 'brakeman:property', { 'brakeman:name' => 'end_time', 'brakeman:value' => tracker.end_time.iso8601 }
|
19
|
+
properties.add_element 'brakeman:property', { 'brakeman:name' => 'duration', 'brakeman:value' => tracker.duration }
|
20
|
+
properties.add_element 'brakeman:property', { 'brakeman:name' => 'checks_performed', 'brakeman:value' => checks.checks_run.join(',') }
|
21
|
+
properties.add_element 'brakeman:property', { 'brakeman:name' => 'number_of_controllers', 'brakeman:value' => tracker.controllers.length }
|
22
|
+
properties.add_element 'brakeman:property', { 'brakeman:name' => 'number_of_models', 'brakeman:value' => tracker.models.length - 1 }
|
23
|
+
properties.add_element 'brakeman:property', { 'brakeman:name' => 'ruby_version', 'brakeman:value' => number_of_templates(@tracker) }
|
24
|
+
properties.add_element 'brakeman:property', { 'brakeman:name' => 'number_of_templates', 'brakeman:value' => RUBY_VERSION }
|
25
|
+
properties.add_element 'brakeman:property', { 'brakeman:name' => 'brakeman_version', 'brakeman:value' => Brakeman::Version }
|
26
|
+
|
27
|
+
errors = test_suites.add_element 'brakeman:errors'
|
28
|
+
tracker.errors.each { |e|
|
29
|
+
error = errors.add_element 'brakeman:error'
|
30
|
+
error.add_attribute 'brakeman:message', e[:error]
|
31
|
+
e[:backtrace].each { |b|
|
32
|
+
backtrace = error.add_element 'brakeman:backtrace'
|
33
|
+
backtrace.add_text b
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
obsolete = test_suites.add_element 'brakeman:obsolete'
|
38
|
+
tracker.unused_fingerprints.each { |fingerprint|
|
39
|
+
obsolete.add_element 'brakeman:warning', { 'brakeman:fingerprint' => fingerprint }
|
40
|
+
}
|
41
|
+
|
42
|
+
ignored = test_suites.add_element 'brakeman:ignored'
|
43
|
+
ignored_warnings.each { |w|
|
44
|
+
warning = ignored.add_element 'brakeman:warning'
|
45
|
+
warning.add_attribute 'brakeman:message', w.message
|
46
|
+
warning.add_attribute 'brakeman:category', w.warning_type
|
47
|
+
warning.add_attribute 'brakeman:file', warning_file(w)
|
48
|
+
warning.add_attribute 'brakeman:line', w.line
|
49
|
+
warning.add_attribute 'brakeman:fingerprint', w.fingerprint
|
50
|
+
warning.add_attribute 'brakeman:confidence', TEXT_CONFIDENCE[w.confidence]
|
51
|
+
warning.add_attribute 'brakeman:code', w.format_code
|
52
|
+
warning.add_text w.to_s
|
53
|
+
}
|
54
|
+
|
55
|
+
hostname = `hostname`.strip
|
56
|
+
i = 0
|
57
|
+
all_warnings
|
58
|
+
.map { |warning| [warning.file, [warning]] }
|
59
|
+
.reduce({}) { |entries, entry|
|
60
|
+
key, value = entry
|
61
|
+
entries[key] = entries[key] ? entries[key].concat(value) : value
|
62
|
+
entries
|
63
|
+
}
|
64
|
+
.each { |file, warnings|
|
65
|
+
i += 1
|
66
|
+
test_suite = test_suites.add_element 'testsuite'
|
67
|
+
test_suite.add_attribute 'id', i
|
68
|
+
test_suite.add_attribute 'package', 'brakeman'
|
69
|
+
test_suite.add_attribute 'name', file.relative
|
70
|
+
test_suite.add_attribute 'timestamp', tracker.start_time.strftime('%FT%T')
|
71
|
+
test_suite.add_attribute 'hostname', hostname == '' ? 'localhost' : hostname
|
72
|
+
test_suite.add_attribute 'tests', checks.checks_run.length
|
73
|
+
test_suite.add_attribute 'failures', warnings.length
|
74
|
+
test_suite.add_attribute 'errors', '0'
|
75
|
+
test_suite.add_attribute 'time', '0'
|
76
|
+
|
77
|
+
test_suite.add_element 'properties'
|
78
|
+
|
79
|
+
warnings.each { |warning|
|
80
|
+
test_case = test_suite.add_element 'testcase'
|
81
|
+
test_case.add_attribute 'name', 'run_check'
|
82
|
+
test_case.add_attribute 'classname', warning.check
|
83
|
+
test_case.add_attribute 'time', '0'
|
84
|
+
|
85
|
+
failure = test_case.add_element 'failure'
|
86
|
+
failure.add_attribute 'message', warning.message
|
87
|
+
failure.add_attribute 'type', warning.warning_type
|
88
|
+
failure.add_attribute 'brakeman:fingerprint', warning.fingerprint
|
89
|
+
failure.add_attribute 'brakeman:file', warning_file(warning)
|
90
|
+
failure.add_attribute 'brakeman:line', warning.line
|
91
|
+
failure.add_attribute 'brakeman:confidence', TEXT_CONFIDENCE[warning.confidence]
|
92
|
+
failure.add_attribute 'brakeman:code', warning.format_code
|
93
|
+
failure.add_text warning.to_s
|
94
|
+
}
|
95
|
+
|
96
|
+
test_suite.add_element 'system-out'
|
97
|
+
test_suite.add_element 'system-err'
|
98
|
+
}
|
99
|
+
|
100
|
+
doc.add test_suites
|
101
|
+
doc.write io
|
102
|
+
io.string
|
103
|
+
end
|
104
|
+
end
|
@@ -84,7 +84,6 @@ class Brakeman::Report::Markdown < Brakeman::Report::Table
|
|
84
84
|
end
|
85
85
|
|
86
86
|
def convert_warning warning, original
|
87
|
-
warning["Confidence"] = TEXT_CONFIDENCE[warning["Confidence"]]
|
88
87
|
warning["Message"] = markdown_message original, warning["Message"]
|
89
88
|
warning["Warning Type"] = "[#{warning['Warning Type']}](#{original.link})" if original.link
|
90
89
|
warning
|
data/lib/brakeman/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: brakeman-lib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Collins
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-02-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -348,6 +348,7 @@ files:
|
|
348
348
|
- lib/brakeman/report/report_hash.rb
|
349
349
|
- lib/brakeman/report/report_html.rb
|
350
350
|
- lib/brakeman/report/report_json.rb
|
351
|
+
- lib/brakeman/report/report_junit.rb
|
351
352
|
- lib/brakeman/report/report_markdown.rb
|
352
353
|
- lib/brakeman/report/report_table.rb
|
353
354
|
- lib/brakeman/report/report_tabs.rb
|
@@ -405,7 +406,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
405
406
|
- !ruby/object:Gem::Version
|
406
407
|
version: '0'
|
407
408
|
requirements: []
|
408
|
-
rubygems_version: 3.
|
409
|
+
rubygems_version: 3.1.2
|
409
410
|
signing_key:
|
410
411
|
specification_version: 4
|
411
412
|
summary: Security vulnerability scanner for Ruby on Rails.
|