brakeman-min 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/FEATURES +16 -0
  2. data/README.md +118 -0
  3. data/WARNING_TYPES +69 -0
  4. data/bin/brakeman +269 -0
  5. data/lib/checks.rb +67 -0
  6. data/lib/checks/base_check.rb +353 -0
  7. data/lib/checks/check_cross_site_scripting.rb +324 -0
  8. data/lib/checks/check_default_routes.rb +29 -0
  9. data/lib/checks/check_evaluation.rb +27 -0
  10. data/lib/checks/check_execute.rb +110 -0
  11. data/lib/checks/check_file_access.rb +46 -0
  12. data/lib/checks/check_forgery_setting.rb +42 -0
  13. data/lib/checks/check_mail_to.rb +48 -0
  14. data/lib/checks/check_mass_assignment.rb +72 -0
  15. data/lib/checks/check_model_attributes.rb +36 -0
  16. data/lib/checks/check_nested_attributes.rb +34 -0
  17. data/lib/checks/check_redirect.rb +98 -0
  18. data/lib/checks/check_render.rb +65 -0
  19. data/lib/checks/check_send_file.rb +15 -0
  20. data/lib/checks/check_session_settings.rb +36 -0
  21. data/lib/checks/check_sql.rb +124 -0
  22. data/lib/checks/check_validation_regex.rb +60 -0
  23. data/lib/format/style.css +105 -0
  24. data/lib/processor.rb +83 -0
  25. data/lib/processors/alias_processor.rb +384 -0
  26. data/lib/processors/base_processor.rb +237 -0
  27. data/lib/processors/config_processor.rb +146 -0
  28. data/lib/processors/controller_alias_processor.rb +237 -0
  29. data/lib/processors/controller_processor.rb +202 -0
  30. data/lib/processors/erb_template_processor.rb +84 -0
  31. data/lib/processors/erubis_template_processor.rb +62 -0
  32. data/lib/processors/haml_template_processor.rb +131 -0
  33. data/lib/processors/lib/find_call.rb +176 -0
  34. data/lib/processors/lib/find_model_call.rb +39 -0
  35. data/lib/processors/lib/processor_helper.rb +36 -0
  36. data/lib/processors/lib/render_helper.rb +137 -0
  37. data/lib/processors/library_processor.rb +118 -0
  38. data/lib/processors/model_processor.rb +125 -0
  39. data/lib/processors/output_processor.rb +233 -0
  40. data/lib/processors/params_processor.rb +77 -0
  41. data/lib/processors/route_processor.rb +338 -0
  42. data/lib/processors/template_alias_processor.rb +86 -0
  43. data/lib/processors/template_processor.rb +55 -0
  44. data/lib/report.rb +651 -0
  45. data/lib/scanner.rb +215 -0
  46. data/lib/scanner_erubis.rb +43 -0
  47. data/lib/tracker.rb +144 -0
  48. data/lib/util.rb +141 -0
  49. data/lib/version.rb +1 -0
  50. data/lib/warning.rb +97 -0
  51. metadata +141 -0
data/FEATURES ADDED
@@ -0,0 +1,16 @@
1
+ Can detect:
2
+ -Possibly unescaped model attributes or parameters in views (Cross Site Scripting)
3
+ -Bad string interpolation in calls to Model.find, Model.last, Model.first, etc., as well as chained calls (SQL Injection)
4
+ -String interpolation in find_by_sql (SQL Injection)
5
+ -String interpolation or params in calls to system, exec, and syscall and `` (Command Injection)
6
+ -Unrestricted mass assignments
7
+ -Global restriction of mass assignment
8
+ -Missing call to protect_from_forgery in ApplicationController (CSRF protection)
9
+ -Default routes, per-controller and globally
10
+ -Redirects based on params (probably too broad currently)
11
+ -Validation regexes not using \A and \z
12
+ -Calls to render with dynamic paths
13
+
14
+ General capabilities:
15
+ -Search for method calls based on target class and/or method name
16
+ -Determine 'output' of templates using ERB, Erubis, or HAML. Can handle automatic escaping
data/README.md ADDED
@@ -0,0 +1,118 @@
1
+ # Brakeman
2
+
3
+ Brakeman is a static analysis tool which checks Ruby on Rails applications for security vulnerabilities.
4
+
5
+ It targets Rails versions > 2.0 and < 3.0.
6
+
7
+ # Installation
8
+
9
+ Using RubyGems:
10
+
11
+ gem install brakeman
12
+
13
+ From source:
14
+
15
+ gem build brakeman.gemspec
16
+ gem install brakeman*.gem
17
+
18
+ # Usage
19
+
20
+ brakeman app_path
21
+
22
+ # Options
23
+
24
+ To specify an output file for the results:
25
+
26
+ brakeman -o output_file app_path
27
+
28
+ The output format is determined by the file extension or by using the `-f` option. Current options are: `text`, `html`, and `csv`.
29
+
30
+ To suppress informational warnings and just output the report:
31
+
32
+ brakeman -q app_path
33
+
34
+ To see all kinds of debugging information:
35
+
36
+ brakeman -d app_path
37
+
38
+ Specific checks can be skipped, if desired. The name needs to be the correct case. For example, to skip looking for default routes (`DefaultRoutes`):
39
+
40
+ brakeman -x DefaultRoutes app_path
41
+
42
+ Multiple checks should be separated by a comma:
43
+
44
+ brakeman -x DefaultRoutes,Redirect app_path
45
+
46
+ To do the opposite and only run a certain set of tests:
47
+
48
+ brakeman -t SQL,ValidationRegex app_path
49
+
50
+ To indicate certain methods are "safe":
51
+
52
+ brakeman -s benign_method,totally_safe app_path
53
+
54
+ By default, brakeman will assume that unknown methods involving untrusted data are dangerous. For example, this would a warning:
55
+
56
+ <%= some_method(:option => params[:input]) %>
57
+
58
+ To only raise warnings only when untrusted data is being directly used:
59
+
60
+ brakeman -r app_path
61
+
62
+ # Warning information
63
+
64
+ See WARNING_TYPES for more information on the warnings reported by this tool.
65
+
66
+ # Warning context
67
+
68
+ The HTML output format provides an excerpt from the original application source where a warning was triggered. Due to the processing done while looking for vulnerabilities, the source may not resemble the reported warning and reported line numbers may be slightly off. However, the context still provides a quick look into the code which raised the warning.
69
+
70
+ # Confidence levels
71
+
72
+ Brakeman assigns a confidence level to each warning. This provides a rough estimate of how certain the tool is that a given warning is actually a problem. Naturally, these ratings should not be taken as absolute truth.
73
+
74
+ There are three levels of confidence:
75
+
76
+ + High - Either this is a simple warning (boolean value) or user input is very likely being used in unsafe ways.
77
+ + Medium - This generally indicates an unsafe use of a variable, but the variable may or may not be user input.
78
+ + Weak - Typically means user input was indirectly used in a potentially unsafe manner.
79
+
80
+ To only get warnings above a given confidence level:
81
+
82
+ brakeman -w3 app_path
83
+
84
+ The `-w` switch takes a number from 1 to 3, with 1 being low (all warnings) and 3 being high (only high confidence warnings).
85
+
86
+ # Configuration files
87
+
88
+ Brakeman options can stored and read from YAML files. To simplify the process of writing a configuration file, the `-C` option will output the currently set options.
89
+
90
+ Options passed in on the commandline have priority over configuration files.
91
+
92
+ The default config locations are `./config.yaml`, `~/.brakeman/`, and `/etc/brakeman/config.yaml`
93
+
94
+ The `-c` option can be used to specify a configuration file to use.
95
+
96
+ # License
97
+
98
+ The MIT License
99
+
100
+ Copyright (c) 2010, YELLOWPAGES.COM, LLC
101
+
102
+ Permission is hereby granted, free of charge, to any person obtaining a copy
103
+ of this software and associated documentation files (the "Software"), to deal
104
+ in the Software without restriction, including without limitation the rights
105
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
106
+ copies of the Software, and to permit persons to whom the Software is
107
+ furnished to do so, subject to the following conditions:
108
+
109
+ The above copyright notice and this permission notice shall be included in
110
+ all copies or substantial portions of the Software.
111
+
112
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
113
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
114
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
115
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
116
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
117
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
118
+ THE SOFTWARE.
data/WARNING_TYPES ADDED
@@ -0,0 +1,69 @@
1
+ This file describes the various warning types reported by this tool.
2
+
3
+ # Cross Site Scripting
4
+
5
+ Cross site scripting warnings are raised when a parameter or model attribute is output through a view without being escaped.
6
+
7
+ See http://guides.rubyonrails.org/security.html#cross-site-scripting-xss for details.
8
+
9
+ # SQL Injection
10
+
11
+ String interpolation or concatenation has been detected in an SQL query. Use parameterized queries instead.
12
+
13
+ See http://guides.rubyonrails.org/security.html#sql-injection for details.
14
+
15
+ # Command Injection
16
+
17
+ Request parameters or string interpolation has been detected in a `system` call. This can lead to someone executing arbitrary commands. Use the safe form of `system` instead, which will pass in arguments safely.
18
+
19
+ See http://guides.rubyonrails.org/security.html#command-line-injection for details.
20
+
21
+ # Mass Assignment
22
+
23
+ Mass assignment is a method for initializing models. If the attributes which are set is not restricted, someone may set the attributes to any value they wish.
24
+
25
+ Mass assignment can be disabled globally.
26
+
27
+ Please see http://railspikes.com/2008/9/22/is-your-rails-application-safe-from-mass-assignment for more details.
28
+
29
+ # Attribute Restriction
30
+
31
+ This warning comes up if a model does not limit what attributes can be set through mass assignment.
32
+
33
+ In particular, this check looks for `attr_accessible` inside model definitions. If it is not found, this warning will be issued.
34
+
35
+ Note that disabling mass assignment globally will suppress these warnings.
36
+
37
+ # Cross-Site Request Forgery
38
+
39
+ No call to `protect_from_forgery` was found in `ApplicationController`. This method prevents CSRF.
40
+
41
+ See http://guides.rubyonrails.org/security.html#cross-site-request-forgery-csrf for details.
42
+
43
+ # Redirect
44
+
45
+ Redirects which rely on user-supplied values can be used to "spoof" websites or hide malicious links in otherwise harmless-looking URLs. They can also allow access to restricted areas of a site if the destination is not validated.
46
+
47
+ This warning is shown when request parameters are used inside a call to `redirect_to`.
48
+
49
+ See http://www.owasp.org/index.php/Top_10_2010-A10 for more information.
50
+
51
+ # Default Routes
52
+
53
+ The general default routes warning means there is a call to `map.connect ":controller/:action/:id"` in config/routes.rb. This allows any public method on any controller to be called as an action.
54
+
55
+ If this warning is reported for a particular controller, it means there is a route to that controller containing `:action`.
56
+
57
+ Default routes can be dangerous if methods are made public which are not intended to be used as URLs or actions.
58
+
59
+ # Format Validation
60
+
61
+ Calls to `validates_format_of ..., :with => //` which do not use `\A` and `\z` as anchors will cause this warning. Using `^` and `$` is not sufficient, as `$` will only match up to a new line. This allows an attacker to put whatever malicious input they would like after a new line character.
62
+
63
+ See http://guides.rubyonrails.org/security.html#regular-expressions for details.
64
+
65
+ # Dynamic Render Path
66
+
67
+ When a call to `render` uses a dynamically generated path, template name, file name, or action, there is the possibility that a user can access templates that should be restricted. The issue may be worse if those templates execute code or modify the database.
68
+
69
+ This warning is shown whenever the path to be rendered is not a static string or symbol.
data/bin/brakeman ADDED
@@ -0,0 +1,269 @@
1
+ #!/usr/bin/env ruby
2
+ require "optparse"
3
+ require 'set'
4
+ require 'yaml'
5
+
6
+ $:.unshift "#{File.expand_path(File.dirname(__FILE__))}/../lib"
7
+
8
+ require 'version'
9
+
10
+ trap("INT") do
11
+ $stderr.puts "\nInterrupted - exiting."
12
+ exit!
13
+ end
14
+
15
+ #Parse command line options
16
+ options = {}
17
+
18
+ OptionParser.new do |opts|
19
+ opts.banner = "Usage: brakeman [options] rails/root/path"
20
+
21
+ opts.on "-p", "--path PATH", "Specify path to Rails application" do |path|
22
+ options[:app_path] = File.expand_path path
23
+ end
24
+
25
+ opts.on "-q", "--quiet", "Suppress informational messages" do
26
+ options[:quiet] = true
27
+ $VERBOSE = nil
28
+ end
29
+
30
+ opts.separator ""
31
+ opts.separator "Scanning options:"
32
+
33
+ opts.on "--ignore-model-output", "Consider model attributes XSS-safe" do
34
+ options[:ignore_model_output] = true
35
+ end
36
+
37
+ opts.on "-r", "--report-direct", "Only report direct use of untrusted data" do |option|
38
+ options[:check_arguments] = !option
39
+ end
40
+
41
+ opts.on "-s", "--safe-methods meth1,meth2,etc", Array, "Consider the specified methods safe" do |methods|
42
+ options[:safe_methods] ||= Set.new
43
+ options[:safe_methods].merge methods.map {|e| e.to_sym }
44
+ end
45
+
46
+ opts.on "-t", "--test Check1,Check2,etc", Array, "Only run the specified checks" do |checks|
47
+ checks.each_with_index do |s, index|
48
+ if s[0,5] != "Check"
49
+ checks[index] = "Check" << s
50
+ end
51
+ end
52
+
53
+ options[:run_checks] ||= Set.new
54
+ options[:run_checks].merge checks
55
+ end
56
+
57
+ opts.on "-x", "--except Check1,Check2,etc", Array, "Skip the specified checks" do |skip|
58
+ skip.each do |s|
59
+ if s[0,5] != "Check"
60
+ s = "Check" << s
61
+ end
62
+
63
+ options[:skip_checks] ||= Set.new
64
+ options[:skip_checks] << s
65
+ end
66
+ end
67
+
68
+ opts.separator ""
69
+ opts.separator "Output options:"
70
+
71
+ opts.on "-d", "--debug", "Lots of output" do
72
+ options[:debug] = true
73
+ end
74
+
75
+ opts.on "-f",
76
+ "--format TYPE",
77
+ [:pdf, :text, :html, :csv, :tabs],
78
+ "Specify output format. Default is tabs" do |type|
79
+
80
+ type = "s" if type == :text
81
+ options[:output_format] = ("to_" << type.to_s).to_sym
82
+ end
83
+
84
+ opts.on "-l", "--[no]-combine-locations", "Combine warning locations (Default)" do |combine|
85
+ options[:combine_locations] = combine
86
+ end
87
+
88
+ opts.on "-m", "--routes", "Report controller information" do
89
+ options[:report_routes] = true
90
+ end
91
+
92
+ opts.on "--message-limit LENGTH", "Limit message length in HTML report" do |limit|
93
+ options[:message_limit] = limit.to_i
94
+ end
95
+
96
+ opts.on "-o", "--output FILE", "Specify file for output. Defaults to stdout" do |file|
97
+ options[:output_file] = file
98
+ end
99
+
100
+ opts.on "-w",
101
+ "--confidence-level LEVEL",
102
+ ["1", "2", "3"],
103
+ "Set minimal confidence level (1 - 3). Default: 1" do |level|
104
+
105
+ options[:min_confidence] = 3 - level.to_i
106
+ end
107
+
108
+ opts.separator ""
109
+ opts.separator "Configuration files:"
110
+
111
+ opts.on "-c", "--config-file FILE", "Use specified configuration file" do |file|
112
+ options[:config_file] = File.expand_path(file)
113
+ end
114
+
115
+ opts.on "-C", "--create-config [FILE]", "Output configuration file based on options" do |file|
116
+ if file
117
+ options[:create_config] = file
118
+ else
119
+ options[:create_config] = true
120
+ end
121
+ end
122
+
123
+ opts.separator ""
124
+
125
+ opts.on_tail "-h", "--help", "Display this message" do
126
+ puts opts
127
+ exit
128
+ end
129
+ end.parse!(ARGV)
130
+
131
+ #Load configuation file
132
+ [File.expand_path(options[:config_file].to_s),
133
+ File.expand_path("./config.yaml"),
134
+ File.expand_path("~/.brakeman/config.yaml"),
135
+ File.expand_path("/etc/brakeman/config.yaml"),
136
+ "#{File.expand_path(File.dirname(__FILE__))}/../lib/config.yaml"].each do |f|
137
+
138
+ if File.exist? f and not File.directory? f
139
+ warn "[Notice] Using configuration in #{f}" unless options[:quiet]
140
+ OPTIONS = YAML.load_file f
141
+ OPTIONS.merge! options
142
+ OPTIONS.each do |k,v|
143
+ if v.is_a? Array
144
+ OPTIONS[k] = Set.new v
145
+ end
146
+ end
147
+ break
148
+ end
149
+ end
150
+
151
+ OPTIONS = options unless defined? OPTIONS
152
+
153
+ #Set defaults just in case
154
+ { :skip_checks => Set.new,
155
+ :check_arguments => true,
156
+ :safe_methods => Set.new,
157
+ :min_confidence => 2,
158
+ :combine_locations => true,
159
+ :collapse_mass_assignment => true,
160
+ :ignore_redirect_to_model => true,
161
+ :ignore_model_output => false,
162
+ :message_limit => 100,
163
+ :html_style => "#{File.expand_path(File.dirname(__FILE__))}/../lib/format/style.css"
164
+ }.each do |k,v|
165
+ OPTIONS[k] = v if OPTIONS[k].nil?
166
+ end
167
+
168
+
169
+ #Set output format
170
+ if OPTIONS[:output_format]
171
+ case OPTIONS[:output_format]
172
+ when :html, :to_html
173
+ OPTIONS[:output_format] = :to_html
174
+ when :csv, :to_csv
175
+ OPTIONS[:output_format] = :to_csv
176
+ when :pdf, :to_pdf
177
+ OPTIONS[:output_format] = :to_pdf
178
+ when :tabs, :to_tabs
179
+ OPTIONS[:output_format] = :to_tabs
180
+ when OPTIONS[:output_format] = :to_s
181
+ OPTIONS[:output_format] = :to_s
182
+ else
183
+ OPTIONS[:output_format] = :to_tabs
184
+ end
185
+ else
186
+ case OPTIONS[:output_file]
187
+ when /\.html$/i
188
+ OPTIONS[:output_format] = :to_html
189
+ when /\.csv$/i
190
+ OPTIONS[:output_format] = :to_csv
191
+ when /\.pdf$/i
192
+ OPTIONS[:output_format] = :to_pdf
193
+ when /\.tabs$/i
194
+ OPTIONS[:output_format] = :to_tabs
195
+ when /\.text$/i
196
+ OPTIONS[:output_format] = :to_s
197
+ else
198
+ OPTIONS[:output_format] = :to_tabs
199
+ end
200
+ end
201
+
202
+ #Output configuration if requested
203
+ if OPTIONS[:create_config]
204
+
205
+ if OPTIONS[:create_config].is_a? String
206
+ file = OPTIONS[:create_config]
207
+ else
208
+ file = nil
209
+ end
210
+
211
+ OPTIONS.delete :create_config
212
+
213
+ OPTIONS.each do |k,v|
214
+ if v.is_a? Set
215
+ OPTIONS[k] = v.to_a
216
+ end
217
+ end
218
+
219
+ if file
220
+ File.open file, "w" do |f|
221
+ YAML.dump OPTIONS, f
222
+ end
223
+ puts "Output configuration to #{file}"
224
+ else
225
+ puts YAML.dump(OPTIONS)
226
+ end
227
+ exit
228
+ end
229
+
230
+
231
+ #Check application path
232
+ unless OPTIONS[:app_path]
233
+ if ARGV[-1].nil?
234
+ OPTIONS[:app_path] = File.expand_path "."
235
+ else
236
+ OPTIONS[:app_path] = File.expand_path ARGV[-1]
237
+ end
238
+ end
239
+
240
+ app_path = OPTIONS[:app_path]
241
+
242
+ abort("Please supply the path to a Rails application.") unless app_path and File.exist? app_path + "/app"
243
+
244
+ warn "[Notice] Using Ruby #{RUBY_VERSION}. Please make sure this matches the one used to run your Rails application."
245
+
246
+ #Load scanner
247
+ begin
248
+ require 'scanner'
249
+ rescue LoadError
250
+ abort "Cannot find lib/ directory."
251
+ end
252
+
253
+ #Start scanning
254
+ scanner = Scanner.new app_path
255
+
256
+ warn "Processing application in #{app_path}"
257
+ tracker = scanner.process
258
+
259
+ warn "Running checks..."
260
+ tracker.run_checks
261
+
262
+ warn "Generating report..."
263
+ if OPTIONS[:output_file]
264
+ File.open OPTIONS[:output_file], "w" do |f|
265
+ f.puts tracker.report.send(OPTIONS[:output_format])
266
+ end
267
+ else
268
+ puts tracker.report.send(OPTIONS[:output_format])
269
+ end