Module: Brakeman
- Defined in:
- lib/brakeman.rb,
lib/brakeman/version.rb,
lib/brakeman/processor.rb
Defined Under Namespace
Modules: Options, ProcessorHelper, RenderHelper, RouteHelper, Util Classes: AliasProcessor, BaseCheck, BaseProcessor, CallIndex, CheckBasicAuth, CheckContentTag, CheckCrossSiteScripting, CheckDefaultRoutes, CheckDigestDoS, CheckEscapeFunction, CheckEvaluation, CheckExecute, CheckFileAccess, CheckFilterSkipping, CheckForgerySetting, CheckLinkTo, CheckLinkToHref, CheckMailTo, CheckMassAssignment, CheckModelAttributes, CheckNestedAttributes, CheckQuoteTableName, CheckRedirect, CheckRender, CheckResponseSplitting, CheckSQL, CheckSafeBufferManipulation, CheckSelectTag, CheckSelectVulnerability, CheckSend, CheckSendFile, CheckSessionSettings, CheckSingleQuotes, CheckSkipBeforeFilter, CheckStripTags, CheckTranslateBug, CheckValidationRegex, CheckWithoutProtection, Checks, ConfigAliasProcessor, ConfigProcessor, ControllerAliasProcessor, ControllerProcessor, Differ, ErbTemplateProcessor, ErubisTemplateProcessor, FindAllCalls, FindCall, GemProcessor, HamlTemplateProcessor, LibraryProcessor, ModelProcessor, OutputProcessor, Processor, Rails2ConfigProcessor, Rails2RoutesProcessor, Rails2XSSPluginErubis, Rails3ConfigProcessor, Rails3Erubis, Rails3RoutesProcessor, Report, RescanReport, Rescanner, RouteAliasProcessor, RoutesProcessor, Scanner, ScannerErubis, SexpProcessor, TemplateAliasProcessor, TemplateProcessor, Tracker, Warning
Constant Summary collapse
- Warnings_Found_Exit_Code =
This exit code is used when warnings are found and the –exit-on-warn option is set
3
- Version =
"1.8.3"
- RAILS_CONFIG =
Replace block variable in
Rails::Initializer.run |config|
with this value so we can keep track of it.
Sexp.new(:call, nil, :config, Sexp.new(:arglist))
Class Method Summary collapse
-
.compare(options) ⇒ Object
Compare JSON ouptut from a previous scan and return the diff of the two scans.
- .debug(message) ⇒ Object
-
.dump_config(options) ⇒ Object
Output configuration to YAML.
-
.get_defaults ⇒ Object
Default set of options.
- .get_output_formats(options) ⇒ Object
-
.install_rake_task ⇒ Object
Installs Rake task for running Brakeman, which basically means copying ‘lib/brakeman/brakeman.rake` to `lib/tasks/brakeman.rake` in the current Rails application.
-
.list_checks ⇒ Object
Output list of checks (for ‘-k` option).
-
.load_options(config_file) ⇒ Object
Load options from YAML file.
- .notify(message) ⇒ Object
-
.rescan(tracker, files, options = {}) ⇒ Object
Rescan a subset of files in a Rails application.
-
.run(options) ⇒ Object
Run Brakeman scan.
-
.scan(options) ⇒ Object
Run a scan.
-
.set_options(options) ⇒ Object
Sets up options for run, checks given application path.
Class Method Details
.compare(options) ⇒ Object
Compare JSON ouptut from a previous scan and return the diff of the two scans
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 |
# File 'lib/brakeman.rb', line 318 def self.compare require 'multi_json' require 'brakeman/differ' raise ArgumentError.new("Comparison file doesn't exist") unless File.exists? [:previous_results_json] begin previous_results = MultiJson.load(File.read([:previous_results_json]), :symbolize_keys => true)[:warnings] rescue MultiJson::DecodeError self.notify "Error parsing comparison file: #{options[:previous_results_json]}" exit! end tracker = run() new_results = MultiJson.load(tracker.report.to_json, :symbolize_keys => true)[:warnings] Brakeman::Differ.new(new_results, previous_results).diff end |
.debug(message) ⇒ Object
313 314 315 |
# File 'lib/brakeman.rb', line 313 def self.debug $stderr.puts if @debug end |
.dump_config(options) ⇒ Object
Output configuration to YAML
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'lib/brakeman.rb', line 215 def self.dump_config if [:create_config].is_a? String file = [:create_config] else file = nil end .delete :create_config .each do |k,v| if v.is_a? Set [k] = v.to_a end end if file File.open file, "w" do |f| YAML.dump , f end puts "Output configuration to #{file}" else puts YAML.dump() end exit end |
.get_defaults ⇒ Object
Default set of options
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/brakeman.rb', line 111 def self.get_defaults { :skip_checks => Set.new, :check_arguments => true, :safe_methods => Set.new, :min_confidence => 2, :combine_locations => true, :collapse_mass_assignment => true, :highlight_user_input => true, :ignore_redirect_to_model => true, :ignore_model_output => false, :message_limit => 100, :parallel_checks => true, :relative_path => false, :quiet => true, :report_progress => true, :html_style => "#{File.expand_path(File.dirname(__FILE__))}/brakeman/format/style.css" } end |
.get_output_formats(options) ⇒ Object
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/brakeman.rb', line 132 def self.get_output_formats #Set output format if [:output_format] && [:output_files] && [:output_files].size > 1 raise ArgumentError, "Cannot specify output format if multiple output files specified" end if [:output_format] [ case [:output_format] when :html, :to_html :to_html when :csv, :to_csv :to_csv when :pdf, :to_pdf :to_pdf when :tabs, :to_tabs :to_tabs when :json, :to_json :to_json else :to_s end ] else return [:to_s] unless [:output_files] [:output_files].map do |output_file| case output_file when /\.html$/i :to_html when /\.csv$/i :to_csv when /\.pdf$/i :to_pdf when /\.tabs$/i :to_tabs when /\.json$/i :to_json else :to_s end end end end |
.install_rake_task ⇒ Object
Installs Rake task for running Brakeman, which basically means copying ‘lib/brakeman/brakeman.rake` to `lib/tasks/brakeman.rake` in the current Rails application.
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/brakeman.rb', line 188 def self.install_rake_task if not File.exists? "Rakefile" abort "No Rakefile detected" elsif File.exists? "lib/tasks/brakeman.rake" abort "Task already exists" end require 'fileutils' if not File.exists? "lib/tasks" notify "Creating lib/tasks" FileUtils.mkdir_p "lib/tasks" end path = File.(File.dirname(__FILE__)) FileUtils.cp "#{path}/brakeman/brakeman.rake", "lib/tasks/brakeman.rake" if File.exists? "lib/tasks/brakeman.rake" notify "Task created in lib/tasks/brakeman.rake" notify "Usage: rake brakeman:run[output_file]" else notify "Could not create task" end end |
.list_checks ⇒ Object
Output list of checks (for ‘-k` option)
176 177 178 179 180 181 182 183 |
# File 'lib/brakeman.rb', line 176 def self.list_checks require 'brakeman/scanner' $stderr.puts "Available Checks:" $stderr.puts "-" * 30 $stderr.puts Checks.checks.map { |c| c.to_s.match(/^Brakeman::(.*)$/)[1].ljust(27) << c.description }.sort.join "\n" end |
.load_options(config_file) ⇒ Object
Load options from YAML file
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/brakeman.rb', line 84 def self. config_file config_file ||= "" #Load configuration file [File.(config_file), File.("./config.yaml"), File.("~/.brakeman/config.yaml"), File.("/etc/brakeman/config.yaml"), "#{File.expand_path(File.dirname(__FILE__))}/../lib/config.yaml"].each do |f| if File.exist? f and not File.directory? f notify "[Notice] Using configuration in #{f}" = YAML.load_file f .each do |k,v| if v.is_a? Array [k] = Set.new v end end return end end return {} end |
.notify(message) ⇒ Object
309 310 311 |
# File 'lib/brakeman.rb', line 309 def self.notify $stderr.puts unless @quiet end |
.rescan(tracker, files, options = {}) ⇒ Object
Rescan a subset of files in a Rails application.
A full scan must have been run already to use this method. The returned Tracker object from Brakeman.run is used as a starting point for the rescan.
Options may be given as a hash with the same values as Brakeman.run. Note that these options will be merged into the Tracker.
This method returns a RescanReport object with information about the scan. However, the Tracker object will also be modified as the scan is run.
298 299 300 301 302 303 304 305 306 307 |
# File 'lib/brakeman.rb', line 298 def self.rescan tracker, files, = {} require 'brakeman/rescanner' tracker..merge! @quiet = !!tracker.[:quiet] @debug = !!tracker.[:debug] Rescanner.new(tracker., tracker.processor, files).recheck end |
.run(options) ⇒ Object
Run Brakeman scan. Returns Tracker object.
Options:
* :app_path - path to root of Rails app (required)
* :assume_all_routes - assume all methods are routes (default: false)
* :check_arguments - check arguments of methods (default: true)
* :collapse_mass_assignment - report unprotected models in single warning (default: true)
* :combine_locations - combine warning locations (default: true)
* :config_file - configuration file
* :escape_html - escape HTML by default (automatic)
* :exit_on_warn - return false if warnings found, true otherwise. Not recommended for library use (default: false)
* :highlight_user_input - highlight user input in reported warnings (default: true)
* :html_style - path to CSS file
* :ignore_model_output - consider models safe (default: false)
* :message_limit - limit length of
* :min_confidence - minimum confidence (0-2, 0 is highest)
* :output_files - files for output
* :output_formats - formats for output (:to_s, :to_tabs, :to_csv, :to_html)
* :parallel_checks - run checks in parallel (default: true)
* :print_report - if no output file specified, print to stdout (default: false)
* :quiet - suppress most (default: true)
* :rails3 - force Rails 3 mode (automatic)
* :report_routes - show found routes on controllers (default: false)
* :run_checks - array of checks to run (run all if not specified)
* :safe_methods - array of methods to consider safe
* :skip_libs - do not process lib/ directory (default: false)
* :skip_checks - checks not to run (run all if not specified)
* :relative_path - show relative path of each file(default: false)
* :summary_only - only output summary section of report
(does not apply to tabs format)
Alternatively, just supply a path as a string.
47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/brakeman.rb', line 47 def self.run = @quiet = !![:quiet] @debug = !![:debug] if @quiet [:report_progress] = false end scan end |
.scan(options) ⇒ Object
Run a scan. Generally called from Brakeman.run instead of directly.
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 |
# File 'lib/brakeman.rb', line 242 def self.scan #Load scanner notify "Loading scanner..." begin require 'brakeman/scanner' rescue LoadError abort "Cannot find lib/ directory." end #Start scanning scanner = Scanner.new notify "[Notice] Using Ruby #{RUBY_VERSION}. Please make sure this matches the one used to run your Rails application." notify "Processing application in #{options[:app_path]}" tracker = scanner.process if [:parallel_checks] notify "Running checks in parallel..." else notify "Runnning checks..." end tracker.run_checks if [:output_files] notify "Generating report..." [:output_files].each_with_index do |output_file, idx| File.open output_file, "w" do |f| f.write tracker.report.send([:output_formats][idx]) end notify "Report saved in '#{output_file}'" end elsif [:print_report] notify "Generating report..." [:output_formats].each do |output_format| puts tracker.report.send(output_format) end end tracker end |
.set_options(options) ⇒ Object
Sets up options for run, checks given application path
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/brakeman.rb', line 60 def self. if .is_a? String = { :app_path => } end [:app_path] = File.([:app_path]) = ([:config_file]).merge! = get_defaults.merge! [:output_formats] = get_output_formats app_path = [:app_path] abort("Please supply the path to a Rails application.") unless app_path and File.exist? app_path + "/app" if File.exist? app_path + "/script/rails" [:rails3] = true notify "[Notice] Detected Rails 3 application" unless [:quiet] end end |