brakeman-lib 4.1.1 → 4.2.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 +5 -5
- data/CHANGES.md +13 -0
- data/lib/brakeman/app_tree.rb +1 -1
- data/lib/brakeman/checks/base_check.rb +2 -6
- data/lib/brakeman/checks/check_execute.rb +21 -3
- data/lib/brakeman/checks/check_redirect.rb +3 -1
- data/lib/brakeman/checks/check_sql.rb +2 -2
- data/lib/brakeman/checks/check_symbol_dos.rb +8 -0
- data/lib/brakeman/checks/check_unscoped_find.rb +17 -1
- data/lib/brakeman/processors/alias_processor.rb +5 -2
- data/lib/brakeman/processors/base_processor.rb +1 -5
- data/lib/brakeman/processors/erb_template_processor.rb +1 -1
- data/lib/brakeman/processors/library_processor.rb +9 -1
- data/lib/brakeman/version.rb +1 -1
- data/lib/ruby_parser/bm_sexp.rb +4 -0
- metadata +5 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 1a02aad3664741bec5ac0228bb7010df63d372fe2720fa3dde272aed8e92c070
|
|
4
|
+
data.tar.gz: d882ea01bc6b151920763b3c9f8ca9220c0abfbd6c443c41d72ef447014c6bfa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bdce57e4ee118d55722a174c0f411dc19d3cc9a7f636c080124a2ebdc954e8f063e6022460d989c59cf265a7f5ef58978191a06057fb37c5f02e29d120d5b348
|
|
7
|
+
data.tar.gz: 1ac676aaefc2a521af60b0bf12f9f3dc94df6e0b1925dc0918e41542b2f8f7f79d8d621e00dd3486b3a1205e1992358aa7173dfddd88e0db3bf713f2e13ee3c3
|
data/CHANGES.md
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
# 4.2.0
|
|
2
|
+
|
|
3
|
+
* Avoid warning about symbol DoS on `Model#attributes`
|
|
4
|
+
* Avoid warning about open redirects with model methods ending with `_path`
|
|
5
|
+
* Avoid warning about command injection with `Shellwords.escape`
|
|
6
|
+
* Use ivars from `initialize` in libraries
|
|
7
|
+
* `Sexp#body=` can accept `:rlist` from `Sexp#body_list`
|
|
8
|
+
* Update RubyParser to 3.11.0
|
|
9
|
+
* Fix multiple assignment of globals
|
|
10
|
+
* Warn about SQL injection in `not`
|
|
11
|
+
* Exclude template folders in `lib/` (kru0096)
|
|
12
|
+
* Handle ERb use of `String#<<` method for Ruby 2.5 (Pocke)
|
|
13
|
+
|
|
1
14
|
# 4.1.1
|
|
2
15
|
|
|
3
16
|
* Remove check for use of `permit` with `*_id` keys
|
data/lib/brakeman/app_tree.rb
CHANGED
|
@@ -110,7 +110,7 @@ module Brakeman
|
|
|
110
110
|
end
|
|
111
111
|
|
|
112
112
|
def lib_paths
|
|
113
|
-
@lib_files ||= find_paths("lib").reject { |path| path.include? "/generators/" or path.include? "lib/tasks/" } +
|
|
113
|
+
@lib_files ||= find_paths("lib").reject { |path| path.include? "/generators/" or path.include? "lib/tasks/" or path.include? "lib/templates/" } +
|
|
114
114
|
find_additional_lib_paths +
|
|
115
115
|
find_helper_paths
|
|
116
116
|
end
|
|
@@ -62,12 +62,8 @@ class Brakeman::BaseCheck < Brakeman::SexpProcessor
|
|
|
62
62
|
#Default Sexp processing. Iterates over each value in the Sexp
|
|
63
63
|
#and processes them if they are also Sexps.
|
|
64
64
|
def process_default exp
|
|
65
|
-
exp.
|
|
66
|
-
if sexp? e
|
|
67
|
-
process e
|
|
68
|
-
else
|
|
69
|
-
e
|
|
70
|
-
end
|
|
65
|
+
exp.each do |e|
|
|
66
|
+
process e if sexp? e
|
|
71
67
|
end
|
|
72
68
|
|
|
73
69
|
exp
|
|
@@ -17,6 +17,10 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
|
|
|
17
17
|
s(:call, s(:const, :Rails), :root),
|
|
18
18
|
s(:call, s(:const, :Rails), :env)]
|
|
19
19
|
|
|
20
|
+
SHELL_ESCAPES = [:escape, :shellescape, :join]
|
|
21
|
+
|
|
22
|
+
SHELLWORDS = s(:const, :Shellwords)
|
|
23
|
+
|
|
20
24
|
#Check models, controllers, and views for command injection.
|
|
21
25
|
def run_check
|
|
22
26
|
Brakeman.debug "Finding system calls using ``"
|
|
@@ -127,15 +131,17 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
|
|
|
127
131
|
:confidence => confidence
|
|
128
132
|
end
|
|
129
133
|
|
|
134
|
+
# This method expects a :dstr or :evstr node
|
|
130
135
|
def dangerous? exp
|
|
131
136
|
exp.each_sexp do |e|
|
|
132
|
-
next if node_type? e, :lit, :str
|
|
133
|
-
next if SAFE_VALUES.include? e
|
|
134
|
-
|
|
135
137
|
if call? e and e.method == :to_s
|
|
136
138
|
e = e.target
|
|
137
139
|
end
|
|
138
140
|
|
|
141
|
+
next if node_type? e, :lit, :str
|
|
142
|
+
next if SAFE_VALUES.include? e
|
|
143
|
+
next if shell_escape? e
|
|
144
|
+
|
|
139
145
|
if node_type? e, :or, :evstr, :dstr
|
|
140
146
|
if res = dangerous?(e)
|
|
141
147
|
return res
|
|
@@ -161,4 +167,16 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
|
|
|
161
167
|
|
|
162
168
|
false
|
|
163
169
|
end
|
|
170
|
+
|
|
171
|
+
def shell_escape? exp
|
|
172
|
+
return false unless call? exp
|
|
173
|
+
|
|
174
|
+
if exp.target == SHELLWORDS and SHELL_ESCAPES.include? exp.method
|
|
175
|
+
true
|
|
176
|
+
elsif exp.method == :shelljoin
|
|
177
|
+
true
|
|
178
|
+
else
|
|
179
|
+
false
|
|
180
|
+
end
|
|
181
|
+
end
|
|
164
182
|
end
|
|
@@ -79,7 +79,9 @@ class Brakeman::CheckRedirect < Brakeman::BaseCheck
|
|
|
79
79
|
end
|
|
80
80
|
|
|
81
81
|
if res = has_immediate_model?(arg)
|
|
82
|
-
|
|
82
|
+
unless call? arg and arg.method.to_s =~ /_path/
|
|
83
|
+
return Match.new(immediate, res)
|
|
84
|
+
end
|
|
83
85
|
elsif call? arg
|
|
84
86
|
if request_value? arg
|
|
85
87
|
return Match.new(immediate, arg)
|
|
@@ -19,7 +19,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
|
19
19
|
@sql_targets = [:average, :calculate, :count, :count_by_sql, :delete_all, :destroy_all,
|
|
20
20
|
:find_by_sql, :maximum, :minimum, :pluck, :sum, :update_all]
|
|
21
21
|
@sql_targets.concat [:from, :group, :having, :joins, :lock, :order, :reorder, :where] if tracker.options[:rails3]
|
|
22
|
-
@sql_targets << :find_by << :find_by! if tracker.options[:rails4]
|
|
22
|
+
@sql_targets << :find_by << :find_by! << :not if tracker.options[:rails4]
|
|
23
23
|
|
|
24
24
|
if version_between?("2.0.0", "3.9.9") or tracker.config.rails_version.nil?
|
|
25
25
|
@sql_targets << :first << :last << :all
|
|
@@ -184,7 +184,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
|
184
184
|
else
|
|
185
185
|
check_find_arguments call.last_arg
|
|
186
186
|
end
|
|
187
|
-
when :where, :having, :find_by, :find_by
|
|
187
|
+
when :where, :having, :find_by, :find_by!, :not
|
|
188
188
|
check_query_arguments call.arglist
|
|
189
189
|
when :order, :group, :reorder
|
|
190
190
|
check_order_arguments call.arglist
|
|
@@ -33,8 +33,10 @@ class Brakeman::CheckSymbolDoS < Brakeman::BaseCheck
|
|
|
33
33
|
confidence = :medium
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
+
|
|
36
37
|
if confidence
|
|
37
38
|
return if safe_parameter? input.match
|
|
39
|
+
return if symbolizing_attributes? input
|
|
38
40
|
|
|
39
41
|
message = "Symbol conversion from unsafe string (#{friendly_type_of input})"
|
|
40
42
|
|
|
@@ -60,4 +62,10 @@ class Brakeman::CheckSymbolDoS < Brakeman::BaseCheck
|
|
|
60
62
|
false
|
|
61
63
|
end
|
|
62
64
|
end
|
|
65
|
+
|
|
66
|
+
def symbolizing_attributes? input
|
|
67
|
+
input.type == :model and
|
|
68
|
+
call? input.match and
|
|
69
|
+
input.match.method == :attributes
|
|
70
|
+
end
|
|
63
71
|
end
|
|
@@ -10,7 +10,11 @@ class Brakeman::CheckUnscopedFind < Brakeman::BaseCheck
|
|
|
10
10
|
Brakeman.debug("Finding instances of #find on models with associations")
|
|
11
11
|
|
|
12
12
|
associated_model_names = active_record_models.keys.select do |name|
|
|
13
|
-
active_record_models[name].associations[:belongs_to]
|
|
13
|
+
if belongs_to = active_record_models[name].associations[:belongs_to]
|
|
14
|
+
not optional_belongs_to? belongs_to
|
|
15
|
+
else
|
|
16
|
+
false
|
|
17
|
+
end
|
|
14
18
|
end
|
|
15
19
|
|
|
16
20
|
calls = tracker.find_call :method => [:find, :find_by_id, :find_by_id!],
|
|
@@ -38,4 +42,16 @@ class Brakeman::CheckUnscopedFind < Brakeman::BaseCheck
|
|
|
38
42
|
:confidence => :weak,
|
|
39
43
|
:user_input => input
|
|
40
44
|
end
|
|
45
|
+
|
|
46
|
+
def optional_belongs_to? exp
|
|
47
|
+
return false unless exp.is_a? Array
|
|
48
|
+
|
|
49
|
+
exp.each do |e|
|
|
50
|
+
if hash? e and true? hash_access(e, :optional)
|
|
51
|
+
return true
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
false
|
|
56
|
+
end
|
|
41
57
|
end
|
|
@@ -431,9 +431,12 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
|
431
431
|
match = Sexp.new(:gvar, exp.lhs)
|
|
432
432
|
exp.rhs = process(exp.rhs)
|
|
433
433
|
value = get_rhs(exp)
|
|
434
|
-
value.line = exp.line
|
|
435
434
|
|
|
436
|
-
|
|
435
|
+
if value
|
|
436
|
+
value.line = exp.line
|
|
437
|
+
|
|
438
|
+
set_value match, value
|
|
439
|
+
end
|
|
437
440
|
|
|
438
441
|
exp
|
|
439
442
|
end
|
|
@@ -14,7 +14,7 @@ class Brakeman::ErbTemplateProcessor < Brakeman::TemplateProcessor
|
|
|
14
14
|
|
|
15
15
|
#_erbout is the default output variable for erb
|
|
16
16
|
if node_type? target, :lvar and target.value == :_erbout
|
|
17
|
-
if method == :concat
|
|
17
|
+
if method == :concat or method == :<<
|
|
18
18
|
@inside_concat = true
|
|
19
19
|
exp.arglist = process(exp.arglist)
|
|
20
20
|
@inside_concat = false
|
|
@@ -13,6 +13,7 @@ class Brakeman::LibraryProcessor < Brakeman::BaseProcessor
|
|
|
13
13
|
@alias_processor = Brakeman::AliasProcessor.new tracker
|
|
14
14
|
@current_module = nil
|
|
15
15
|
@current_class = nil
|
|
16
|
+
@intializer_env = nil
|
|
16
17
|
end
|
|
17
18
|
|
|
18
19
|
def process_library src, file_name = nil
|
|
@@ -29,7 +30,14 @@ class Brakeman::LibraryProcessor < Brakeman::BaseProcessor
|
|
|
29
30
|
end
|
|
30
31
|
|
|
31
32
|
def process_defn exp
|
|
32
|
-
exp
|
|
33
|
+
if exp.method_name == :initialize
|
|
34
|
+
@alias_processor.process_safely exp.body_list
|
|
35
|
+
@initializer_env = @alias_processor.only_ivars
|
|
36
|
+
elsif node_type? exp, :defn
|
|
37
|
+
exp = @alias_processor.process_safely exp, @initializer_env
|
|
38
|
+
else
|
|
39
|
+
exp = @alias_processor.process exp
|
|
40
|
+
end
|
|
33
41
|
|
|
34
42
|
if @current_class
|
|
35
43
|
exp.body = process_all! exp.body
|
data/lib/brakeman/version.rb
CHANGED
data/lib/ruby_parser/bm_sexp.rb
CHANGED
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: 4.
|
|
4
|
+
version: 4.2.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:
|
|
12
|
+
date: 2018-02-22 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: minitest
|
|
@@ -31,14 +31,14 @@ dependencies:
|
|
|
31
31
|
requirements:
|
|
32
32
|
- - "~>"
|
|
33
33
|
- !ruby/object:Gem::Version
|
|
34
|
-
version: 3.
|
|
34
|
+
version: 3.11.0
|
|
35
35
|
type: :runtime
|
|
36
36
|
prerelease: false
|
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
|
38
38
|
requirements:
|
|
39
39
|
- - "~>"
|
|
40
40
|
- !ruby/object:Gem::Version
|
|
41
|
-
version: 3.
|
|
41
|
+
version: 3.11.0
|
|
42
42
|
- !ruby/object:Gem::Dependency
|
|
43
43
|
name: sexp_processor
|
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -380,7 +380,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
380
380
|
version: '0'
|
|
381
381
|
requirements: []
|
|
382
382
|
rubyforge_project:
|
|
383
|
-
rubygems_version: 2.
|
|
383
|
+
rubygems_version: 2.7.6
|
|
384
384
|
signing_key:
|
|
385
385
|
specification_version: 4
|
|
386
386
|
summary: Security vulnerability scanner for Ruby on Rails.
|