brakeman 0.6.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ require 'checks/base_check'
2
+ require 'processors/lib/find_call'
3
+
4
+ #Check for versions with vulnerable html escape method
5
+ #http://groups.google.com/group/rubyonrails-security/browse_thread/thread/56bffb5923ab1195
6
+ class CheckEscapeFunction < BaseCheck
7
+ Checks.add self
8
+
9
+ def run_check
10
+ if version_between?('2.0.0', '2.3.13') and RUBY_VERSION < '1.9.0'
11
+
12
+ warn :warning_type => 'Cross Site Scripting',
13
+ :message => 'Versions before 2.3.14 have a vulnerability in escape method when used with Ruby 1.8. Upgrade or apply patches as needed.',
14
+ :confidence => CONFIDENCE[:high]
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,27 @@
1
+ require 'checks/base_check'
2
+ require 'processors/lib/find_call'
3
+
4
+ #Check for filter skipping vulnerability
5
+ #http://groups.google.com/group/rubyonrails-security/browse_thread/thread/3420ac71aed312d6
6
+ class CheckFilterSkipping < BaseCheck
7
+ Checks.add self
8
+
9
+ def run_check
10
+ if version_between?('3.0.0', '3.0.9') and uses_arbitrary_actions?
11
+
12
+ warn :warning_type => "Default Routes",
13
+ :message => "Versions before 3.0.10 have a vulnerability which allows filters to be bypassed. Upgrade or apply patches as needed.",
14
+ :confidence => CONFIDENCE[:high]
15
+ end
16
+ end
17
+
18
+ def uses_arbitrary_actions?
19
+ tracker.routes.each do |name, actions|
20
+ if actions == :allow_all_actions
21
+ return true
22
+ end
23
+ end
24
+
25
+ false
26
+ end
27
+ end
@@ -0,0 +1,34 @@
1
+ require 'checks/base_check'
2
+ require 'processors/lib/find_call'
3
+
4
+ #Check for uses of quote_table_name in Rails versions before 2.3.13 and 3.0.10
5
+ #http://groups.google.com/group/rubyonrails-security/browse_thread/thread/6a1e473744bc389b
6
+ class CheckQuoteTableName < BaseCheck
7
+ Checks.add self
8
+
9
+ def run_check
10
+ if (version_between?('2.0.0', '2.3.13') or
11
+ version_between?('3.0.0', '3.0.9'))
12
+
13
+ if uses_quote_table_name?
14
+ confidence = CONFIDENCE[:high]
15
+ else
16
+ confidence = CONFIDENCE[:med]
17
+ end
18
+
19
+ if tracker.config[:rails_version] =~ /^3/
20
+ message = "Versions before 3.0.10 have a vulnerability in quote_table_name. Upgrade or apply patches as needed."
21
+ else
22
+ message = "Versions before 2.3.14 have a vulnerability in quote_table_name. Upgrade or apply patches as needed."
23
+ end
24
+
25
+ warn :warning_type => "SQL Injection",
26
+ :message => message,
27
+ :confidence => confidence
28
+ end
29
+ end
30
+
31
+ def uses_quote_table_name?
32
+ not tracker.find_call([], :quote_table_name).empty?
33
+ end
34
+ end
@@ -0,0 +1,18 @@
1
+ require 'checks/base_check'
2
+ require 'processors/lib/find_call'
3
+
4
+ #Warn about response splitting in Rails versions before 2.3.13
5
+ #http://groups.google.com/group/rubyonrails-security/browse_thread/thread/6ffc93bde0298768
6
+ class CheckResponseSplitting < BaseCheck
7
+ Checks.add self
8
+
9
+ def run_check
10
+ if version_between?('2.3.0', '2.3.13')
11
+
12
+ warn :warning_type => "Response Splitting",
13
+ :message => "Versions before 2.3.14 have a vulnerability content type handling allowing injection of headers. Upgrade or apply patches as needed.",
14
+ :confidence => CONFIDENCE[:med]
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,28 @@
1
+ require 'checks/base_check'
2
+ require 'processors/lib/find_call'
3
+
4
+ #Checks for uses of strip_tags in Rails versions before 2.3.13 and 3.0.10
5
+ #http://groups.google.com/group/rubyonrails-security/browse_thread/thread/2b9130749b74ea12
6
+ class CheckStripTags < BaseCheck
7
+ Checks.add self
8
+
9
+ def run_check
10
+ if (version_between?('2.0.0', '2.3.12') or
11
+ version_between?('3.0.0', '3.0.9')) and uses_strip_tags?
12
+
13
+ if tracker.config[:rails_version] =~ /^3/
14
+ message = "Versions before 3.0.10 have a vulnerability in strip_tags. Upgrade or apply patches as needed."
15
+ else
16
+ message = "Versions before 2.3.13 have a vulnerability in strip_tags. Upgrade or apply patches as needed."
17
+ end
18
+
19
+ warn :warning_type => "Cross Site Scripting",
20
+ :message => message,
21
+ :confidence => CONFIDENCE[:high]
22
+ end
23
+ end
24
+
25
+ def uses_strip_tags?
26
+ not tracker.find_call([], :strip_tags).empty?
27
+ end
28
+ end
@@ -22,6 +22,11 @@ class Processor
22
22
  ConfigProcessor.new(@tracker).process_config src
23
23
  end
24
24
 
25
+ #Process Gemfile
26
+ def process_gems src, gem_lock = nil
27
+ GemProcessor.new(@tracker).process_gems src, gem_lock
28
+ end
29
+
25
30
  #Process route file source
26
31
  def process_routes src
27
32
  RoutesProcessor.new(@tracker).process_routes src
@@ -0,0 +1,36 @@
1
+ #Processes Gemfile.lock
2
+ class GemProcessor < BaseProcessor
3
+ def initialize *args
4
+ super
5
+
6
+ @tracker.config[:gems] ||= {}
7
+ end
8
+
9
+ def process_gems src, gem_lock = nil
10
+ process src
11
+
12
+ if gem_lock
13
+ get_rails_version gem_lock
14
+ elsif @tracker.config[:gems][:rails] =~ /(\d+.\d+.\d+)/
15
+ @tracker.config[:rails_version] = $1
16
+ end
17
+ end
18
+
19
+ def process_call exp
20
+ if exp[1] == nil and exp[2] == :gem
21
+ args = exp[3][1..-1]
22
+
23
+ if sexp? args[1]
24
+ @tracker.config[:gems][args[0][1].to_sym] = args[1][1]
25
+ end
26
+ end
27
+
28
+ exp
29
+ end
30
+
31
+ def get_rails_version gem_lock
32
+ if gem_lock =~ /\srails \((\d+.\d+.\d+)\)$/
33
+ @tracker.config[:rails_version] = $1
34
+ end
35
+ end
36
+ end
@@ -16,6 +16,8 @@ module ProcessorHelper
16
16
  case exp.node_type
17
17
  when :const
18
18
  exp[1]
19
+ when :lvar
20
+ exp[1].to_sym
19
21
  when :colon2
20
22
  "#{class_name(exp[1])}::#{exp[2]}".to_sym
21
23
  when :colon3
@@ -87,17 +87,39 @@ class RoutesProcessor < BaseProcessor
87
87
  def process_match exp
88
88
  args = exp[3][1..-1]
89
89
 
90
- hash_iterate args[0] do |k, v|
91
- if string? k and string? v
92
- controller, action = extract_action v[1]
90
+ #Check if there is an unrestricted action parameter
91
+ action_variable = false
92
+
93
+ if string? args[0]
94
+ matcher = args[0][1]
95
+
96
+ if matcher == ':controller(/:action(/:id(.:format)))' or
97
+ matcher.include? ':controller' and matcher.include? ':action' #Default routes
98
+ @tracker.routes[:allow_all_actions] = args[0]
99
+ return exp
100
+ elsif matcher.include? ':action'
101
+ action_variable = true
102
+ end
103
+ end
93
104
 
94
- self.current_controller = controller
95
- @tracker.routes[@current_controller] << action.to_sym if action
96
- elsif symbol? k and k[1] == :action
97
- @tracker.routes[@current_controller] << v[1].to_sym
105
+ if hash? args[-1]
106
+ hash_iterate args[-1] do |k, v|
107
+ if string? k and string? v
108
+ controller, action = extract_action v[1]
109
+
110
+ self.current_controller = controller
111
+ @tracker.routes[@current_controller] << action.to_sym if action
112
+ elsif symbol? k and k[1] == :action
113
+ @tracker.routes[@current_controller] << v[1].to_sym
114
+ action_variable = false
115
+ end
98
116
  end
99
117
  end
100
118
 
119
+ if action_variable
120
+ @tracker.routes[@current_controller] = :allow_all_actions
121
+ end
122
+
101
123
  exp
102
124
  end
103
125
 
@@ -636,7 +636,7 @@ class Report
636
636
 
637
637
  checks.send(meth).map do |w|
638
638
  line = w.line || 0
639
- w.warning_type.gsub! /[^\w\s]/, ' '
639
+ w.warning_type.gsub!(/[^\w\s]/, ' ')
640
640
  "#{file_for w}\t#{line}\t#{w.warning_type}\t#{category}\t#{w.format_message}\t#{TEXT_CONFIDENCE[w.confidence]}"
641
641
  end.join "\n"
642
642
 
@@ -41,6 +41,8 @@ class Scanner
41
41
  def process
42
42
  warn "Processing configuration..."
43
43
  process_config
44
+ warn "Processing gems..."
45
+ process_gems
44
46
  warn "Processing initializers..."
45
47
  process_initializers
46
48
  warn "Processing libs..."
@@ -74,6 +76,17 @@ class Scanner
74
76
  end
75
77
  end
76
78
 
79
+ #Process Gemfile
80
+ def process_gems
81
+ if File.exists? "#@path/Gemfile"
82
+ if File.exists? "#@path/Gemfile.lock"
83
+ @processor.process_gems(RubyParser.new.parse(File.read("#@path/Gemfile")), File.read("#@path/Gemfile.lock"))
84
+ else
85
+ @processor.process_gems(RubyParser.new.parse(File.read("#@path/Gemfile")))
86
+ end
87
+ end
88
+ end
89
+
77
90
  #Process all the .rb files in config/initializers/
78
91
  #
79
92
  #Adds parsed information to tracker.initializers
@@ -1 +1 @@
1
- Version = "0.6.1"
1
+ Version = "0.7.0"
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 6
8
- - 1
9
- version: 0.6.1
7
+ - 7
8
+ - 0
9
+ version: 0.7.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Justin Collins
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-07-29 00:00:00 -07:00
17
+ date: 2011-08-17 00:00:00 -07:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -105,6 +105,7 @@ files:
105
105
  - FEATURES
106
106
  - README.md
107
107
  - lib/warning.rb
108
+ - lib/processors/gem_processor.rb
108
109
  - lib/processors/params_processor.rb
109
110
  - lib/processors/controller_alias_processor.rb
110
111
  - lib/processors/base_processor.rb
@@ -130,17 +131,22 @@ files:
130
131
  - lib/checks/check_send_file.rb
131
132
  - lib/checks/check_session_settings.rb
132
133
  - lib/checks/check_nested_attributes.rb
134
+ - lib/checks/check_strip_tags.rb
133
135
  - lib/checks/check_sql.rb
134
136
  - lib/checks/check_mass_assignment.rb
137
+ - lib/checks/check_escape_function.rb
135
138
  - lib/checks/check_cross_site_scripting.rb
136
139
  - lib/checks/check_model_attributes.rb
137
140
  - lib/checks/check_default_routes.rb
138
141
  - lib/checks/check_evaluation.rb
142
+ - lib/checks/check_quote_table_name.rb
139
143
  - lib/checks/check_validation_regex.rb
140
144
  - lib/checks/check_execute.rb
145
+ - lib/checks/check_filter_skipping.rb
141
146
  - lib/checks/check_mail_to.rb
142
147
  - lib/checks/base_check.rb
143
148
  - lib/checks/check_file_access.rb
149
+ - lib/checks/check_response_splitting.rb
144
150
  - lib/checks/check_redirect.rb
145
151
  - lib/checks/check_forgery_setting.rb
146
152
  - lib/checks/check_render.rb