brakeman 2.1.2 → 2.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.
- data/CHANGES +9 -0
- data/README.md +4 -2
- data/lib/brakeman/app_tree.rb +2 -2
- data/lib/brakeman/checks/check_detailed_exceptions.rb +54 -0
- data/lib/brakeman/checks/check_execute.rb +45 -4
- data/lib/brakeman/checks/check_redirect.rb +7 -1
- data/lib/brakeman/processors/gem_processor.rb +5 -0
- data/lib/brakeman/processors/lib/route_helper.rb +2 -0
- data/lib/brakeman/scanner.rb +2 -2
- data/lib/brakeman/version.rb +1 -1
- data/lib/brakeman/warning_codes.rb +3 -1
- metadata +8 -7
data/CHANGES
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
# 2.2.0
|
2
|
+
|
3
|
+
* Reduce command injection false positives
|
4
|
+
* Use Rails version from Gemfile if it is available
|
5
|
+
* Only add routes with actual names
|
6
|
+
* Ignore redirects to models using friendly_id (AJ Ostrow)
|
7
|
+
* Support scanning Rails engines (Geoffrey Hichborn)
|
8
|
+
* Add check for detailed exceptions in production
|
9
|
+
|
1
10
|
# 2.1.2
|
2
11
|
|
3
12
|
* Do not attempt to load custom Haml filters
|
data/README.md
CHANGED
@@ -29,7 +29,7 @@ Using RubyGems:
|
|
29
29
|
|
30
30
|
gem install brakeman
|
31
31
|
|
32
|
-
Using Bundler, add to development group in Gemfile:
|
32
|
+
Using Bundler, add to development group in Gemfile and set to not be required automatically:
|
33
33
|
|
34
34
|
group :development do
|
35
35
|
gem 'brakeman', :require => false
|
@@ -163,4 +163,6 @@ The default config locations are `./config/brakeman.yml`, `~/.brakeman/config.ym
|
|
163
163
|
|
164
164
|
The `-c` option can be used to specify a configuration file to use.
|
165
165
|
|
166
|
-
# License
|
166
|
+
# License
|
167
|
+
|
168
|
+
see MIT-LICENSE
|
data/lib/brakeman/app_tree.rb
CHANGED
@@ -66,7 +66,7 @@ module Brakeman
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def layout_exists?(name)
|
69
|
-
pattern = "#{@root}/app/views/layouts/#{name}.html.{erb,haml,slim}"
|
69
|
+
pattern = "#{@root}/{engines/*/,}app/views/layouts/#{name}.html.{erb,haml,slim}"
|
70
70
|
!Dir.glob(pattern).empty?
|
71
71
|
end
|
72
72
|
|
@@ -77,7 +77,7 @@ module Brakeman
|
|
77
77
|
private
|
78
78
|
|
79
79
|
def find_paths(directory, extensions = "*.rb")
|
80
|
-
pattern = @root + "
|
80
|
+
pattern = @root + "/{engines/*/,}#{directory}/**/#{extensions}"
|
81
81
|
|
82
82
|
select_files(Dir.glob(pattern).sort)
|
83
83
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'brakeman/checks/base_check'
|
2
|
+
|
3
|
+
# Check for detailed exceptions enabled for production
|
4
|
+
class Brakeman::CheckDetailedExceptions < Brakeman::BaseCheck
|
5
|
+
Brakeman::Checks.add self
|
6
|
+
|
7
|
+
LOCAL_REQUEST = s(:call, s(:call, nil, :request), :local?)
|
8
|
+
|
9
|
+
@description = "Checks for information disclosure displayed via detailed exceptions"
|
10
|
+
|
11
|
+
def run_check
|
12
|
+
check_local_request_config
|
13
|
+
check_detailed_exceptions
|
14
|
+
end
|
15
|
+
|
16
|
+
def check_local_request_config
|
17
|
+
if true? tracker.config[:rails][:consider_all_requests_local]
|
18
|
+
warn :warning_type => "Information Disclosure",
|
19
|
+
:warning_code => :local_request_config,
|
20
|
+
:message => "Detailed exceptions are enabled in production",
|
21
|
+
:confidence => CONFIDENCE[:high],
|
22
|
+
:file => "config/environments/production.rb"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def check_detailed_exceptions
|
27
|
+
tracker.controllers.each do |name, controller|
|
28
|
+
controller[:public].each do |name, method|
|
29
|
+
body = method.body.last
|
30
|
+
next unless body
|
31
|
+
|
32
|
+
if name == :show_detailed_exceptions? and not safe? body
|
33
|
+
if true? body
|
34
|
+
confidence = CONFIDENCE[:high]
|
35
|
+
else
|
36
|
+
confidence = CONFIDENCE[:med]
|
37
|
+
end
|
38
|
+
|
39
|
+
warn :warning_type => "Information Disclosure",
|
40
|
+
:warning_code => :detailed_exceptions,
|
41
|
+
:message => "Detailed exceptions may be enabled in 'show_detailed_exceptions?'",
|
42
|
+
:confidence => confidence,
|
43
|
+
:code => method,
|
44
|
+
:file => controller[:file]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def safe? body
|
51
|
+
false? body or
|
52
|
+
body == LOCAL_REQUEST
|
53
|
+
end
|
54
|
+
end
|
@@ -13,6 +13,10 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
|
|
13
13
|
|
14
14
|
@description = "Finds instances of possible command injection"
|
15
15
|
|
16
|
+
SAFE_VALUES = [s(:const, :RAILS_ROOT),
|
17
|
+
s(:call, s(:const, :Rails), :root),
|
18
|
+
s(:call, s(:const, :Rails), :env)]
|
19
|
+
|
16
20
|
#Check models, controllers, and views for command injection.
|
17
21
|
def run_check
|
18
22
|
Brakeman.debug "Finding system calls using ``"
|
@@ -38,9 +42,9 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
|
|
38
42
|
|
39
43
|
case call.method
|
40
44
|
when :system, :exec
|
41
|
-
failure = include_user_input?(first_arg) ||
|
45
|
+
failure = include_user_input?(first_arg) || dangerous_interp?(first_arg)
|
42
46
|
else
|
43
|
-
failure = include_user_input?(args) ||
|
47
|
+
failure = include_user_input?(args) || dangerous_interp?(args)
|
44
48
|
end
|
45
49
|
|
46
50
|
if failure and not duplicate? result
|
@@ -82,9 +86,11 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
|
|
82
86
|
if input = include_user_input?(exp)
|
83
87
|
confidence = CONFIDENCE[:high]
|
84
88
|
user_input = input.match
|
85
|
-
|
89
|
+
elsif input = dangerous?(exp)
|
86
90
|
confidence = CONFIDENCE[:med]
|
87
|
-
user_input =
|
91
|
+
user_input = input
|
92
|
+
else
|
93
|
+
return
|
88
94
|
end
|
89
95
|
|
90
96
|
warn :result => result,
|
@@ -95,4 +101,39 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
|
|
95
101
|
:user_input => user_input,
|
96
102
|
:confidence => confidence
|
97
103
|
end
|
104
|
+
|
105
|
+
def dangerous? exp
|
106
|
+
exp.each_sexp do |e|
|
107
|
+
next if node_type? e, :lit, :str
|
108
|
+
next if SAFE_VALUES.include? e
|
109
|
+
|
110
|
+
if call? e and e.method == :to_s
|
111
|
+
e = e.target
|
112
|
+
end
|
113
|
+
|
114
|
+
if node_type? e, :or, :evstr, :string_eval, :string_interp
|
115
|
+
if res = dangerous?(e)
|
116
|
+
return res
|
117
|
+
end
|
118
|
+
else
|
119
|
+
return e
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
false
|
124
|
+
end
|
125
|
+
|
126
|
+
def dangerous_interp? exp
|
127
|
+
match = include_interp? exp
|
128
|
+
return unless match
|
129
|
+
interp = match.match
|
130
|
+
|
131
|
+
interp.each_sexp do |e|
|
132
|
+
if res = dangerous?(e)
|
133
|
+
return Match.new(:interp, res)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
false
|
138
|
+
end
|
98
139
|
end
|
@@ -128,7 +128,7 @@ class Brakeman::CheckRedirect < Brakeman::BaseCheck
|
|
128
128
|
if node_type? exp, :or
|
129
129
|
model_instance? exp.lhs or model_instance? exp.rhs
|
130
130
|
elsif call? exp
|
131
|
-
if model_name? exp.target and
|
131
|
+
if model_name? exp.target or friendly_model? exp.target and
|
132
132
|
(@model_find_calls.include? exp.method or exp.method.to_s.match(/^find_by_/))
|
133
133
|
true
|
134
134
|
else
|
@@ -137,6 +137,12 @@ class Brakeman::CheckRedirect < Brakeman::BaseCheck
|
|
137
137
|
end
|
138
138
|
end
|
139
139
|
|
140
|
+
#Returns true if exp is (probably) a friendly model instance
|
141
|
+
#using the FriendlyId gem
|
142
|
+
def friendly_model? exp
|
143
|
+
call? exp and model_name? exp.target and exp.method == :friendly
|
144
|
+
end
|
145
|
+
|
140
146
|
#Returns true if exp is (probably) a decorated model instance
|
141
147
|
#using the Draper gem
|
142
148
|
def decorated_model? exp
|
@@ -19,6 +19,11 @@ class Brakeman::GemProcessor < Brakeman::BaseProcessor
|
|
19
19
|
@tracker.config[:rails_version] = $1
|
20
20
|
end
|
21
21
|
|
22
|
+
if @tracker.config[:rails_version] =~ /^(3|4)\./ and not @tracker.options[:rails3]
|
23
|
+
@tracker.options[:rails3] = true
|
24
|
+
Brakeman.notify "[Notice] Detected Rails #$1 application"
|
25
|
+
end
|
26
|
+
|
22
27
|
if @tracker.config[:gems][:rails_xss]
|
23
28
|
@tracker.config[:escape_html] = true
|
24
29
|
|
data/lib/brakeman/scanner.rb
CHANGED
@@ -47,10 +47,10 @@ class Brakeman::Scanner
|
|
47
47
|
|
48
48
|
#Process everything in the Rails application
|
49
49
|
def process
|
50
|
-
Brakeman.notify "Processing configuration..."
|
51
|
-
process_config
|
52
50
|
Brakeman.notify "Processing gems..."
|
53
51
|
process_gems
|
52
|
+
Brakeman.notify "Processing configuration..."
|
53
|
+
process_config
|
54
54
|
Brakeman.notify "Processing initializers..."
|
55
55
|
process_initializers
|
56
56
|
Brakeman.notify "Processing libs..."
|
data/lib/brakeman/version.rb
CHANGED
@@ -60,7 +60,9 @@ module Brakeman::WarningCodes
|
|
60
60
|
:CVE_2013_1856 => 57,
|
61
61
|
:CVE_2013_1857 => 58,
|
62
62
|
:unsafe_symbol_creation => 59,
|
63
|
-
:dangerous_attr_accessible => 60
|
63
|
+
:dangerous_attr_accessible => 60,
|
64
|
+
:local_request_config => 61,
|
65
|
+
:detailed_exceptions => 62
|
64
66
|
}
|
65
67
|
|
66
68
|
def self.code name
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: brakeman
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 7
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 2
|
8
|
-
- 1
|
9
8
|
- 2
|
10
|
-
|
9
|
+
- 0
|
10
|
+
version: 2.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Justin Collins
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2013-
|
18
|
+
date: 2013-10-28 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: ruby_parser
|
@@ -87,12 +87,12 @@ dependencies:
|
|
87
87
|
requirements:
|
88
88
|
- - ~>
|
89
89
|
- !ruby/object:Gem::Version
|
90
|
-
hash:
|
90
|
+
hash: 39
|
91
91
|
segments:
|
92
92
|
- 1
|
93
93
|
- 6
|
94
|
-
-
|
95
|
-
version: 1.6.
|
94
|
+
- 20
|
95
|
+
version: 1.6.20
|
96
96
|
type: :runtime
|
97
97
|
version_requirements: *id005
|
98
98
|
- !ruby/object:Gem::Dependency
|
@@ -235,6 +235,7 @@ files:
|
|
235
235
|
- lib/brakeman/warning_codes.rb
|
236
236
|
- lib/brakeman/app_tree.rb
|
237
237
|
- lib/brakeman/checks/check_select_vulnerability.rb
|
238
|
+
- lib/brakeman/checks/check_detailed_exceptions.rb
|
238
239
|
- lib/brakeman/checks/check_escape_function.rb
|
239
240
|
- lib/brakeman/checks/check_single_quotes.rb
|
240
241
|
- lib/brakeman/checks/check_model_serialize.rb
|