brakeman-min 3.2.1 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES +18 -0
- data/bin/brakeman +1 -1
- data/lib/brakeman.rb +9 -1
- data/lib/brakeman/call_index.rb +1 -1
- data/lib/brakeman/checks/check_content_tag.rb +1 -1
- data/lib/brakeman/checks/check_cross_site_scripting.rb +1 -1
- data/lib/brakeman/checks/check_execute.rb +4 -0
- data/lib/brakeman/checks/check_forgery_setting.rb +3 -2
- data/lib/brakeman/checks/check_link_to.rb +1 -1
- data/lib/brakeman/checks/check_link_to_href.rb +2 -2
- data/lib/brakeman/checks/check_mass_assignment.rb +1 -1
- data/lib/brakeman/checks/check_redirect.rb +6 -0
- data/lib/brakeman/checks/check_secrets.rb +40 -0
- data/lib/brakeman/checks/check_sql.rb +1 -1
- data/lib/brakeman/processor.rb +6 -6
- data/lib/brakeman/processors/alias_processor.rb +29 -3
- data/lib/brakeman/processors/base_processor.rb +35 -4
- data/lib/brakeman/processors/controller_alias_processor.rb +4 -4
- data/lib/brakeman/processors/haml_template_processor.rb +1 -1
- data/lib/brakeman/processors/lib/basic_processor.rb +18 -0
- data/lib/brakeman/processors/lib/rails2_config_processor.rb +3 -2
- data/lib/brakeman/processors/lib/rails2_route_processor.rb +2 -1
- data/lib/brakeman/processors/lib/rails3_config_processor.rb +3 -2
- data/lib/brakeman/processors/lib/rails3_route_processor.rb +2 -1
- data/lib/brakeman/processors/template_alias_processor.rb +4 -4
- data/lib/brakeman/processors/template_processor.rb +1 -0
- data/lib/brakeman/report/report_codeclimate.rb +2 -1
- data/lib/brakeman/scanner.rb +1 -1
- data/lib/brakeman/tracker.rb +11 -1
- data/lib/brakeman/tracker/constants.rb +101 -0
- data/lib/brakeman/util.rb +4 -0
- data/lib/brakeman/version.rb +1 -1
- data/lib/brakeman/warning_codes.rb +1 -0
- data/lib/ruby_parser/bm_sexp.rb +6 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bfbe9bf6ab37921809b33145342e4bcd6df55e8e
|
4
|
+
data.tar.gz: 62f41f3c6a63e4f1b9c662b28779cb821d60a7b9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3724d2c9aad208a2c5197decc4e72e46e9306a7745aaecdd6326bb8357367941b6f14586163bab5e299928cec1acb1d4f994f884441b78f521580cc0b26cbbcf
|
7
|
+
data.tar.gz: 26f0ab2c6871b2a304773c7d93c1b25e2958adef16f97d96257a39ba8cf1c085c1451e5180754e2ae18f197b7b5efc2370e081bd21ec6cb2ab17bb9bc554321d
|
data/CHANGES
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
# 3.3.0
|
2
|
+
|
3
|
+
* Skip processing obviously false if branches (more broadly)
|
4
|
+
* Skip if branches with `Rails.env.test?`
|
5
|
+
* Return exit code `4` if no Rails application is detected
|
6
|
+
* Avoid warning about mass assignment with `params.slice`
|
7
|
+
* Avoid warning about `u` helper (Chad Dollins)
|
8
|
+
* Add optional check for secrets in source code
|
9
|
+
* Process `Array#first`
|
10
|
+
* Allow non-Hash arguments in `protect_from_forgery` (Jason Yeo)
|
11
|
+
* Avoid warning on `popen` with array
|
12
|
+
* Bundle all dependencies in gem
|
13
|
+
* Track constants globally
|
14
|
+
* Handle HAML `find_and_preserve` with a block
|
15
|
+
* [Code Climate engine] When possible, output to /dev/stdout (Gordon Diggs)
|
16
|
+
* [Code Climate engine] Remove nil entries from include_paths (Gordon Diggs)
|
17
|
+
* [Code Climate engine] Report end lines for issues (Gordon Diggs)
|
18
|
+
|
1
19
|
# 3.2.1
|
2
20
|
|
3
21
|
* Remove `multi_json` dependency from `bin/brakeman`
|
data/bin/brakeman
CHANGED
data/lib/brakeman.rb
CHANGED
@@ -1,12 +1,20 @@
|
|
1
|
-
require 'rubygems'
|
2
1
|
require 'set'
|
3
2
|
|
3
|
+
path_load = "#{File.expand_path(File.dirname(__FILE__))}/../bundle/load.rb"
|
4
|
+
|
5
|
+
if File.exist? path_load
|
6
|
+
require path_load
|
7
|
+
end
|
8
|
+
|
4
9
|
module Brakeman
|
5
10
|
|
6
11
|
#This exit code is used when warnings are found and the --exit-on-warn
|
7
12
|
#option is set
|
8
13
|
Warnings_Found_Exit_Code = 3
|
9
14
|
|
15
|
+
#Exit code returned when no Rails application is detected
|
16
|
+
No_App_Found_Exit_Code = 4
|
17
|
+
|
10
18
|
@debug = false
|
11
19
|
@quiet = false
|
12
20
|
@loaded_dependencies = []
|
data/lib/brakeman/call_index.rb
CHANGED
@@ -53,7 +53,7 @@ class Brakeman::CallIndex
|
|
53
53
|
elsif method
|
54
54
|
calls = calls_by_method method
|
55
55
|
else
|
56
|
-
|
56
|
+
raise "Invalid arguments to CallCache#find_calls: #{options.inspect}"
|
57
57
|
end
|
58
58
|
|
59
59
|
return [] if calls.nil?
|
@@ -24,7 +24,7 @@ class Brakeman::CheckContentTag < Brakeman::CheckCrossSiteScripting
|
|
24
24
|
:hidden_field, :hidden_field_tag, :image_tag, :label,
|
25
25
|
:mail_to, :radio_button, :select,
|
26
26
|
:submit_tag, :text_area, :text_field,
|
27
|
-
:text_field_tag, :url_encode, :url_for,
|
27
|
+
:text_field_tag, :url_encode, :u, :url_for,
|
28
28
|
:will_paginate].merge tracker.options[:safe_methods]
|
29
29
|
|
30
30
|
@known_dangerous = []
|
@@ -286,7 +286,7 @@ class Brakeman::CheckCrossSiteScripting < Brakeman::BaseCheck
|
|
286
286
|
:hidden_field, :hidden_field_tag, :image_tag, :label,
|
287
287
|
:link_to, :mail_to, :radio_button, :select,
|
288
288
|
:submit_tag, :text_area, :text_field,
|
289
|
-
:text_field_tag, :url_encode, :url_for,
|
289
|
+
:text_field_tag, :url_encode, :u, :url_for,
|
290
290
|
:will_paginate].merge tracker.options[:safe_methods]
|
291
291
|
|
292
292
|
@models = tracker.models.keys
|
@@ -43,6 +43,10 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
|
|
43
43
|
first_arg = call.first_arg
|
44
44
|
|
45
45
|
case call.method
|
46
|
+
when :popen
|
47
|
+
unless array? first_arg
|
48
|
+
failure = include_user_input?(args) || dangerous_interp?(args)
|
49
|
+
end
|
46
50
|
when :system, :exec
|
47
51
|
failure = include_user_input?(first_arg) || dangerous_interp?(first_arg)
|
48
52
|
else
|
@@ -13,7 +13,7 @@ class Brakeman::CheckForgerySetting < Brakeman::BaseCheck
|
|
13
13
|
app_controller = tracker.controllers[:ApplicationController]
|
14
14
|
return unless app_controller and app_controller.ancestor? :"ActionController::Base"
|
15
15
|
|
16
|
-
if tracker.config.allow_forgery_protection?
|
16
|
+
if tracker.config.allow_forgery_protection?
|
17
17
|
warn :controller => :ApplicationController,
|
18
18
|
:warning_type => "Cross-Site Request Forgery",
|
19
19
|
:warning_code => :csrf_protection_disabled,
|
@@ -53,7 +53,8 @@ class Brakeman::CheckForgerySetting < Brakeman::BaseCheck
|
|
53
53
|
elsif version_between? "4.0.0", "100.0.0" and forgery_opts = app_controller.options[:protect_from_forgery]
|
54
54
|
|
55
55
|
unless forgery_opts.is_a?(Array) and sexp?(forgery_opts.first) and
|
56
|
-
access_arg = hash_access(forgery_opts.first.first_arg, :with) and access_arg
|
56
|
+
access_arg = hash_access(forgery_opts.first.first_arg, :with) and symbol? access_arg and
|
57
|
+
access_arg.value == :exception
|
57
58
|
|
58
59
|
args = {
|
59
60
|
:controller => :ApplicationController,
|
@@ -17,7 +17,7 @@ class Brakeman::CheckLinkTo < Brakeman::CheckCrossSiteScripting
|
|
17
17
|
:hidden_field, :hidden_field_tag, :image_tag, :label,
|
18
18
|
:mail_to, :radio_button, :select,
|
19
19
|
:submit_tag, :text_area, :text_field,
|
20
|
-
:text_field_tag, :url_encode, :url_for,
|
20
|
+
:text_field_tag, :url_encode, :u, :url_for,
|
21
21
|
:will_paginate].merge tracker.options[:safe_methods]
|
22
22
|
|
23
23
|
@known_dangerous = []
|
@@ -15,9 +15,9 @@ class Brakeman::CheckLinkToHref < Brakeman::CheckLinkTo
|
|
15
15
|
@ignore_methods = Set[:button_to, :check_box,
|
16
16
|
:field_field, :fields_for, :hidden_field,
|
17
17
|
:hidden_field, :hidden_field_tag, :image_tag, :label,
|
18
|
-
:mail_to, :polymorphic_url, :radio_button, :select,
|
18
|
+
:mail_to, :polymorphic_url, :radio_button, :select, :slice,
|
19
19
|
:submit_tag, :text_area, :text_field,
|
20
|
-
:text_field_tag, :url_encode, :url_for,
|
20
|
+
:text_field_tag, :url_encode, :u, :url_for,
|
21
21
|
:will_paginate].merge(tracker.options[:url_safe_methods] || [])
|
22
22
|
|
23
23
|
@models = tracker.models.keys
|
@@ -160,7 +160,7 @@ class Brakeman::CheckMassAssignment < Brakeman::BaseCheck
|
|
160
160
|
# Look for and warn about uses of Parameters#permit! for mass assignment
|
161
161
|
def check_permit!
|
162
162
|
tracker.find_call(:method => :permit!).each do |result|
|
163
|
-
if params? result[:call].target
|
163
|
+
if params? result[:call].target and not result[:chain].include? :slice
|
164
164
|
warn_on_permit! result
|
165
165
|
end
|
166
166
|
end
|
@@ -38,6 +38,7 @@ class Brakeman::CheckRedirect < Brakeman::BaseCheck
|
|
38
38
|
if method == :redirect_to and
|
39
39
|
not only_path?(call) and
|
40
40
|
not explicit_host?(call.first_arg) and
|
41
|
+
not slice_call?(call.first_arg) and
|
41
42
|
res = include_user_input?(call)
|
42
43
|
|
43
44
|
add_result result
|
@@ -206,4 +207,9 @@ class Brakeman::CheckRedirect < Brakeman::BaseCheck
|
|
206
207
|
|
207
208
|
model.association? meth
|
208
209
|
end
|
210
|
+
|
211
|
+
def slice_call? exp
|
212
|
+
return unless call? exp
|
213
|
+
exp.method == :slice
|
214
|
+
end
|
209
215
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'brakeman/checks/base_check'
|
2
|
+
|
3
|
+
class Brakeman::CheckSecrets < Brakeman::BaseCheck
|
4
|
+
Brakeman::Checks.add_optional self
|
5
|
+
|
6
|
+
@description = "Checks for secrets stored in source code"
|
7
|
+
|
8
|
+
def run_check
|
9
|
+
check_constants
|
10
|
+
end
|
11
|
+
|
12
|
+
def check_constants
|
13
|
+
@warned = Set.new
|
14
|
+
|
15
|
+
@tracker.constants.each do |constant|
|
16
|
+
name = constant.name.last
|
17
|
+
value = constant.value
|
18
|
+
|
19
|
+
if string? value and not value.value.empty? and looks_like_secret? name
|
20
|
+
match = [name, value, value.line]
|
21
|
+
|
22
|
+
unless @warned.include? match
|
23
|
+
@warned << match
|
24
|
+
|
25
|
+
warn :warning_code => :secret_in_source,
|
26
|
+
:warning_type => "Authentication",
|
27
|
+
:message => "Hardcoded value for #{name} in source code",
|
28
|
+
:confidence => CONFIDENCE[:med],
|
29
|
+
:file => constant.file,
|
30
|
+
:line => constant.line
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def looks_like_secret? name
|
37
|
+
# REST_AUTH_SITE_KEY is the pepper in Devise
|
38
|
+
name.match /password|secret|(rest_auth_site|api)_key$/i
|
39
|
+
end
|
40
|
+
end
|
@@ -264,7 +264,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
264
264
|
end
|
265
265
|
|
266
266
|
if request_value? arg
|
267
|
-
unless call? arg and params? arg.target and arg.method
|
267
|
+
unless call? arg and params? arg.target and [:permit, :slice].include? arg.method
|
268
268
|
# Model.where(params[:where])
|
269
269
|
arg
|
270
270
|
end
|
data/lib/brakeman/processor.rb
CHANGED
@@ -22,8 +22,8 @@ module Brakeman
|
|
22
22
|
end
|
23
23
|
|
24
24
|
#Process configuration file source
|
25
|
-
def process_config src
|
26
|
-
ConfigProcessor.new(@tracker).process_config src
|
25
|
+
def process_config src, file_name
|
26
|
+
ConfigProcessor.new(@tracker).process_config src, file_name
|
27
27
|
end
|
28
28
|
|
29
29
|
#Process Gemfile
|
@@ -88,10 +88,10 @@ module Brakeman
|
|
88
88
|
end
|
89
89
|
|
90
90
|
#Process source for initializing files
|
91
|
-
def process_initializer
|
92
|
-
res = BaseProcessor.new(@tracker).
|
93
|
-
res = AliasProcessor.new(@tracker).
|
94
|
-
@tracker.initializers[Pathname.new(
|
91
|
+
def process_initializer file_name, src
|
92
|
+
res = BaseProcessor.new(@tracker).process_file src, file_name
|
93
|
+
res = AliasProcessor.new(@tracker).process_safely res, nil, file_name
|
94
|
+
@tracker.initializers[Pathname.new(file_name).basename.to_s] = res
|
95
95
|
end
|
96
96
|
|
97
97
|
#Process source for a library file
|
@@ -16,7 +16,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
16
16
|
#The recommended usage is:
|
17
17
|
#
|
18
18
|
# AliasProcessor.new.process_safely src
|
19
|
-
def initialize tracker = nil
|
19
|
+
def initialize tracker = nil, file_name = nil
|
20
20
|
super()
|
21
21
|
@env = SexpProcessor::Environment.new
|
22
22
|
@inside_if = false
|
@@ -28,6 +28,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
28
28
|
@helper_method_info = Hash.new({})
|
29
29
|
@or_depth_limit = (tracker && tracker.options[:branch_limit]) || 5 #arbitrary default
|
30
30
|
@meth_env = nil
|
31
|
+
@file_name = file_name
|
31
32
|
set_env_defaults
|
32
33
|
end
|
33
34
|
|
@@ -39,7 +40,8 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
39
40
|
#
|
40
41
|
#This method returns a new Sexp with variables replaced with their values,
|
41
42
|
#where possible.
|
42
|
-
def process_safely src, set_env = nil
|
43
|
+
def process_safely src, set_env = nil, file_name = nil
|
44
|
+
@file_name = file_name
|
43
45
|
@env = set_env || SexpProcessor::Environment.new
|
44
46
|
@result = src.deep_clone
|
45
47
|
process @result
|
@@ -73,8 +75,11 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
73
75
|
def replace exp, int = 0
|
74
76
|
return exp if int > 3
|
75
77
|
|
78
|
+
|
76
79
|
if replacement = env[exp] and not duplicate? replacement
|
77
80
|
replace(replacement.deep_clone(exp.line), int + 1)
|
81
|
+
elsif tracker and replacement = tracker.constant_lookup(exp) and not duplicate? replacement
|
82
|
+
replace(replacement.deep_clone(exp.line), int + 1)
|
78
83
|
else
|
79
84
|
exp
|
80
85
|
end
|
@@ -82,6 +87,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
82
87
|
|
83
88
|
ARRAY_CONST = s(:const, :Array)
|
84
89
|
HASH_CONST = s(:const, :Hash)
|
90
|
+
RAILS_TEST = s(:call, s(:call, s(:const, :Rails), :env), :test?)
|
85
91
|
|
86
92
|
#Process a method call.
|
87
93
|
def process_call exp
|
@@ -110,8 +116,11 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
110
116
|
return Sexp.new(:array, *exp.args)
|
111
117
|
elsif target == HASH_CONST and method == :new and first_arg.nil? and !node_type?(@exp_context.last, :iter)
|
112
118
|
return Sexp.new(:hash)
|
119
|
+
elsif exp == RAILS_TEST
|
120
|
+
return Sexp.new(:false)
|
113
121
|
end
|
114
122
|
|
123
|
+
|
115
124
|
#See if it is possible to simplify some basic cases
|
116
125
|
#of addition/concatenation.
|
117
126
|
case method
|
@@ -204,6 +213,10 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
204
213
|
target = find_push_target(target_var)
|
205
214
|
env[target] = exp unless target.nil? # Happens in TemplateAliasProcessor
|
206
215
|
end
|
216
|
+
when :first
|
217
|
+
if array? target and first_arg.nil? and sexp? target[1]
|
218
|
+
exp = target[1]
|
219
|
+
end
|
207
220
|
end
|
208
221
|
|
209
222
|
exp
|
@@ -504,6 +517,19 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
504
517
|
exp.rhs = process exp.rhs
|
505
518
|
end
|
506
519
|
|
520
|
+
file = case
|
521
|
+
when @file_name
|
522
|
+
@file_name
|
523
|
+
when @current_class.is_a?(Brakeman::Collection)
|
524
|
+
@current_class.file
|
525
|
+
when @current_module.is_a?(Brakeman::Collection)
|
526
|
+
@current_module.file
|
527
|
+
else
|
528
|
+
nil
|
529
|
+
end
|
530
|
+
|
531
|
+
@tracker.add_constant exp.lhs, exp.rhs, :file => file if @tracker
|
532
|
+
|
507
533
|
if exp.lhs.is_a? Symbol
|
508
534
|
match = Sexp.new(:const, exp.lhs)
|
509
535
|
else
|
@@ -543,7 +569,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
543
569
|
@ignore_ifs = @tracker && @tracker.options[:ignore_ifs]
|
544
570
|
end
|
545
571
|
|
546
|
-
condition = process exp.condition
|
572
|
+
condition = exp.condition = process exp.condition
|
547
573
|
|
548
574
|
#Check if a branch is obviously going to be taken
|
549
575
|
if true? condition
|
@@ -13,7 +13,12 @@ class Brakeman::BaseProcessor < Brakeman::SexpProcessor
|
|
13
13
|
super()
|
14
14
|
@last = nil
|
15
15
|
@tracker = tracker
|
16
|
-
@current_template = @current_module = @current_class = @current_method = nil
|
16
|
+
@current_template = @current_module = @current_class = @current_method = @file_name = nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def process_file exp, file_name
|
20
|
+
@file_name = file_name
|
21
|
+
process exp
|
17
22
|
end
|
18
23
|
|
19
24
|
def ignore
|
@@ -43,9 +48,19 @@ class Brakeman::BaseProcessor < Brakeman::SexpProcessor
|
|
43
48
|
#Process an if statement.
|
44
49
|
def process_if exp
|
45
50
|
exp = exp.dup
|
46
|
-
exp[1] = process exp.condition
|
47
|
-
|
48
|
-
|
51
|
+
condition = exp[1] = process exp.condition
|
52
|
+
|
53
|
+
if true? condition
|
54
|
+
exp[2] = process exp.then_clause if exp.then_clause
|
55
|
+
exp[3] = nil
|
56
|
+
elsif false? condition
|
57
|
+
exp[2] = nil
|
58
|
+
exp[3] = process exp.else_clause if exp.else_clause
|
59
|
+
else
|
60
|
+
exp[2] = process exp.then_clause if exp.then_clause
|
61
|
+
exp[3] = process exp.else_clause if exp.else_clause
|
62
|
+
end
|
63
|
+
|
49
64
|
exp
|
50
65
|
end
|
51
66
|
|
@@ -173,6 +188,22 @@ class Brakeman::BaseProcessor < Brakeman::SexpProcessor
|
|
173
188
|
exp
|
174
189
|
end
|
175
190
|
|
191
|
+
def process_cdecl exp
|
192
|
+
file = case
|
193
|
+
when @file_name
|
194
|
+
@file_name
|
195
|
+
when @current_class.is_a?(Brakeman::Collection)
|
196
|
+
@current_class.file
|
197
|
+
when @current_module.is_a?(Brakeman::Collection)
|
198
|
+
@current_module.file
|
199
|
+
else
|
200
|
+
nil
|
201
|
+
end
|
202
|
+
|
203
|
+
@tracker.add_constant exp.lhs, exp.rhs, :file => file if @tracker
|
204
|
+
exp
|
205
|
+
end
|
206
|
+
|
176
207
|
#Convenience method for `make_render exp, true`
|
177
208
|
def make_render_in_view exp
|
178
209
|
make_render exp, true
|
@@ -20,13 +20,13 @@ class Brakeman::ControllerAliasProcessor < Brakeman::AliasProcessor
|
|
20
20
|
@method_cache = {} #Cache method lookups
|
21
21
|
end
|
22
22
|
|
23
|
-
def process_controller name, src,
|
23
|
+
def process_controller name, src, file_name
|
24
24
|
if not node_type? src, :class
|
25
25
|
Brakeman.debug "#{name} is not a class, it's a #{src.node_type}"
|
26
26
|
return
|
27
27
|
else
|
28
28
|
@current_class = name
|
29
|
-
@
|
29
|
+
@file_name = file_name
|
30
30
|
|
31
31
|
process_default src
|
32
32
|
|
@@ -59,7 +59,7 @@ class Brakeman::ControllerAliasProcessor < Brakeman::AliasProcessor
|
|
59
59
|
method = processor.process method
|
60
60
|
end
|
61
61
|
|
62
|
-
@
|
62
|
+
@file_name = mixin.file
|
63
63
|
#Then process it like any other method in the controller
|
64
64
|
process method
|
65
65
|
end
|
@@ -182,7 +182,7 @@ class Brakeman::ControllerAliasProcessor < Brakeman::AliasProcessor
|
|
182
182
|
end
|
183
183
|
end
|
184
184
|
|
185
|
-
render_path = Brakeman::RenderPath.new.add_controller_render(@current_class, @current_method, line, relative_path(@
|
185
|
+
render_path = Brakeman::RenderPath.new.add_controller_render(@current_class, @current_method, line, relative_path(@file_name))
|
186
186
|
super name, args, render_path, line
|
187
187
|
end
|
188
188
|
|
@@ -88,7 +88,7 @@ class Brakeman::HamlTemplateProcessor < Brakeman::TemplateProcessor
|
|
88
88
|
#Process call to render()
|
89
89
|
exp.arglist = process exp.arglist
|
90
90
|
make_render_in_view exp
|
91
|
-
elsif target == nil and method == :find_and_preserve
|
91
|
+
elsif target == nil and method == :find_and_preserve and exp.first_arg
|
92
92
|
process exp.first_arg
|
93
93
|
elsif method == :render_with_options
|
94
94
|
if target == JAVASCRIPT_FILTER or target == COFFEE_FILTER
|
@@ -30,4 +30,22 @@ class Brakeman::BasicProcessor < Brakeman::SexpProcessor
|
|
30
30
|
process_default exp
|
31
31
|
end
|
32
32
|
end
|
33
|
+
|
34
|
+
def process_if exp
|
35
|
+
condition = exp.condition
|
36
|
+
|
37
|
+
process condition
|
38
|
+
|
39
|
+
if true? condition
|
40
|
+
process exp.then_clause
|
41
|
+
elsif false? condition
|
42
|
+
process exp.else_clause
|
43
|
+
else
|
44
|
+
[exp.then_clause, exp.else_clause].compact.map do |e|
|
45
|
+
process e
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
exp
|
50
|
+
end
|
33
51
|
end
|
@@ -27,8 +27,9 @@ class Brakeman::Rails2ConfigProcessor < Brakeman::BasicProcessor
|
|
27
27
|
end
|
28
28
|
|
29
29
|
#Use this method to process configuration file
|
30
|
-
def process_config src
|
31
|
-
|
30
|
+
def process_config src, file_name
|
31
|
+
@file_name = file_name
|
32
|
+
res = Brakeman::ConfigAliasProcessor.new.process_safely(src, nil, file_name)
|
32
33
|
process res
|
33
34
|
end
|
34
35
|
|
@@ -16,6 +16,7 @@ class Brakeman::Rails2RoutesProcessor < Brakeman::BasicProcessor
|
|
16
16
|
@prefix = [] #Controller name prefix (a module name, usually)
|
17
17
|
@current_controller = nil
|
18
18
|
@with_options = nil #For use inside map.with_options
|
19
|
+
@file_name = "config/routes.rb"
|
19
20
|
end
|
20
21
|
|
21
22
|
#Call this with parsed route file information.
|
@@ -23,7 +24,7 @@ class Brakeman::Rails2RoutesProcessor < Brakeman::BasicProcessor
|
|
23
24
|
#This method first calls RouteAliasProcessor#process_safely on the +exp+,
|
24
25
|
#so it does not modify the +exp+.
|
25
26
|
def process_routes exp
|
26
|
-
process Brakeman::RouteAliasProcessor.new.process_safely(exp)
|
27
|
+
process Brakeman::RouteAliasProcessor.new.process_safely(exp, nil, @file_name)
|
27
28
|
end
|
28
29
|
|
29
30
|
#Looking for mapping of routes
|
@@ -24,8 +24,9 @@ class Brakeman::Rails3ConfigProcessor < Brakeman::BasicProcessor
|
|
24
24
|
end
|
25
25
|
|
26
26
|
#Use this method to process configuration file
|
27
|
-
def process_config src
|
28
|
-
|
27
|
+
def process_config src, file_name
|
28
|
+
@file_name = file_name
|
29
|
+
res = Brakeman::AliasProcessor.new(@tracker).process_safely(src, nil, @file_name)
|
29
30
|
process res
|
30
31
|
end
|
31
32
|
|
@@ -17,10 +17,11 @@ class Brakeman::Rails3RoutesProcessor < Brakeman::BasicProcessor
|
|
17
17
|
@current_controller = nil
|
18
18
|
@with_options = nil #For use inside map.with_options
|
19
19
|
@controller_block = false
|
20
|
+
@file_name = "config/routes.rb"
|
20
21
|
end
|
21
22
|
|
22
23
|
def process_routes exp
|
23
|
-
process exp
|
24
|
+
process Brakeman::AliasProcessor.new.process_safely(exp, nil, @file_name)
|
24
25
|
end
|
25
26
|
|
26
27
|
def process_call exp
|
@@ -18,8 +18,8 @@ class Brakeman::TemplateAliasProcessor < Brakeman::AliasProcessor
|
|
18
18
|
end
|
19
19
|
|
20
20
|
#Process template
|
21
|
-
def process_template name, args, _, line = nil
|
22
|
-
|
21
|
+
def process_template name, args, _, line = nil, file_name = nil
|
22
|
+
@file_name = file_name || relative_path(@template.file || @tracker.templates[@template.name])
|
23
23
|
|
24
24
|
if @called_from
|
25
25
|
if @called_from.include_template? name
|
@@ -27,9 +27,9 @@ class Brakeman::TemplateAliasProcessor < Brakeman::AliasProcessor
|
|
27
27
|
return
|
28
28
|
end
|
29
29
|
|
30
|
-
super name, args, @called_from.dup.add_template_render(@template.name, line,
|
30
|
+
super name, args, @called_from.dup.add_template_render(@template.name, line, @file_name)
|
31
31
|
else
|
32
|
-
super name, args, Brakeman::RenderPath.new.add_template_render(@template.name, line,
|
32
|
+
super name, args, Brakeman::RenderPath.new.add_template_render(@template.name, line, @file_name)
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
@@ -8,6 +8,7 @@ class Brakeman::TemplateProcessor < Brakeman::BaseProcessor
|
|
8
8
|
def initialize tracker, template_name, called_from = nil, file_name = nil
|
9
9
|
super(tracker)
|
10
10
|
@current_template = Brakeman::Template.new template_name, called_from, file_name, tracker
|
11
|
+
@file_name = file_name
|
11
12
|
|
12
13
|
if called_from
|
13
14
|
template_name = (template_name.to_s + "." + called_from.to_s).to_sym
|
data/lib/brakeman/scanner.rb
CHANGED
data/lib/brakeman/tracker.rb
CHANGED
@@ -5,10 +5,11 @@ require 'brakeman/report'
|
|
5
5
|
require 'brakeman/processors/lib/find_call'
|
6
6
|
require 'brakeman/processors/lib/find_all_calls'
|
7
7
|
require 'brakeman/tracker/config'
|
8
|
+
require 'brakeman/tracker/constants'
|
8
9
|
|
9
10
|
#The Tracker keeps track of all the processed information.
|
10
11
|
class Brakeman::Tracker
|
11
|
-
attr_accessor :controllers, :templates, :models, :errors,
|
12
|
+
attr_accessor :controllers, :constants, :templates, :models, :errors,
|
12
13
|
:checks, :initializers, :config, :routes, :processor, :libs,
|
13
14
|
:template_cache, :options, :filter_cache, :start_time, :end_time,
|
14
15
|
:duration, :ignored_filter
|
@@ -38,6 +39,7 @@ class Brakeman::Tracker
|
|
38
39
|
@initializers = {}
|
39
40
|
@errors = []
|
40
41
|
@libs = {}
|
42
|
+
@constants = Brakeman::Constants.new
|
41
43
|
@checks = nil
|
42
44
|
@processed = nil
|
43
45
|
@template_cache = Set.new
|
@@ -188,6 +190,14 @@ class Brakeman::Tracker
|
|
188
190
|
end
|
189
191
|
end
|
190
192
|
|
193
|
+
def add_constant name, value, context = nil
|
194
|
+
@constants.add name, value, context
|
195
|
+
end
|
196
|
+
|
197
|
+
def constant_lookup name
|
198
|
+
@constants.get_literal name
|
199
|
+
end
|
200
|
+
|
191
201
|
def index_call_sites
|
192
202
|
finder = Brakeman::FindAllCalls.new self
|
193
203
|
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'brakeman/processors/output_processor'
|
2
|
+
|
3
|
+
module Brakeman
|
4
|
+
class Constant
|
5
|
+
attr_reader :name, :file
|
6
|
+
|
7
|
+
def initialize name, value = nil, context = nil
|
8
|
+
set_name name, context
|
9
|
+
@values = [ value ]
|
10
|
+
@context = context
|
11
|
+
|
12
|
+
if @context
|
13
|
+
@file = @context[:file]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def line
|
18
|
+
if @values.first.is_a? Sexp
|
19
|
+
@values.first.line
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def set_name name, context
|
24
|
+
@name = Constants.constant_as_array(name)
|
25
|
+
end
|
26
|
+
|
27
|
+
def match? name
|
28
|
+
@name.reverse.zip(name.reverse).reduce(true) { |m, a| a[1] ? a[0] == a[1] && m : m }
|
29
|
+
end
|
30
|
+
|
31
|
+
def value
|
32
|
+
@values.reverse.reduce do |m, v|
|
33
|
+
Sexp.new(:or, v, m)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def add_value exp
|
38
|
+
unless @values.include? exp
|
39
|
+
@values << exp
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class Constants
|
45
|
+
include Brakeman::Util
|
46
|
+
|
47
|
+
def initialize
|
48
|
+
@constants = []
|
49
|
+
end
|
50
|
+
|
51
|
+
def [] exp
|
52
|
+
return unless constant? exp
|
53
|
+
match = find_constant exp
|
54
|
+
|
55
|
+
if match
|
56
|
+
match.value
|
57
|
+
else
|
58
|
+
nil
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def find_constant exp
|
63
|
+
name = Constants.constant_as_array(exp)
|
64
|
+
@constants.find do |c|
|
65
|
+
c.match? name
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def add name, value, context = nil
|
70
|
+
if existing = self.find_constant(name)
|
71
|
+
existing.add_value value
|
72
|
+
else
|
73
|
+
@constants << Constant.new(name, value, context)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def get_literal name
|
78
|
+
if x = self[name] and [:lit, :false, :str, :true, :array, :hash].include? x.node_type
|
79
|
+
x
|
80
|
+
else
|
81
|
+
nil
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def each &block
|
86
|
+
@constants.each &block
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.constant_as_array exp
|
90
|
+
get_constant_name(exp).split('::')
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.get_constant_name exp
|
94
|
+
if exp.is_a? Sexp
|
95
|
+
Brakeman::OutputProcessor.new.format(exp)
|
96
|
+
else
|
97
|
+
exp.to_s
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
data/lib/brakeman/util.rb
CHANGED
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-min
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.3.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: 2016-
|
12
|
+
date: 2016-05-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: test-unit
|
@@ -130,6 +130,7 @@ files:
|
|
130
130
|
- lib/brakeman/checks/check_route_dos.rb
|
131
131
|
- lib/brakeman/checks/check_safe_buffer_manipulation.rb
|
132
132
|
- lib/brakeman/checks/check_sanitize_methods.rb
|
133
|
+
- lib/brakeman/checks/check_secrets.rb
|
133
134
|
- lib/brakeman/checks/check_select_tag.rb
|
134
135
|
- lib/brakeman/checks/check_select_vulnerability.rb
|
135
136
|
- lib/brakeman/checks/check_send.rb
|
@@ -220,6 +221,7 @@ files:
|
|
220
221
|
- lib/brakeman/tracker.rb
|
221
222
|
- lib/brakeman/tracker/collection.rb
|
222
223
|
- lib/brakeman/tracker/config.rb
|
224
|
+
- lib/brakeman/tracker/constants.rb
|
223
225
|
- lib/brakeman/tracker/controller.rb
|
224
226
|
- lib/brakeman/tracker/library.rb
|
225
227
|
- lib/brakeman/tracker/model.rb
|
@@ -250,7 +252,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
250
252
|
version: '0'
|
251
253
|
requirements: []
|
252
254
|
rubyforge_project:
|
253
|
-
rubygems_version: 2.
|
255
|
+
rubygems_version: 2.5.1
|
254
256
|
signing_key:
|
255
257
|
specification_version: 4
|
256
258
|
summary: Security vulnerability scanner for Ruby on Rails.
|