brakeman 1.6.1 → 1.6.2

Sign up to get free protection for your applications and to get access to all the features.
data/bin/brakeman CHANGED
@@ -53,7 +53,7 @@ trap("INT") do
53
53
  end
54
54
 
55
55
  if options[:previous_results_json]
56
- vulns = Brakeman.compare options
56
+ vulns = Brakeman.compare options.merge(:quiet => options[:quiet])
57
57
  puts JSON.pretty_generate(vulns)
58
58
  else
59
59
  #Run scan and output a report
@@ -13,6 +13,12 @@ class Brakeman::CheckRedirect < Brakeman::BaseCheck
13
13
  def run_check
14
14
  Brakeman.debug "Finding calls to redirect_to()"
15
15
 
16
+ @model_find_calls = Set[:all, :find, :find_by_sql, :first, :last, :new]
17
+
18
+ if tracker.options[:rails3]
19
+ @model_find_calls.merge [:from, :group, :having, :joins, :lock, :order, :reorder, :select, :where]
20
+ end
21
+
16
22
  @tracker.find_call(:target => false, :method => :redirect_to).each do |res|
17
23
  process_result res
18
24
  end
@@ -50,20 +56,19 @@ class Brakeman::CheckRedirect < Brakeman::BaseCheck
50
56
  def include_user_input? call
51
57
  Brakeman.debug "Checking if call includes user input"
52
58
 
53
- if tracker.options[:ignore_redirect_to_model] and call? call[3][1] and
54
- call[3][1][2] == :new and call[3][1][1]
59
+ args = call[3]
55
60
 
56
- begin
57
- target = class_name call[3][1][1]
58
- if @tracker.models.include? target
59
- return false
60
- end
61
- rescue
62
- end
61
+ if tracker.options[:ignore_redirect_to_model] and call? args[1] and
62
+ (@model_find_calls.include? args[1][2] or args[1][2].to_s.match(/^find_by_/)) and
63
+ model_name? args[1][1]
64
+
65
+ return false
63
66
  end
64
67
 
65
- call[3].each do |arg|
66
- if call? arg
68
+ args.each do |arg|
69
+ if res = has_immediate_model?(arg)
70
+ return Match.new(:immediate, res)
71
+ elsif call? arg
67
72
  if request_value? arg
68
73
  return Match.new(:immediate, arg)
69
74
  elsif request_value? arg[1]
@@ -37,6 +37,15 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
37
37
  Brakeman.debug "Finding calls to named_scope or scope"
38
38
  calls.concat find_scope_calls
39
39
 
40
+ Brakeman.debug "Checking version of Rails for CVE-2012-2660"
41
+ check_rails_version_for_cve_2012_2660
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
+
40
49
  Brakeman.debug "Processing possible SQL calls"
41
50
  calls.each do |c|
42
51
  process_result c
@@ -80,6 +89,33 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
80
89
  scope_calls
81
90
  end
82
91
 
92
+ def check_rails_version_for_cve_2012_2660
93
+ if version_between?("2.0.0", "3.0.0") || version_between?("3.0.0", "3.0.12") || version_between?("3.1.0", "3.1.4") || version_between?("3.2.0", "3.2.3")
94
+ warn :warning_type => 'SQL Injection',
95
+ :message => 'All versions of Rails before 3.0.13, 3.1.5, and 3.2.5 contain a SQL Query Generation Vulnerability: CVE-2012-2660; Upgrade to 3.2.5, 3.1.5, 3.0.13',
96
+ :confidence => CONFIDENCE[:high],
97
+ :file => gemfile_or_environment
98
+ end
99
+ end
100
+
101
+ def check_rails_version_for_cve_2012_2661
102
+ if version_between?("3.0.0", "3.0.12") || version_between?("3.1.0", "3.1.4") || version_between?("3.2.0", "3.2.3")
103
+ warn :warning_type => 'SQL Injection',
104
+ :message => 'All versions of Rails before 3.0.13, 3.1.5, and 3.2.5 contain a SQL Injection Vulnerability: CVE-2012-2661; Upgrade to 3.2.5, 3.1.5, 3.0.13',
105
+ :confidence => CONFIDENCE[:high],
106
+ :file => gemfile_or_environment
107
+ end
108
+ end
109
+
110
+ def check_rails_version_for_cve_2012_2695
111
+ if version_between?("2.0.0", "3.0.0") || version_between?("3.0.0", "3.0.13") || version_between?("3.1.0", "3.1.5") || version_between?("3.2.0", "3.2.5")
112
+ warn :warning_type => 'SQL Injection',
113
+ :message => 'All versions of Rails before 3.0.14, 3.1.6, and 3.2.6 contain SQL Injection Vulnerabilities: CVE-2012-2694 and CVE-2012-2695; Upgrade to 3.2.6, 3.1.6, 3.0.14',
114
+ :confidence => CONFIDENCE[:high],
115
+ :file => gemfile_or_environment
116
+ end
117
+ end
118
+
83
119
  def process_scope_with_block model_name, args
84
120
  scope_name = args[1][1]
85
121
  block = args[-1][-1]
@@ -219,17 +219,25 @@ class Brakeman::ControllerAliasProcessor < Brakeman::AliasProcessor
219
219
 
220
220
  #Returns an array of filter names
221
221
  def get_before_filters method, controller
222
+ return [] unless controller[:options] and controller[:options][:before_filters]
223
+
222
224
  filters = []
223
- return filters unless controller[:options]
224
- filter_list = controller[:options][:before_filters]
225
- return filters unless filter_list
226
225
 
227
- filter_list.each do |filter|
228
- f = before_filter_to_hash filter
226
+ if controller[:before_filter_cache].nil?
227
+ filter_cache = []
228
+
229
+ controller[:options][:before_filters].each do |filter|
230
+ filter_cache << before_filter_to_hash(filter)
231
+ end
232
+
233
+ controller[:before_filter_cache] = filter_cache
234
+ end
235
+
236
+ controller[:before_filter_cache].each do |f|
229
237
  if f[:all] or
230
238
  (f[:only] == method) or
231
239
  (f[:only].is_a? Array and f[:only].include? method) or
232
- (f[:except] == method) or
240
+ (f[:except].is_a? Symbol and f[:except] != method) or
233
241
  (f[:except].is_a? Array and not f[:except].include? method)
234
242
 
235
243
  filters.concat f[:methods]
@@ -254,7 +262,7 @@ class Brakeman::ControllerAliasProcessor < Brakeman::AliasProcessor
254
262
  filter[:methods] = [args[0][1]]
255
263
 
256
264
  args[1..-1].each do |a|
257
- filter[:methods] << a[1] unless a.node_type == :hash
265
+ filter[:methods] << a[1] if a.node_type == :lit
258
266
  end
259
267
 
260
268
  if args[-1].node_type == :hash
@@ -19,7 +19,7 @@ begin
19
19
  rescue LoadError => e
20
20
  $stderr.puts e.message
21
21
  $stderr.puts "Please install the appropriate dependency."
22
- exit
22
+ exit -1
23
23
  end
24
24
 
25
25
  #Scans the Rails application.
data/lib/brakeman/util.rb CHANGED
@@ -11,6 +11,8 @@ module Brakeman::Util
11
11
 
12
12
  REQUEST_PARAMETERS = Sexp.new(:call, Sexp.new(:call, nil, :request, Sexp.new(:arglist)), :request_parameters, Sexp.new(:arglist))
13
13
 
14
+ REQUEST_PARAMS = Sexp.new(:call, Sexp.new(:call, nil, :request, Sexp.new(:arglist)), :parameters, Sexp.new(:arglist))
15
+
14
16
  REQUEST_ENV = Sexp.new(:call, Sexp.new(:call, nil, :request, Sexp.new(:arglist)), :env, Sexp.new(:arglist))
15
17
 
16
18
  PARAMETERS = Sexp.new(:call, nil, :params, Sexp.new(:arglist))
@@ -19,7 +21,7 @@ module Brakeman::Util
19
21
 
20
22
  SESSION = Sexp.new(:call, nil, :session, Sexp.new(:arglist))
21
23
 
22
- ALL_PARAMETERS = Set[PARAMETERS, QUERY_PARAMETERS, PATH_PARAMETERS, REQUEST_PARAMETERS]
24
+ ALL_PARAMETERS = Set[PARAMETERS, QUERY_PARAMETERS, PATH_PARAMETERS, REQUEST_PARAMETERS, REQUEST_PARAMS]
23
25
 
24
26
  #Convert a string from "something_like_this" to "SomethingLikeThis"
25
27
  #
@@ -1,3 +1,3 @@
1
1
  module Brakeman
2
- Version = "1.6.1"
2
+ Version = "1.6.2"
3
3
  end
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: 13
4
+ hash: 11
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 6
9
- - 1
10
- version: 1.6.1
9
+ - 2
10
+ version: 1.6.2
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: 2012-05-23 00:00:00 Z
18
+ date: 2012-06-13 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: activesupport
@@ -202,7 +202,6 @@ files:
202
202
  - lib/brakeman/warning.rb
203
203
  - lib/brakeman/differ.rb
204
204
  - lib/brakeman/processors/gem_processor.rb
205
- - lib/brakeman/processors/params_processor.rb
206
205
  - lib/brakeman/processors/controller_alias_processor.rb
207
206
  - lib/brakeman/processors/base_processor.rb
208
207
  - lib/brakeman/processors/controller_processor.rb
@@ -1,76 +0,0 @@
1
- require 'sexp_processor'
2
- require 'set'
3
-
4
- #Looks for request parameters. Not used currently.
5
- class Brakeman::ParamsProcessor < SexpProcessor
6
- attr_reader :result
7
-
8
- def initialize
9
- super()
10
- self.strict = false
11
- self.auto_shift_type = false
12
- self.require_empty = false
13
- self.default_method = :process_default
14
- self.warn_on_default = false
15
- @result = []
16
- @matched = false
17
- @mark = false
18
- @watch_nodes = Set[:call, :iasgn, :lasgn, :gasgn, :cvasgn, :return, :attrasgn]
19
- @params = Sexp.new(:call, nil, :params, Sexp.new(:arglist))
20
- end
21
-
22
- def process_default exp
23
- if @watch_nodes.include?(exp.node_type) and not @mark
24
- @mark = true
25
- @matched = false
26
- process_these exp[1..-1]
27
- if @matched
28
- @result << exp
29
- @matched = false
30
- end
31
- @mark = false
32
- else
33
- process_these exp[1..-1]
34
- end
35
-
36
- exp
37
- end
38
-
39
- def process_these exp
40
- exp.each do |e|
41
- if sexp? e and not e.empty?
42
- process e
43
- end
44
- end
45
- end
46
-
47
- def process_call exp
48
- if @mark
49
- actually_process_call exp
50
- else
51
- @mark = true
52
- actually_process_call exp
53
- if @matched
54
- @result << exp
55
- end
56
- @mark = @matched = false
57
- end
58
-
59
- exp
60
- end
61
-
62
- def actually_process_call exp
63
- process exp[1]
64
- process exp[3]
65
- if exp[1] == @params or exp == @params
66
- @matched = true
67
- end
68
- end
69
-
70
- #Don't really care about condition
71
- def process_if exp
72
- process_these exp[2..-1]
73
- exp
74
- end
75
-
76
- end