brakeman 0.6.1 → 0.7.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/lib/checks/check_escape_function.rb +17 -0
- data/lib/checks/check_filter_skipping.rb +27 -0
- data/lib/checks/check_quote_table_name.rb +34 -0
- data/lib/checks/check_response_splitting.rb +18 -0
- data/lib/checks/check_strip_tags.rb +28 -0
- data/lib/processor.rb +5 -0
- data/lib/processors/gem_processor.rb +36 -0
- data/lib/processors/lib/processor_helper.rb +2 -0
- data/lib/processors/lib/rails3_route_processor.rb +29 -7
- data/lib/report.rb +1 -1
- data/lib/scanner.rb +13 -0
- data/lib/version.rb +1 -1
- metadata +10 -4
@@ -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
|
data/lib/processor.rb
CHANGED
@@ -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
|
@@ -87,17 +87,39 @@ class RoutesProcessor < BaseProcessor
|
|
87
87
|
def process_match exp
|
88
88
|
args = exp[3][1..-1]
|
89
89
|
|
90
|
-
|
91
|
-
|
92
|
-
|
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
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
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
|
|
data/lib/report.rb
CHANGED
@@ -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!
|
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
|
|
data/lib/scanner.rb
CHANGED
@@ -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
|
data/lib/version.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
Version = "0.
|
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
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
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-
|
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
|