Module: Brakeman
- Defined in:
- lib/brakeman.rb,
lib/brakeman/version.rb,
lib/brakeman/app_tree.rb,
lib/brakeman/messages.rb,
lib/brakeman/file_path.rb,
lib/brakeman/processor.rb,
lib/brakeman/commandline.rb,
lib/brakeman/file_parser.rb,
lib/brakeman/report/pager.rb,
lib/brakeman/tracker/model.rb,
lib/brakeman/tracker/config.rb,
lib/brakeman/tracker/library.rb,
lib/brakeman/tracker/template.rb,
lib/brakeman/tracker/constants.rb,
lib/brakeman/tracker/collection.rb,
lib/brakeman/tracker/controller.rb,
lib/brakeman/report/ignore/config.rb,
lib/brakeman/parsers/haml_embedded.rb,
lib/brakeman/parsers/template_parser.rb,
lib/brakeman/report/ignore/interactive.rb,
lib/brakeman/processors/lib/render_path.rb,
lib/brakeman/processors/lib/safe_call_helper.rb,
lib/brakeman/codeclimate/engine_configuration.rb,
lib/brakeman/processors/lib/call_conversion_helper.rb
Defined Under Namespace
Modules: CallConversionHelper, Codeclimate, ControllerMethods, FakeHamlFilter, Messages, ModelMethods, ModuleHelper, Options, ProcessorHelper, RenderHelper, RouteHelper, SafeCallHelper, Util, WarningCodes Classes: ASTFile, AliasProcessor, AppTree, BaseCheck, BaseProcessor, BasicProcessor, CallIndex, CheckBasicAuth, CheckBasicAuthTimingAttack, CheckContentTag, CheckCookieSerialization, CheckCreateWith, CheckCrossSiteScripting, CheckDefaultRoutes, CheckDeserialize, CheckDetailedExceptions, CheckDigestDoS, CheckDivideByZero, CheckDynamicFinders, CheckEscapeFunction, CheckEvaluation, CheckExecute, CheckFileAccess, CheckFileDisclosure, CheckFilterSkipping, CheckForceSSL, CheckForgerySetting, CheckHeaderDoS, CheckI18nXSS, CheckJRubyXML, CheckJSONEncoding, CheckJSONParsing, CheckLinkTo, CheckLinkToHref, CheckMailTo, CheckMassAssignment, CheckMimeTypeDoS, CheckModelAttrAccessible, CheckModelAttributes, CheckModelSerialize, CheckNestedAttributes, CheckNestedAttributesBypass, CheckNumberToCurrency, CheckPermitAttributes, CheckQuoteTableName, CheckRedirect, CheckRegexDoS, CheckRender, CheckRenderDoS, CheckRenderInline, CheckResponseSplitting, CheckReverseTabnabbing, CheckRouteDoS, CheckSQL, CheckSQLCVEs, CheckSSLVerify, CheckSafeBufferManipulation, CheckSanitizeMethods, CheckSecrets, CheckSelectTag, CheckSelectVulnerability, CheckSend, CheckSendFile, CheckSessionManipulation, CheckSessionSettings, CheckSimpleFormat, CheckSingleQuotes, CheckSkipBeforeFilter, CheckSprocketsPathTraversal, CheckStripTags, CheckSymbolDoS, CheckSymbolDoSCVE, CheckTranslateBug, CheckUnsafeReflection, CheckUnscopedFind, CheckValidationRegex, CheckWeakHash, CheckWithoutProtection, CheckXMLDoS, CheckYAMLParsing, Checks, Collection, Commandline, Config, ConfigAliasProcessor, ConfigProcessor, Constant, Constants, Controller, ControllerAliasProcessor, ControllerProcessor, DependencyError, Differ, ErbTemplateProcessor, ErubisTemplateProcessor, FileParser, FilePath, FindAllCalls, FindCall, FindReturnValue, GemProcessor, HamlTemplateProcessor, IgnoreConfig, InteractiveIgnorer, Library, LibraryProcessor, MissingChecksError, Model, ModelProcessor, NoApplication, NoBrakemanError, OutputProcessor, Pager, Processor, Rails2ConfigProcessor, Rails2RoutesProcessor, Rails2XSSPluginErubis, Rails3ConfigProcessor, Rails3Erubis, Rails3RoutesProcessor, Rails4ConfigProcessor, RenderPath, Report, RescanReport, Rescanner, RouteAliasProcessor, RoutesProcessor, Scanner, ScannerErubis, SexpProcessor, SlimTemplateProcessor, Template, TemplateAliasProcessor, TemplateParser, 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
- No_App_Found_Exit_Code =
Exit code returned when no Rails application is detected
4
- Not_Latest_Version_Exit_Code =
Exit code returned when brakeman was outdated
5
- Missing_Checks_Exit_Code =
Exit code returned when user requests non-existent checks
6
- Errors_Found_Exit_Code =
Exit code returned when errors were found and the –exit-on-error option is set
7
- CONFIG_FILES =
[ File.("~/.brakeman/config.yml"), File.("/etc/brakeman/config.yml") ]
- Version =
"4.7.2"
Class Method Summary collapse
- .add_external_checks(options) ⇒ Object
- .check_for_missing_checks(included_checks, excluded_checks, enabled_checks) ⇒ Object
-
.compare(options) ⇒ Object
Compare JSON ouptut from a previous scan and return the diff of the two scans.
- .config_file(custom_location, app_path) ⇒ Object
- .debug(message) ⇒ Object
- .debug=(val) ⇒ Object
-
.default_options ⇒ Object
Default set of options.
-
.dump_config(options) ⇒ Object
Output configuration to YAML.
- .ensure_latest ⇒ Object
- .filter_warnings(tracker, options) ⇒ Object
- .get_output_formats(options) ⇒ Object
-
.list_checks(options) ⇒ Object
Output list of checks (for ‘-k` option).
- .load_brakeman_dependency(name, allow_fail = false) ⇒ Object
-
.load_options(line_options) ⇒ Object
Load options from YAML file.
- .notify(message) ⇒ Object
- .quiet=(val) ⇒ 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
.add_external_checks(options) ⇒ Object
525 526 527 528 529 |
# File 'lib/brakeman.rb', line 525 def self.add_external_checks [:additional_checks_path].each do |path| Brakeman::Checks.initialize_checks path end if [:additional_checks_path] end |
.check_for_missing_checks(included_checks, excluded_checks, enabled_checks) ⇒ Object
531 532 533 534 535 536 537 538 539 |
# File 'lib/brakeman.rb', line 531 def self.check_for_missing_checks included_checks, excluded_checks, enabled_checks checks = included_checks.to_a + excluded_checks.to_a + enabled_checks.to_a missing = Brakeman::Checks.missing_checks(checks) unless missing.empty? raise MissingChecksError, "Could not find specified check#{missing.length > 1 ? 's' : ''}: #{missing.map {|c| "`#{c}`"}.join(', ')}" end end |
.compare(options) ⇒ Object
Compare JSON ouptut from a previous scan and return the diff of the two scans
452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 |
# File 'lib/brakeman.rb', line 452 def self.compare require 'json' require 'brakeman/differ' raise ArgumentError.new("Comparison file doesn't exist") unless File.exist? [:previous_results_json] begin previous_results = JSON.parse(File.read([:previous_results_json]), :symbolize_names => true)[:warnings] rescue JSON::ParserError self.notify "Error parsing comparison file: #{[:previous_results_json]}" exit! end tracker = run() new_results = JSON.parse(tracker.report.to_json, :symbolize_names => true)[:warnings] Brakeman::Differ.new(new_results, previous_results).diff end |
.config_file(custom_location, app_path) ⇒ Object
160 161 162 163 164 |
# File 'lib/brakeman.rb', line 160 def self.config_file custom_location, app_path app_config = File.(File.join(app_path, "config", "brakeman.yml")) supported_locations = [File.(custom_location || ""), app_config] + CONFIG_FILES supported_locations.detect {|f| File.file?(f) } end |
.debug(message) ⇒ Object
447 448 449 |
# File 'lib/brakeman.rb', line 447 def self.debug $stderr.puts if @debug end |
.debug=(val) ⇒ Object
541 542 543 |
# File 'lib/brakeman.rb', line 541 def self.debug= val @debug = val end |
.default_options ⇒ Object
Default set of options
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/brakeman.rb', line 167 def self. { :assume_all_routes => true, :check_arguments => true, :collapse_mass_assignment => false, :combine_locations => true, :engine_paths => ["engines/*"], :exit_on_error => true, :exit_on_warn => true, :highlight_user_input => true, :html_style => "#{File.(File.dirname(__FILE__))}/brakeman/format/style.css", :ignore_model_output => false, :ignore_redirect_to_model => true, :index_libs => true, :message_limit => 100, :min_confidence => 2, :output_color => true, :pager => true, :parallel_checks => true, :parser_timeout => 10, :relative_path => false, :report_progress => true, :safe_methods => Set.new, :skip_checks => Set.new, } end |
.dump_config(options) ⇒ Object
Output configuration to YAML
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 |
# File 'lib/brakeman.rb', line 307 def self.dump_config require 'yaml' 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 notify "Output configuration to #{file}" else notify YAML.dump() end end |
.ensure_latest ⇒ Object
333 334 335 336 337 338 339 |
# File 'lib/brakeman.rb', line 333 def self.ensure_latest current = Brakeman::Version latest = Gem.latest_version_for('brakeman').to_s if current != latest "Brakeman #{current} is not the latest version #{latest}" end end |
.filter_warnings(tracker, options) ⇒ Object
497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 |
# File 'lib/brakeman.rb', line 497 def self.filter_warnings tracker, require 'brakeman/report/ignore/config' app_tree = Brakeman::AppTree.() if [:ignore_file] file = [:ignore_file] elsif app_tree.exists? "config/brakeman.ignore" file = app_tree.("config/brakeman.ignore") elsif not [:interactive_ignore] return end notify "Filtering warnings..." if [:interactive_ignore] require 'brakeman/report/ignore/interactive' config = InteractiveIgnorer.new(file, tracker.warnings).start else notify "[Notice] Using '#{file}' to filter warnings" config = IgnoreConfig.new(file, tracker.warnings) config.read_from_file config.filter_ignored end tracker.ignored_filter = config end |
.get_output_formats(options) ⇒ Object
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/brakeman.rb', line 195 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] get_formats_from_output_format [:output_format] elsif [:output_files] get_formats_from_output_files [:output_files] else begin self.load_brakeman_dependency 'terminal-table', :allow_fail return [:to_s] rescue LoadError return [:to_json] end end end |
.list_checks(options) ⇒ Object
Output list of checks (for ‘-k` option)
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 |
# File 'lib/brakeman.rb', line 285 def self.list_checks require 'brakeman/scanner' add_external_checks if [:list_optional_checks] $stderr.puts "Optional Checks:" checks = Checks.optional_checks else $stderr.puts "Available Checks:" checks = Checks.checks end format_length = 30 $stderr.puts "-" * format_length checks.each do |check| $stderr.printf("%-#{format_length}s%s\n", check.name, check.description) end end |
.load_brakeman_dependency(name, allow_fail = false) ⇒ Object
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 |
# File 'lib/brakeman.rb', line 471 def self.load_brakeman_dependency name, allow_fail = false return if @loaded_dependencies.include? name unless @vendored_paths path_load = "#{File.(File.dirname(__FILE__))}/../bundle/load.rb" if File.exist? path_load require path_load end @vendored_paths = true end begin require name rescue LoadError => e if allow_fail raise e else $stderr.puts e. $stderr.puts "Please install the appropriate dependency: #{name}." exit!(-1) end end end |
.load_options(line_options) ⇒ Object
Load options from YAML file
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/brakeman.rb', line 118 def self. custom_location = [:config_file] quiet = [:quiet] app_path = [:app_path] #Load configuration file if config = config_file(custom_location, app_path) require 'date' # https://github.com/dtao/safe_yaml/issues/80 self.load_brakeman_dependency 'safe_yaml/load' = SafeYAML.load_file config, :deserialize_symbols => true if .each { |k, v| [k] = Set.new v if v.is_a? Array } # After parsing the yaml config file for options, convert any string keys into symbols. .keys.select {|k| k.is_a? String}.map {|k| k.to_sym }.each {|k| [k] = [k.to_s]; .delete(k.to_s) } unless [:allow_check_paths_in_config] if .include? :additional_checks_path .delete :additional_checks_path notify "[Notice] Ignoring additional check paths in config file. Use --allow-check-paths-in-config to allow" unless ([:quiet] || quiet) end end # notify if options[:quiet] and quiet is nil||false notify "[Notice] Using configuration in #{config}" unless ([:quiet] || quiet) else notify "[Notice] Empty configuration file: #{config}" unless quiet {} end else {} end end |
.notify(message) ⇒ Object
443 444 445 |
# File 'lib/brakeman.rb', line 443 def self.notify $stderr.puts unless @quiet end |
.quiet=(val) ⇒ Object
545 546 547 |
# File 'lib/brakeman.rb', line 545 def self.quiet= val @quiet = val 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.
432 433 434 435 436 437 438 439 440 441 |
# File 'lib/brakeman.rb', line 432 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)
* :additional_checks_path - array of additional directories containing additional out-of-tree checks to run
* :additional_libs_path - array of additional application relative lib directories (ex. app/mailers) to process
* :assume_all_routes - assume all methods are routes (default: true)
* :check_arguments - check arguments of methods (default: true)
* :collapse_mass_assignment - report unprotected models in single warning (default: false)
* :combine_locations - combine warning locations (default: true)
* :config_file - configuration file
* :escape_html - escape HTML by default (automatic)
* :exit_on_error - only affects Commandline module (default: true)
* :exit_on_warn - only affects Commandline module (default: true)
* :github_repo - github repo to use for file links (user/repo[/path][@ref])
* :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)
* :index_libs - add libraries to call index (default: true)
* :interprocedural - limited interprocedural processing of method calls (default: false)
* :message_limit - limit length of messages
* :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)
* :parser_timeout - set timeout for parsing an individual file (default: 10 seconds)
* :print_report - if no output file specified, print to stdout (default: false)
* :quiet - suppress most messages (default: true)
* :rails3 - force Rails 3 mode (automatic)
* :rails4 - force Rails 4 mode (automatic)
* :rails5 - force Rails 5 mode (automatic)
* :rails6 - force Rails 6 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)
* :absolute_paths - show absolute path of each file (default: false)
* :summary_only - only output summary section of report for plain/table (:summary_only, :no_summary, true)
Alternatively, just supply a path as a string.
70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/brakeman.rb', line 70 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.
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 |
# File 'lib/brakeman.rb', line 342 def self.scan #Load scanner notify "Loading scanner..." begin require 'brakeman/scanner' rescue LoadError raise NoBrakemanError, "Cannot find lib/ directory." end add_external_checks #Start scanning scanner = Scanner.new tracker = scanner.tracker check_for_missing_checks [:run_checks], [:skip_checks], [:enable_checks] notify "Processing application in #{tracker.app_path}" scanner.process if [:parallel_checks] notify "Running checks in parallel..." else notify "Runnning checks..." end tracker.run_checks self.filter_warnings tracker, if [:output_files] notify "Generating report..." write_report_to_files tracker, [:output_files] elsif [:print_report] notify "Generating report..." write_report_to_formats tracker, [:output_formats] end tracker end |
.set_options(options) ⇒ Object
Sets up options for run, checks given application path
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 109 110 111 112 113 114 115 |
# File 'lib/brakeman.rb', line 84 def self. if .is_a? String = { :app_path => } end if [:quiet] == :command_line command_line = true .delete :quiet end = .merge(()).merge() if [:quiet].nil? and not command_line [:quiet] = true end if [:rails4] [:rails3] = true elsif [:rails5] [:rails3] = true [:rails4] = true elsif [:rails6] [:rails3] = true [:rails4] = true [:rails5] = true end [:output_formats] = get_output_formats [:github_url] = get_github_url end |