brakeman-lib 3.6.2 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES +9 -0
- data/lib/brakeman.rb +7 -0
- data/lib/brakeman/checks/check_redirect.rb +26 -3
- data/lib/brakeman/processors/alias_processor.rb +91 -3
- data/lib/brakeman/processors/base_processor.rb +9 -1
- data/lib/brakeman/report/ignore/interactive.rb +9 -4
- data/lib/brakeman/tracker/constants.rb +11 -2
- data/lib/brakeman/version.rb +1 -1
- data/lib/ruby_parser/bm_sexp.rb +0 -8
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3c3cd6ef685d42e97e293f59c00f8dbb22fdd260
|
4
|
+
data.tar.gz: 607b26573452f7a3003e34ff1151dc1e46a41cb1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b88ae2370d4dfde46dcfd88558bf41bbc99bb2b371ea27749bdb0a0c1e0bb456f9de3ecc44f9f891f61ae4f19cb99ae2b2347f55391580f8ae43c72657ac410b
|
7
|
+
data.tar.gz: a0ff1f759bde8f5ed837bc01d812bbc8e6140b4e8930ab799cd0e7362c7a5594272a9ef438cf1eaf3291431442d67f051c33aff5a2322ee131267f1eb218e179
|
data/CHANGES
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
# 3.7.0
|
2
|
+
|
3
|
+
* Improve support for rails4/rails5 options in config file
|
4
|
+
* Track more information about constant assignments
|
5
|
+
* Show progress indicator in interactive mode
|
6
|
+
* Handle simple conditional guards that use `return`
|
7
|
+
* Fix false positive for redirect_to in Rails 4 (Mário Areias)
|
8
|
+
* Avoid interpolating hashes/arrays on failed access
|
9
|
+
|
1
10
|
# 3.6.2
|
2
11
|
|
3
12
|
* Handle safe call operator in checks
|
data/lib/brakeman.rb
CHANGED
@@ -90,6 +90,13 @@ module Brakeman
|
|
90
90
|
options[:quiet] = true
|
91
91
|
end
|
92
92
|
|
93
|
+
if options[:rails4]
|
94
|
+
options[:rails3] = true
|
95
|
+
elsif options[:rails5]
|
96
|
+
options[:rails3] = true
|
97
|
+
options[:rails4] = true
|
98
|
+
end
|
99
|
+
|
93
100
|
options[:output_formats] = get_output_formats options
|
94
101
|
options[:github_url] = get_github_url options
|
95
102
|
|
@@ -105,11 +105,34 @@ class Brakeman::CheckRedirect < Brakeman::BaseCheck
|
|
105
105
|
arg = call.first_arg
|
106
106
|
|
107
107
|
if hash? arg
|
108
|
-
|
109
|
-
return true if true?(value)
|
110
|
-
end
|
108
|
+
return has_only_path? arg
|
111
109
|
elsif call? arg and arg.method == :url_for
|
112
110
|
return check_url_for(arg)
|
111
|
+
elsif call? arg and hash? arg.first_arg and use_unsafe_hash_method? arg
|
112
|
+
return has_only_path? arg.first_arg
|
113
|
+
end
|
114
|
+
|
115
|
+
false
|
116
|
+
end
|
117
|
+
|
118
|
+
def use_unsafe_hash_method? arg
|
119
|
+
return call_has_param(arg, :to_unsafe_hash) || call_has_param(arg, :to_unsafe_h)
|
120
|
+
end
|
121
|
+
|
122
|
+
def call_has_param arg, key
|
123
|
+
if call? arg and call? arg.target
|
124
|
+
target = arg.target
|
125
|
+
method = target.method
|
126
|
+
|
127
|
+
node_type? target.target, :params and method == key
|
128
|
+
else
|
129
|
+
false
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def has_only_path? arg
|
134
|
+
if value = hash_access(arg, :only_path)
|
135
|
+
return true if true?(value)
|
113
136
|
end
|
114
137
|
|
115
138
|
false
|
@@ -87,6 +87,73 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
|
+
def process_bracket_call exp
|
91
|
+
r = replace(exp)
|
92
|
+
|
93
|
+
if r != exp
|
94
|
+
return r
|
95
|
+
end
|
96
|
+
|
97
|
+
exp.arglist = process_default(exp.arglist)
|
98
|
+
|
99
|
+
r = replace(exp)
|
100
|
+
|
101
|
+
if r != exp
|
102
|
+
return r
|
103
|
+
end
|
104
|
+
|
105
|
+
t = process(exp.target.deep_clone)
|
106
|
+
|
107
|
+
# sometimes t[blah] has a match in the env
|
108
|
+
# but we don't want to actually set the target
|
109
|
+
# in case the target is big...which is what this
|
110
|
+
# whole method is trying to avoid
|
111
|
+
if t != exp.target
|
112
|
+
e = exp.deep_clone
|
113
|
+
e.target = t
|
114
|
+
|
115
|
+
r = replace(e)
|
116
|
+
|
117
|
+
if r != e
|
118
|
+
return r
|
119
|
+
end
|
120
|
+
else
|
121
|
+
t = nil
|
122
|
+
end
|
123
|
+
|
124
|
+
if hash? t
|
125
|
+
if v = hash_access(t, exp.first_arg)
|
126
|
+
v.deep_clone(exp.line)
|
127
|
+
else
|
128
|
+
case t.node_type
|
129
|
+
when :params
|
130
|
+
exp.target = PARAMS_SEXP.deep_clone(exp.target.line)
|
131
|
+
when :session
|
132
|
+
exp.target = SESSION_SEXP.deep_clone(exp.target.line)
|
133
|
+
when :cookies
|
134
|
+
exp.target = COOKIES_SEXP.deep_clone(exp.target.line)
|
135
|
+
end
|
136
|
+
|
137
|
+
exp
|
138
|
+
end
|
139
|
+
elsif array? t
|
140
|
+
if v = process_array_access(t, exp.args)
|
141
|
+
v.deep_clone(exp.line)
|
142
|
+
else
|
143
|
+
exp
|
144
|
+
end
|
145
|
+
elsif t
|
146
|
+
exp.target = t
|
147
|
+
exp
|
148
|
+
else
|
149
|
+
if exp.target # `self` target is reported as `nil` https://github.com/seattlerb/ruby_parser/issues/250
|
150
|
+
exp.target = process_default exp.target
|
151
|
+
end
|
152
|
+
|
153
|
+
exp
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
90
157
|
ARRAY_CONST = s(:const, :Array)
|
91
158
|
HASH_CONST = s(:const, :Hash)
|
92
159
|
RAILS_TEST = s(:call, s(:call, s(:const, :Rails), :env), :test?)
|
@@ -99,7 +166,12 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
99
166
|
if exp.node_type == :safe_call
|
100
167
|
exp.node_type = :call
|
101
168
|
end
|
102
|
-
|
169
|
+
|
170
|
+
if exp.method == :[]
|
171
|
+
return process_bracket_call exp
|
172
|
+
else
|
173
|
+
exp = process_default exp
|
174
|
+
end
|
103
175
|
|
104
176
|
#In case it is replaced with something else
|
105
177
|
unless call? exp
|
@@ -391,7 +463,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
391
463
|
# x[:y] = 1
|
392
464
|
def process_attrasgn exp
|
393
465
|
tar_variable = exp.target
|
394
|
-
target =
|
466
|
+
target = process(exp.target)
|
395
467
|
method = exp.method
|
396
468
|
index_arg = exp.first_arg
|
397
469
|
value_arg = exp.second_arg
|
@@ -406,6 +478,10 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
406
478
|
if hash? target
|
407
479
|
env[tar_variable] = hash_insert target.deep_clone, index, value
|
408
480
|
end
|
481
|
+
|
482
|
+
unless node_type? target, :hash
|
483
|
+
exp.target = target
|
484
|
+
end
|
409
485
|
elsif method.to_s[-1,1] == "="
|
410
486
|
exp.first_arg = process(index_arg)
|
411
487
|
value = get_rhs(exp)
|
@@ -413,6 +489,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
413
489
|
match = Sexp.new(:call, target, method.to_s[0..-2].to_sym)
|
414
490
|
|
415
491
|
set_value match, value
|
492
|
+
exp.target = target
|
416
493
|
else
|
417
494
|
raise "Unrecognized assignment: #{exp}"
|
418
495
|
end
|
@@ -522,7 +599,14 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
522
599
|
exp.rhs = process exp.rhs
|
523
600
|
end
|
524
601
|
|
525
|
-
|
602
|
+
if @tracker
|
603
|
+
@tracker.add_constant exp.lhs,
|
604
|
+
exp.rhs,
|
605
|
+
:file => current_file_name,
|
606
|
+
:module => @current_module,
|
607
|
+
:class => @current_class,
|
608
|
+
:method => @current_method
|
609
|
+
end
|
526
610
|
|
527
611
|
if exp.lhs.is_a? Symbol
|
528
612
|
match = Sexp.new(:const, exp.lhs)
|
@@ -598,6 +682,10 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
598
682
|
env.current[var] = condition.target[1]
|
599
683
|
exp[branch_index] = process_if_branch branch
|
600
684
|
env.current[var] = previous_value
|
685
|
+
elsif i == 1 and array_include_all_literals? condition and node_type? branch, :return
|
686
|
+
var = condition.first_arg
|
687
|
+
env.current[var] = condition.target[1]
|
688
|
+
exp[branch_index] = process_if_branch branch
|
601
689
|
else
|
602
690
|
exp[branch_index] = process_if_branch branch
|
603
691
|
end
|
@@ -183,7 +183,15 @@ class Brakeman::BaseProcessor < Brakeman::SexpProcessor
|
|
183
183
|
end
|
184
184
|
|
185
185
|
def process_cdecl exp
|
186
|
-
|
186
|
+
if @tracker
|
187
|
+
@tracker.add_constant exp.lhs,
|
188
|
+
exp.rhs,
|
189
|
+
:file => current_file_name,
|
190
|
+
:module => @current_module,
|
191
|
+
:class => @current_class,
|
192
|
+
:method => @current_method
|
193
|
+
end
|
194
|
+
|
187
195
|
exp
|
188
196
|
end
|
189
197
|
|
@@ -101,7 +101,7 @@ module Brakeman
|
|
101
101
|
end
|
102
102
|
|
103
103
|
def pre_show_help
|
104
|
-
say "-" *
|
104
|
+
say "-" * 30
|
105
105
|
say "Actions:", :cyan
|
106
106
|
show_help
|
107
107
|
end
|
@@ -189,7 +189,11 @@ q - Quit, do not update ignored warnings
|
|
189
189
|
end
|
190
190
|
|
191
191
|
def process_warnings
|
192
|
-
@new_warnings.
|
192
|
+
@warning_count = @new_warnings.length
|
193
|
+
|
194
|
+
@new_warnings.each_with_index do |w, index|
|
195
|
+
@current_index = index
|
196
|
+
|
193
197
|
if skip_ignored? w or @skip_rest
|
194
198
|
next
|
195
199
|
elsif @ignore_rest
|
@@ -261,7 +265,8 @@ q - Quit, do not update ignored warnings
|
|
261
265
|
end
|
262
266
|
|
263
267
|
def pretty_display warning
|
264
|
-
|
268
|
+
progress = "#{@current_index + 1}/#{@warning_count}"
|
269
|
+
say "-------- #{progress} #{"-" * (20 - progress.length)}", :cyan
|
265
270
|
show_confidence warning
|
266
271
|
|
267
272
|
label "Category"
|
@@ -302,7 +307,7 @@ q - Quit, do not update ignored warnings
|
|
302
307
|
end
|
303
308
|
|
304
309
|
def summarize_changes
|
305
|
-
say "-" *
|
310
|
+
say "-" * 30
|
306
311
|
|
307
312
|
say "Ignoring #{@ignore_config.ignored_warnings.length} warnings", :yellow
|
308
313
|
say "Showing #{@ignore_config.shown_warnings.length} warnings", :green
|
@@ -2,14 +2,18 @@ require 'brakeman/processors/output_processor'
|
|
2
2
|
|
3
3
|
module Brakeman
|
4
4
|
class Constant
|
5
|
-
attr_reader :name, :name_array, :file, :value
|
5
|
+
attr_reader :name, :name_array, :file, :value, :context
|
6
6
|
|
7
|
-
def initialize name, value
|
7
|
+
def initialize name, value, context = {}
|
8
8
|
set_name name, context
|
9
9
|
@value = value
|
10
10
|
@context = context
|
11
11
|
|
12
12
|
if @context
|
13
|
+
if @context[:class].is_a? Brakeman::Controller
|
14
|
+
@context[:class] = @context[:class].name
|
15
|
+
end
|
16
|
+
|
13
17
|
@file = @context[:file]
|
14
18
|
end
|
15
19
|
end
|
@@ -88,6 +92,11 @@ module Brakeman
|
|
88
92
|
nil
|
89
93
|
end
|
90
94
|
|
95
|
+
def find_all exp
|
96
|
+
base_name = Constants.get_constant_base_name(exp)
|
97
|
+
@constants[base_name]
|
98
|
+
end
|
99
|
+
|
91
100
|
def add name, value, context = nil
|
92
101
|
if call? value and value.method == :freeze
|
93
102
|
value = value.target
|
data/lib/brakeman/version.rb
CHANGED
data/lib/ruby_parser/bm_sexp.rb
CHANGED
@@ -120,14 +120,6 @@ class Sexp
|
|
120
120
|
old_find_node(*args)
|
121
121
|
end
|
122
122
|
|
123
|
-
#Iterates over the Sexps in an Sexp, skipping values that are not
|
124
|
-
#an Sexp.
|
125
|
-
def each_sexp
|
126
|
-
self.each do |e|
|
127
|
-
yield e if Sexp === e
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
123
|
#Raise a WrongSexpError if the nodes type does not match one of the expected
|
132
124
|
#types.
|
133
125
|
def expect *types
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: brakeman-lib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Collins
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain:
|
11
11
|
- brakeman-public_cert.pem
|
12
|
-
date: 2017-
|
12
|
+
date: 2017-06-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: minitest
|
@@ -39,6 +39,20 @@ dependencies:
|
|
39
39
|
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: 3.9.0
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: sexp_processor
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '4.7'
|
49
|
+
type: :runtime
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '4.7'
|
42
56
|
- !ruby/object:Gem::Dependency
|
43
57
|
name: ruby2ruby
|
44
58
|
requirement: !ruby/object:Gem::Requirement
|