brakeman 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +20 -0
- data/README.md +6 -1
- data/bin/brakeman +13 -3
- data/lib/brakeman.rb +64 -7
- data/lib/brakeman/call_index.rb +6 -4
- data/lib/brakeman/checks/check_basic_auth.rb +47 -2
- data/lib/brakeman/checks/check_cross_site_scripting.rb +50 -12
- data/lib/brakeman/checks/check_execute.rb +4 -1
- data/lib/brakeman/checks/check_model_attr_accessible.rb +48 -0
- data/lib/brakeman/checks/check_sql.rb +101 -154
- data/lib/brakeman/options.rb +16 -0
- data/lib/brakeman/parsers/rails2_erubis.rb +2 -0
- data/lib/brakeman/parsers/rails2_xss_plugin_erubis.rb +2 -0
- data/lib/brakeman/parsers/rails3_erubis.rb +2 -0
- data/lib/brakeman/processors/alias_processor.rb +19 -4
- data/lib/brakeman/processors/controller_alias_processor.rb +2 -3
- data/lib/brakeman/processors/gem_processor.rb +5 -4
- data/lib/brakeman/processors/lib/find_all_calls.rb +43 -16
- data/lib/brakeman/report.rb +39 -640
- data/lib/brakeman/report/ignore/config.rb +130 -0
- data/lib/brakeman/report/ignore/interactive.rb +311 -0
- data/lib/brakeman/report/renderer.rb +2 -0
- data/lib/brakeman/report/report_base.rb +279 -0
- data/lib/brakeman/report/report_csv.rb +56 -0
- data/lib/brakeman/report/report_hash.rb +22 -0
- data/lib/brakeman/report/report_html.rb +203 -0
- data/lib/brakeman/report/report_json.rb +46 -0
- data/lib/brakeman/report/report_table.rb +109 -0
- data/lib/brakeman/report/report_tabs.rb +17 -0
- data/lib/brakeman/report/templates/ignored_warnings.html.erb +21 -0
- data/lib/brakeman/report/templates/overview.html.erb +6 -0
- data/lib/brakeman/report/templates/security_warnings.html.erb +1 -1
- data/lib/brakeman/scanner.rb +14 -12
- data/lib/brakeman/tracker.rb +5 -1
- data/lib/brakeman/util.rb +2 -0
- data/lib/brakeman/version.rb +1 -1
- data/lib/ruby_parser/bm_sexp.rb +12 -1
- metadata +179 -90
- checksums.yaml +0 -7
@@ -18,10 +18,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
18
18
|
|
19
19
|
@sql_targets = [:all, :average, :calculate, :count, :count_by_sql, :exists?,
|
20
20
|
:find, :find_by_sql, :first, :last, :maximum, :minimum, :pluck, :sum, :update_all]
|
21
|
-
|
22
|
-
if tracker.options[:rails3]
|
23
|
-
@sql_targets.concat [:from, :group, :having, :joins, :lock, :order, :reorder, :select, :where]
|
24
|
-
end
|
21
|
+
@sql_targets.concat [:from, :group, :having, :joins, :lock, :order, :reorder, :select, :where] if tracker.options[:rails3]
|
25
22
|
|
26
23
|
Brakeman.debug "Finding possible SQL calls on models"
|
27
24
|
calls = tracker.find_call :targets => active_record_models.keys,
|
@@ -37,25 +34,11 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
37
34
|
Brakeman.debug "Finding calls to named_scope or scope"
|
38
35
|
calls.concat find_scope_calls
|
39
36
|
|
40
|
-
Brakeman.debug "Checking version of Rails for CVE
|
41
|
-
|
42
|
-
|
43
|
-
Brakeman.debug "Checking version of Rails for CVE-2012-2661"
|
44
|
-
check_rails_version_for_cve_2012_2661
|
45
|
-
|
46
|
-
Brakeman.debug "Checking version of Rails for CVE-2012-2695"
|
47
|
-
check_rails_version_for_cve_2012_2695
|
48
|
-
|
49
|
-
Brakeman.debug "Checking version of Rails for CVE-2012-5664"
|
50
|
-
check_rails_version_for_cve_2012_5664
|
51
|
-
|
52
|
-
Brakeman.debug "Checking version of Rails for CVE-2013-0155"
|
53
|
-
check_rails_version_for_cve_2013_0155
|
37
|
+
Brakeman.debug "Checking version of Rails for CVE issues"
|
38
|
+
check_rails_versions_against_cve_issues
|
54
39
|
|
55
40
|
Brakeman.debug "Processing possible SQL calls"
|
56
|
-
calls.each
|
57
|
-
process_result c
|
58
|
-
end
|
41
|
+
calls.each { |call| process_result call }
|
59
42
|
end
|
60
43
|
|
61
44
|
#Find calls to named_scope() or scope() in models
|
@@ -63,33 +46,24 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
63
46
|
def find_scope_calls
|
64
47
|
scope_calls = []
|
65
48
|
|
66
|
-
if version_between?
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
process_scope_with_block name, args
|
85
|
-
elsif second_arg.node_type == :call
|
86
|
-
call = second_arg
|
87
|
-
scope_calls << { :call => call, :location => { :type => :class, :class => name }, :method => call.method }
|
88
|
-
else
|
89
|
-
call = make_call(nil, :scope, args).line(args.line)
|
90
|
-
scope_calls << { :call => call, :location => { :type => :class, :class => name }, :method => :scope }
|
91
|
-
end
|
92
|
-
end
|
49
|
+
if version_between?("2.1.0", "3.0.9")
|
50
|
+
ar_scope_calls(:named_scope) do |name, args|
|
51
|
+
call = make_call(nil, :named_scope, args).line(args.line)
|
52
|
+
scope_calls << scope_call_hash(call, name, :named_scope)
|
53
|
+
end
|
54
|
+
elsif version_between?("3.1.0", "3.9.9")
|
55
|
+
ar_scope_calls(:scope) do |name, args|
|
56
|
+
second_arg = args[2]
|
57
|
+
next unless sexp? second_arg
|
58
|
+
|
59
|
+
if second_arg.node_type == :iter and node_type? second_arg.block, :block, :call
|
60
|
+
process_scope_with_block(name, args)
|
61
|
+
elsif second_arg.node_type == :call
|
62
|
+
call = second_arg
|
63
|
+
scope_calls << scope_call_hash(call, name, call.method)
|
64
|
+
else
|
65
|
+
call = make_call(nil, :scope, args).line(args.line)
|
66
|
+
scope_calls << scope_call_hash(call, name, :scope)
|
93
67
|
end
|
94
68
|
end
|
95
69
|
end
|
@@ -97,66 +71,34 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
97
71
|
scope_calls
|
98
72
|
end
|
99
73
|
|
100
|
-
def
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
%w[3.2.0 3.2.3 3.2.5]]
|
113
|
-
|
114
|
-
cve_warning_for versions, "CVE-2012-2661", "https://groups.google.com/d/topic/rubyonrails-security/dUaiOOGWL1k/discussion"
|
115
|
-
end
|
116
|
-
|
117
|
-
def check_rails_version_for_cve_2012_2695
|
118
|
-
versions = [%w[2.0.0 2.3.14 2.3.15],
|
119
|
-
%w[3.0.0 3.0.13 3.0.14],
|
120
|
-
%w[3.1.0 3.1.5 3.1.6],
|
121
|
-
%w[3.2.0 3.2.5 3.2.6]]
|
122
|
-
|
123
|
-
cve_warning_for versions, "CVE-2012-2695", "https://groups.google.com/d/topic/rubyonrails-security/l4L0TEVAz1k/discussion"
|
74
|
+
def ar_scope_calls(symbol_name = :named_scope, &block)
|
75
|
+
return_array = []
|
76
|
+
active_record_models.each do |name, model|
|
77
|
+
model_args = model[:options][symbol_name]
|
78
|
+
if model_args
|
79
|
+
model_args.each do |args|
|
80
|
+
yield name, args
|
81
|
+
return_array << [name, args]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
return_array
|
124
86
|
end
|
125
87
|
|
126
|
-
def
|
127
|
-
|
128
|
-
%w[3.0.0 3.0.17 3.0.18],
|
129
|
-
%w[3.1.0 3.1.8 3.1.9],
|
130
|
-
%w[3.2.0 3.2.9 3.2.18]]
|
131
|
-
|
132
|
-
cve_warning_for versions, "CVE-2012-5664", "https://groups.google.com/d/topic/rubyonrails-security/DCNTNp_qjFM/discussion"
|
88
|
+
def scope_call_hash(call, name, method)
|
89
|
+
{ :call => call, :location => { :type => :class, :class => name }, :method => :named_scope }
|
133
90
|
end
|
134
91
|
|
135
|
-
def check_rails_version_for_cve_2013_0155
|
136
|
-
versions = [%w[2.0.0 2.3.15 2.3.16],
|
137
|
-
%w[3.0.0 3.0.18 3.0.19],
|
138
|
-
%w[3.1.0 3.1.9 3.1.10],
|
139
|
-
%w[3.2.0 3.2.10 3.2.11]]
|
140
|
-
|
141
|
-
|
142
|
-
cve_warning_for versions, "CVE-2013-0155", "https://groups.google.com/d/topic/rubyonrails-security/c7jT-EeN9eI/discussion"
|
143
|
-
end
|
144
92
|
|
145
93
|
def process_scope_with_block model_name, args
|
146
94
|
scope_name = args[1][1]
|
147
95
|
block = args[-1][-1]
|
148
96
|
|
149
|
-
#Search lambda for calls to query methods
|
97
|
+
# Search lambda for calls to query methods
|
150
98
|
if block.node_type == :block
|
151
|
-
find_calls = Brakeman::FindAllCalls.new
|
152
|
-
|
153
|
-
find_calls.
|
154
|
-
|
155
|
-
find_calls.calls.each do |call|
|
156
|
-
if @sql_targets.include? call[:method]
|
157
|
-
process_result call
|
158
|
-
end
|
159
|
-
end
|
99
|
+
find_calls = Brakeman::FindAllCalls.new(tracker)
|
100
|
+
find_calls.process_source(block, :class => model_name, :method => scope_name)
|
101
|
+
find_calls.calls.each { |call| process_result(call) if @sql_targets.include?(call[:method]) }
|
160
102
|
elsif block.node_type == :call
|
161
103
|
process_result :target => block.target, :method => block.method, :call => block,
|
162
104
|
:location => { :type => :class, :class => model_name, :method => scope_name }
|
@@ -191,7 +133,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
191
133
|
# * lock
|
192
134
|
#
|
193
135
|
def process_result result
|
194
|
-
return if duplicate?
|
136
|
+
return if duplicate?(result) or result[:call].original_line
|
195
137
|
|
196
138
|
call = result[:call]
|
197
139
|
method = call.method
|
@@ -236,7 +178,8 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
236
178
|
if dangerous_value
|
237
179
|
add_result result
|
238
180
|
|
239
|
-
|
181
|
+
input = include_user_input? dangerous_value
|
182
|
+
if input
|
240
183
|
confidence = CONFIDENCE[:high]
|
241
184
|
user_input = input.match
|
242
185
|
else
|
@@ -267,6 +210,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
267
210
|
end
|
268
211
|
end
|
269
212
|
|
213
|
+
|
270
214
|
#The 'find' methods accept a number of different types of parameters:
|
271
215
|
#
|
272
216
|
# * The first argument might be :all, :first, or :last
|
@@ -279,9 +223,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
279
223
|
#
|
280
224
|
#This method should only be passed the second argument.
|
281
225
|
def check_find_arguments arg
|
282
|
-
if not sexp? arg or node_type? arg, :lit, :string, :str, :true, :false, :nil
|
283
|
-
return nil
|
284
|
-
end
|
226
|
+
return nil if not sexp? arg or node_type? arg, :lit, :string, :str, :true, :false, :nil
|
285
227
|
|
286
228
|
unsafe_sql? arg
|
287
229
|
end
|
@@ -289,11 +231,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
289
231
|
def check_scope_arguments call
|
290
232
|
scope_arg = call.second_arg #first arg is name of scope
|
291
233
|
|
292
|
-
|
293
|
-
unsafe_sql? scope_arg.block
|
294
|
-
else
|
295
|
-
unsafe_sql? scope_arg
|
296
|
-
end
|
234
|
+
node_type?(scope_arg, :iter) ? unsafe_sql?(scope_arg.block) : unsafe_sql?(scope_arg)
|
297
235
|
end
|
298
236
|
|
299
237
|
def check_query_arguments arg
|
@@ -330,13 +268,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
330
268
|
return unless sexp? args
|
331
269
|
|
332
270
|
if node_type? args, :arglist
|
333
|
-
args
|
334
|
-
if unsafe_arg = unsafe_sql?(arg)
|
335
|
-
return unsafe_arg
|
336
|
-
end
|
337
|
-
end
|
338
|
-
|
339
|
-
nil
|
271
|
+
check_update_all_arguments(args)
|
340
272
|
else
|
341
273
|
unsafe_sql? args
|
342
274
|
end
|
@@ -349,11 +281,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
349
281
|
|
350
282
|
#This is kind of unnecessary, because unsafe_sql? will handle an array
|
351
283
|
#correctly, but might be better to be explicit.
|
352
|
-
|
353
|
-
unsafe_sql? arg[1]
|
354
|
-
else
|
355
|
-
unsafe_sql? arg
|
356
|
-
end
|
284
|
+
array?(arg) ? unsafe_sql?(arg[1]) : unsafe_sql?(arg)
|
357
285
|
end
|
358
286
|
|
359
287
|
#joins can take a string, hash of associations, or an array of both(?)
|
@@ -363,9 +291,8 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
363
291
|
|
364
292
|
if array? arg
|
365
293
|
arg.each do |a|
|
366
|
-
|
367
|
-
|
368
|
-
end
|
294
|
+
unsafe_arg = check_joins_arguments a
|
295
|
+
return unsafe_arg if unsafe_arg
|
369
296
|
end
|
370
297
|
|
371
298
|
nil
|
@@ -376,8 +303,8 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
376
303
|
|
377
304
|
def check_update_all_arguments args
|
378
305
|
args.each do |arg|
|
379
|
-
|
380
|
-
return
|
306
|
+
unsafe_arg = unsafe_sql? arg
|
307
|
+
return unsafe_arg if unsafe_arg
|
381
308
|
end
|
382
309
|
|
383
310
|
nil
|
@@ -389,7 +316,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
389
316
|
def check_lock_arguments arg
|
390
317
|
return unless sexp? arg and not node_type? arg, :hash, :array, :string, :str
|
391
318
|
|
392
|
-
unsafe_sql?
|
319
|
+
unsafe_sql?(arg, :ignore_hash)
|
393
320
|
end
|
394
321
|
|
395
322
|
|
@@ -398,10 +325,9 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
398
325
|
#could be bad)
|
399
326
|
def check_hash_keys exp
|
400
327
|
hash_iterate(exp) do |key, value|
|
401
|
-
unless symbol?
|
402
|
-
|
403
|
-
|
404
|
-
end
|
328
|
+
unless symbol?(key)
|
329
|
+
unsafe_key = unsafe_sql? value
|
330
|
+
return unsafe_key if unsafe_key
|
405
331
|
end
|
406
332
|
end
|
407
333
|
|
@@ -414,9 +340,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
414
340
|
#unless safe_value? explicitly returns true.
|
415
341
|
def check_string_interp arg
|
416
342
|
arg.each do |exp|
|
417
|
-
if node_type?(exp, :string_eval, :evstr) and not safe_value?
|
418
|
-
return exp.value
|
419
|
-
end
|
343
|
+
return exp.value if node_type?(exp, :string_eval, :evstr) and not safe_value?(exp.value)
|
420
344
|
end
|
421
345
|
|
422
346
|
nil
|
@@ -427,15 +351,10 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
427
351
|
#
|
428
352
|
#Otherwise, returns false/nil.
|
429
353
|
def unsafe_sql? exp, ignore_hash = false
|
430
|
-
return unless sexp?
|
354
|
+
return unless sexp?(exp)
|
431
355
|
|
432
356
|
dangerous_value = find_dangerous_value exp, ignore_hash
|
433
|
-
|
434
|
-
if safe_value? dangerous_value
|
435
|
-
false
|
436
|
-
else
|
437
|
-
dangerous_value
|
438
|
-
end
|
357
|
+
safe_value?(dangerous_value) ? false : dangerous_value
|
439
358
|
end
|
440
359
|
|
441
360
|
#Check _exp_ for dangerous values. Used by unsafe_sql?
|
@@ -449,7 +368,6 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
449
368
|
# ["blah = ? AND thing = ?", ...]
|
450
369
|
#
|
451
370
|
#and check first value
|
452
|
-
|
453
371
|
unsafe_sql? exp[1]
|
454
372
|
when :string_interp, :dstr
|
455
373
|
check_string_interp exp
|
@@ -467,7 +385,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
467
385
|
end
|
468
386
|
when :or
|
469
387
|
if unsafe = (unsafe_sql?(exp.lhs) || unsafe_sql?(exp.rhs))
|
470
|
-
|
388
|
+
unsafe
|
471
389
|
else
|
472
390
|
nil
|
473
391
|
end
|
@@ -525,12 +443,12 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
525
443
|
method = exp.method
|
526
444
|
|
527
445
|
if string? target or string? exp.first_arg
|
528
|
-
if STRING_METHODS.include? method
|
529
|
-
return exp
|
530
|
-
end
|
446
|
+
return exp if STRING_METHODS.include? method
|
531
447
|
elsif STRING_METHODS.include? method and call? target
|
532
|
-
unsafe_sql? target
|
448
|
+
return unsafe_sql? target
|
533
449
|
end
|
450
|
+
|
451
|
+
nil
|
534
452
|
end
|
535
453
|
|
536
454
|
IGNORE_METHODS_IN_SQL = Set[:id, :merge_conditions, :table_name, :to_i, :to_f,
|
@@ -561,8 +479,9 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
561
479
|
#Check call for string building
|
562
480
|
def check_call exp
|
563
481
|
return unless call? exp
|
482
|
+
unsafe = check_for_string_building exp
|
564
483
|
|
565
|
-
if unsafe
|
484
|
+
if unsafe
|
566
485
|
unsafe
|
567
486
|
elsif call? exp.target
|
568
487
|
check_call exp.target
|
@@ -576,11 +495,9 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
576
495
|
#
|
577
496
|
#http://www.rorsecurity.info/2008/09/08/sql-injection-issue-in-limit-and-offset-parameter/
|
578
497
|
def check_for_limit_or_offset_vulnerability options
|
579
|
-
return false if @rails_version.nil? or @rails_version >= "2.1.1" or not hash?
|
498
|
+
return false if @rails_version.nil? or @rails_version >= "2.1.1" or not hash?(options)
|
580
499
|
|
581
|
-
if hash_access(options, :limit) or hash_access(options, :offset)
|
582
|
-
return true
|
583
|
-
end
|
500
|
+
return true if hash_access(options, :limit) or hash_access(options, :offset)
|
584
501
|
|
585
502
|
false
|
586
503
|
end
|
@@ -606,14 +523,44 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
606
523
|
|
607
524
|
def upgrade_version? versions
|
608
525
|
versions.each do |low, high, upgrade|
|
609
|
-
if version_between? low, high
|
610
|
-
return upgrade
|
611
|
-
end
|
526
|
+
return upgrade if version_between? low, high
|
612
527
|
end
|
613
528
|
|
614
529
|
false
|
615
530
|
end
|
616
531
|
|
532
|
+
def check_rails_versions_against_cve_issues
|
533
|
+
[
|
534
|
+
{
|
535
|
+
:cve => "CVE-2012-2660",
|
536
|
+
:versions => [%w[2.0.0 2.3.14 2.3.17], %w[3.0.0 3.0.12 3.0.13], %w[3.1.0 3.1.4 3.1.5], %w[3.2.0 3.2.3 3.2.4]],
|
537
|
+
:url => "https://groups.google.com/d/topic/rubyonrails-security/8SA-M3as7A8/discussion"
|
538
|
+
},
|
539
|
+
{
|
540
|
+
:cve => "CVE-2012-2661",
|
541
|
+
:versions => [%w[3.0.0 3.0.12 3.0.13], %w[3.1.0 3.1.4 3.1.5], %w[3.2.0 3.2.3 3.2.5]],
|
542
|
+
:url => "https://groups.google.com/d/topic/rubyonrails-security/dUaiOOGWL1k/discussion"
|
543
|
+
},
|
544
|
+
{
|
545
|
+
:cve => "CVE-2012-2695",
|
546
|
+
:versions => [%w[2.0.0 2.3.14 2.3.15], %w[3.0.0 3.0.13 3.0.14], %w[3.1.0 3.1.5 3.1.6], %w[3.2.0 3.2.5 3.2.6]],
|
547
|
+
:url => "https://groups.google.com/d/topic/rubyonrails-security/l4L0TEVAz1k/discussion"
|
548
|
+
},
|
549
|
+
{
|
550
|
+
:cve => "CVE-2012-5664",
|
551
|
+
:versions => [%w[2.0.0 2.3.14 2.3.15], %w[3.0.0 3.0.17 3.0.18], %w[3.1.0 3.1.8 3.1.9], %w[3.2.0 3.2.9 3.2.18]],
|
552
|
+
:url => "https://groups.google.com/d/topic/rubyonrails-security/DCNTNp_qjFM/discussion"
|
553
|
+
},
|
554
|
+
{
|
555
|
+
:cve => "CVE-2013-0155",
|
556
|
+
:versions => [%w[2.0.0 2.3.15 2.3.16], %w[3.0.0 3.0.18 3.0.19], %w[3.1.0 3.1.9 3.1.10], %w[3.2.0 3.2.10 3.2.11]],
|
557
|
+
:url => "https://groups.google.com/d/topic/rubyonrails-security/c7jT-EeN9eI/discussion"
|
558
|
+
},
|
559
|
+
].each do |cve_issue|
|
560
|
+
cve_warning_for cve_issue[:versions], cve_issue[:cve], cve_issue[:url]
|
561
|
+
end
|
562
|
+
end
|
563
|
+
|
617
564
|
def cve_warning_for versions, cve, link
|
618
565
|
upgrade_version = upgrade_version? versions
|
619
566
|
return unless upgrade_version
|
data/lib/brakeman/options.rb
CHANGED
@@ -79,6 +79,10 @@ module Brakeman::Options
|
|
79
79
|
options[:ignore_ifs] = true
|
80
80
|
end
|
81
81
|
|
82
|
+
opts.on "--branch-limit LIMIT", Integer, "Limit depth of values in branches (-1 for no limit)" do |limit|
|
83
|
+
options[:branch_limit] = limit
|
84
|
+
end
|
85
|
+
|
82
86
|
opts.on "-r", "--report-direct", "Only report direct use of untrusted data" do |option|
|
83
87
|
options[:check_arguments] = !option
|
84
88
|
end
|
@@ -149,6 +153,14 @@ module Brakeman::Options
|
|
149
153
|
options[:html_style] = File.expand_path file
|
150
154
|
end
|
151
155
|
|
156
|
+
opts.on "-i IGNOREFILE", "--ignore-config IGNOREFILE", "Use configuration to ignore warnings" do |file|
|
157
|
+
options[:ignore_file] = file
|
158
|
+
end
|
159
|
+
|
160
|
+
opts.on "-I", "--interactive-ignore", "Interactively ignore warnings" do
|
161
|
+
options[:interactive_ignore] = true
|
162
|
+
end
|
163
|
+
|
152
164
|
opts.on "-l", "--[no-]combine-locations", "Combine warning locations (Default)" do |combine|
|
153
165
|
options[:combine_locations] = combine
|
154
166
|
end
|
@@ -234,6 +246,10 @@ module Brakeman::Options
|
|
234
246
|
parser.parse args
|
235
247
|
end
|
236
248
|
|
249
|
+
if options[:previous_results_json] and options[:output_files]
|
250
|
+
options[:comparison_output_file] = options[:output_files].shift
|
251
|
+
end
|
252
|
+
|
237
253
|
return options, parser
|
238
254
|
end
|
239
255
|
end
|