brakeman-lib 3.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (159) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES +872 -0
  3. data/FEATURES +16 -0
  4. data/README.md +169 -0
  5. data/WARNING_TYPES +95 -0
  6. data/bin/brakeman +89 -0
  7. data/lib/brakeman.rb +495 -0
  8. data/lib/brakeman/app_tree.rb +161 -0
  9. data/lib/brakeman/brakeman.rake +17 -0
  10. data/lib/brakeman/call_index.rb +219 -0
  11. data/lib/brakeman/checks.rb +191 -0
  12. data/lib/brakeman/checks/base_check.rb +518 -0
  13. data/lib/brakeman/checks/check_basic_auth.rb +88 -0
  14. data/lib/brakeman/checks/check_basic_auth_timing_attack.rb +33 -0
  15. data/lib/brakeman/checks/check_content_tag.rb +160 -0
  16. data/lib/brakeman/checks/check_create_with.rb +75 -0
  17. data/lib/brakeman/checks/check_cross_site_scripting.rb +385 -0
  18. data/lib/brakeman/checks/check_default_routes.rb +86 -0
  19. data/lib/brakeman/checks/check_deserialize.rb +57 -0
  20. data/lib/brakeman/checks/check_detailed_exceptions.rb +55 -0
  21. data/lib/brakeman/checks/check_digest_dos.rb +38 -0
  22. data/lib/brakeman/checks/check_dynamic_finders.rb +49 -0
  23. data/lib/brakeman/checks/check_escape_function.rb +21 -0
  24. data/lib/brakeman/checks/check_evaluation.rb +36 -0
  25. data/lib/brakeman/checks/check_execute.rb +167 -0
  26. data/lib/brakeman/checks/check_file_access.rb +63 -0
  27. data/lib/brakeman/checks/check_file_disclosure.rb +35 -0
  28. data/lib/brakeman/checks/check_filter_skipping.rb +31 -0
  29. data/lib/brakeman/checks/check_forgery_setting.rb +74 -0
  30. data/lib/brakeman/checks/check_header_dos.rb +31 -0
  31. data/lib/brakeman/checks/check_i18n_xss.rb +48 -0
  32. data/lib/brakeman/checks/check_jruby_xml.rb +38 -0
  33. data/lib/brakeman/checks/check_json_encoding.rb +47 -0
  34. data/lib/brakeman/checks/check_json_parsing.rb +107 -0
  35. data/lib/brakeman/checks/check_link_to.rb +132 -0
  36. data/lib/brakeman/checks/check_link_to_href.rb +115 -0
  37. data/lib/brakeman/checks/check_mail_to.rb +49 -0
  38. data/lib/brakeman/checks/check_mass_assignment.rb +198 -0
  39. data/lib/brakeman/checks/check_mime_type_dos.rb +39 -0
  40. data/lib/brakeman/checks/check_model_attr_accessible.rb +55 -0
  41. data/lib/brakeman/checks/check_model_attributes.rb +119 -0
  42. data/lib/brakeman/checks/check_model_serialize.rb +67 -0
  43. data/lib/brakeman/checks/check_nested_attributes.rb +38 -0
  44. data/lib/brakeman/checks/check_nested_attributes_bypass.rb +58 -0
  45. data/lib/brakeman/checks/check_number_to_currency.rb +74 -0
  46. data/lib/brakeman/checks/check_quote_table_name.rb +40 -0
  47. data/lib/brakeman/checks/check_redirect.rb +215 -0
  48. data/lib/brakeman/checks/check_regex_dos.rb +69 -0
  49. data/lib/brakeman/checks/check_render.rb +92 -0
  50. data/lib/brakeman/checks/check_render_dos.rb +37 -0
  51. data/lib/brakeman/checks/check_render_inline.rb +54 -0
  52. data/lib/brakeman/checks/check_response_splitting.rb +21 -0
  53. data/lib/brakeman/checks/check_route_dos.rb +42 -0
  54. data/lib/brakeman/checks/check_safe_buffer_manipulation.rb +31 -0
  55. data/lib/brakeman/checks/check_sanitize_methods.rb +79 -0
  56. data/lib/brakeman/checks/check_secrets.rb +40 -0
  57. data/lib/brakeman/checks/check_select_tag.rb +60 -0
  58. data/lib/brakeman/checks/check_select_vulnerability.rb +60 -0
  59. data/lib/brakeman/checks/check_send.rb +48 -0
  60. data/lib/brakeman/checks/check_send_file.rb +19 -0
  61. data/lib/brakeman/checks/check_session_manipulation.rb +36 -0
  62. data/lib/brakeman/checks/check_session_settings.rb +170 -0
  63. data/lib/brakeman/checks/check_simple_format.rb +59 -0
  64. data/lib/brakeman/checks/check_single_quotes.rb +101 -0
  65. data/lib/brakeman/checks/check_skip_before_filter.rb +60 -0
  66. data/lib/brakeman/checks/check_sql.rb +660 -0
  67. data/lib/brakeman/checks/check_sql_cves.rb +101 -0
  68. data/lib/brakeman/checks/check_ssl_verify.rb +49 -0
  69. data/lib/brakeman/checks/check_strip_tags.rb +89 -0
  70. data/lib/brakeman/checks/check_symbol_dos.rb +64 -0
  71. data/lib/brakeman/checks/check_symbol_dos_cve.rb +30 -0
  72. data/lib/brakeman/checks/check_translate_bug.rb +45 -0
  73. data/lib/brakeman/checks/check_unsafe_reflection.rb +51 -0
  74. data/lib/brakeman/checks/check_unscoped_find.rb +41 -0
  75. data/lib/brakeman/checks/check_validation_regex.rb +116 -0
  76. data/lib/brakeman/checks/check_weak_hash.rb +151 -0
  77. data/lib/brakeman/checks/check_without_protection.rb +80 -0
  78. data/lib/brakeman/checks/check_xml_dos.rb +51 -0
  79. data/lib/brakeman/checks/check_yaml_parsing.rb +121 -0
  80. data/lib/brakeman/differ.rb +66 -0
  81. data/lib/brakeman/file_parser.rb +50 -0
  82. data/lib/brakeman/format/style.css +133 -0
  83. data/lib/brakeman/options.rb +301 -0
  84. data/lib/brakeman/parsers/rails2_erubis.rb +6 -0
  85. data/lib/brakeman/parsers/rails2_xss_plugin_erubis.rb +48 -0
  86. data/lib/brakeman/parsers/rails3_erubis.rb +74 -0
  87. data/lib/brakeman/parsers/template_parser.rb +89 -0
  88. data/lib/brakeman/processor.rb +102 -0
  89. data/lib/brakeman/processors/alias_processor.rb +1013 -0
  90. data/lib/brakeman/processors/base_processor.rb +277 -0
  91. data/lib/brakeman/processors/config_processor.rb +14 -0
  92. data/lib/brakeman/processors/controller_alias_processor.rb +273 -0
  93. data/lib/brakeman/processors/controller_processor.rb +326 -0
  94. data/lib/brakeman/processors/erb_template_processor.rb +80 -0
  95. data/lib/brakeman/processors/erubis_template_processor.rb +104 -0
  96. data/lib/brakeman/processors/gem_processor.rb +57 -0
  97. data/lib/brakeman/processors/haml_template_processor.rb +190 -0
  98. data/lib/brakeman/processors/lib/basic_processor.rb +37 -0
  99. data/lib/brakeman/processors/lib/find_all_calls.rb +223 -0
  100. data/lib/brakeman/processors/lib/find_call.rb +183 -0
  101. data/lib/brakeman/processors/lib/find_return_value.rb +134 -0
  102. data/lib/brakeman/processors/lib/processor_helper.rb +75 -0
  103. data/lib/brakeman/processors/lib/rails2_config_processor.rb +145 -0
  104. data/lib/brakeman/processors/lib/rails2_route_processor.rb +313 -0
  105. data/lib/brakeman/processors/lib/rails3_config_processor.rb +132 -0
  106. data/lib/brakeman/processors/lib/rails3_route_processor.rb +308 -0
  107. data/lib/brakeman/processors/lib/render_helper.rb +181 -0
  108. data/lib/brakeman/processors/lib/render_path.rb +107 -0
  109. data/lib/brakeman/processors/lib/route_helper.rb +68 -0
  110. data/lib/brakeman/processors/lib/safe_call_helper.rb +16 -0
  111. data/lib/brakeman/processors/library_processor.rb +119 -0
  112. data/lib/brakeman/processors/model_processor.rb +191 -0
  113. data/lib/brakeman/processors/output_processor.rb +171 -0
  114. data/lib/brakeman/processors/route_processor.rb +17 -0
  115. data/lib/brakeman/processors/slim_template_processor.rb +107 -0
  116. data/lib/brakeman/processors/template_alias_processor.rb +116 -0
  117. data/lib/brakeman/processors/template_processor.rb +74 -0
  118. data/lib/brakeman/report.rb +78 -0
  119. data/lib/brakeman/report/config/remediation.yml +71 -0
  120. data/lib/brakeman/report/ignore/config.rb +135 -0
  121. data/lib/brakeman/report/ignore/interactive.rb +311 -0
  122. data/lib/brakeman/report/renderer.rb +24 -0
  123. data/lib/brakeman/report/report_base.rb +286 -0
  124. data/lib/brakeman/report/report_codeclimate.rb +70 -0
  125. data/lib/brakeman/report/report_csv.rb +55 -0
  126. data/lib/brakeman/report/report_hash.rb +23 -0
  127. data/lib/brakeman/report/report_html.rb +216 -0
  128. data/lib/brakeman/report/report_json.rb +42 -0
  129. data/lib/brakeman/report/report_markdown.rb +156 -0
  130. data/lib/brakeman/report/report_table.rb +107 -0
  131. data/lib/brakeman/report/report_tabs.rb +17 -0
  132. data/lib/brakeman/report/templates/controller_overview.html.erb +22 -0
  133. data/lib/brakeman/report/templates/controller_warnings.html.erb +21 -0
  134. data/lib/brakeman/report/templates/error_overview.html.erb +29 -0
  135. data/lib/brakeman/report/templates/header.html.erb +58 -0
  136. data/lib/brakeman/report/templates/ignored_warnings.html.erb +25 -0
  137. data/lib/brakeman/report/templates/model_warnings.html.erb +21 -0
  138. data/lib/brakeman/report/templates/overview.html.erb +38 -0
  139. data/lib/brakeman/report/templates/security_warnings.html.erb +23 -0
  140. data/lib/brakeman/report/templates/template_overview.html.erb +21 -0
  141. data/lib/brakeman/report/templates/view_warnings.html.erb +34 -0
  142. data/lib/brakeman/report/templates/warning_overview.html.erb +17 -0
  143. data/lib/brakeman/rescanner.rb +483 -0
  144. data/lib/brakeman/scanner.rb +317 -0
  145. data/lib/brakeman/tracker.rb +347 -0
  146. data/lib/brakeman/tracker/collection.rb +93 -0
  147. data/lib/brakeman/tracker/config.rb +101 -0
  148. data/lib/brakeman/tracker/constants.rb +101 -0
  149. data/lib/brakeman/tracker/controller.rb +161 -0
  150. data/lib/brakeman/tracker/library.rb +17 -0
  151. data/lib/brakeman/tracker/model.rb +90 -0
  152. data/lib/brakeman/tracker/template.rb +33 -0
  153. data/lib/brakeman/util.rb +481 -0
  154. data/lib/brakeman/version.rb +3 -0
  155. data/lib/brakeman/warning.rb +255 -0
  156. data/lib/brakeman/warning_codes.rb +111 -0
  157. data/lib/ruby_parser/bm_sexp.rb +610 -0
  158. data/lib/ruby_parser/bm_sexp_processor.rb +116 -0
  159. metadata +362 -0
@@ -0,0 +1,66 @@
1
+ # extracting the diff logic to it's own class for consistency. Currently handles
2
+ # an array of Brakeman::Warnings or plain hash representations.
3
+ class Brakeman::Differ
4
+ DEFAULT_HASH = {:new => [], :fixed => []}
5
+ OLD_WARNING_KEYS = [:warning_type, :location, :code, :message, :file, :link, :confidence, :user_input]
6
+ attr_reader :old_warnings, :new_warnings
7
+
8
+ def initialize new_warnings, old_warnings
9
+ @new_warnings = new_warnings
10
+ @old_warnings = old_warnings
11
+ end
12
+
13
+ def diff
14
+ # get the type of elements
15
+ return DEFAULT_HASH if @new_warnings.empty?
16
+
17
+ warnings = {}
18
+ warnings[:new] = @new_warnings - @old_warnings
19
+ warnings[:fixed] = @old_warnings - @new_warnings
20
+
21
+ second_pass(warnings)
22
+ end
23
+
24
+ # second pass to cleanup any vulns which have changed in line number only.
25
+ # Given a list of new warnings, delete pairs of new/fixed vulns that differ
26
+ # only by line number.
27
+ # Horrible O(n^2) performance. Keep n small :-/
28
+ def second_pass(warnings)
29
+ # keep track of the number of elements deleted because the index numbers
30
+ # won't update as the list is modified
31
+ elements_deleted_offset = 0
32
+
33
+ # dup this list since we will be deleting from it and the iterator gets confused.
34
+ # use _with_index for fast deletion as opposed to .reject!{|obj| obj == *_warning}
35
+ warnings[:new].dup.each_with_index do |new_warning, new_warning_id|
36
+ warnings[:fixed].each_with_index do |fixed_warning, fixed_warning_id|
37
+ if eql_except_line_number new_warning, fixed_warning
38
+ warnings[:new].delete_at(new_warning_id - elements_deleted_offset)
39
+ elements_deleted_offset += 1
40
+ warnings[:fixed].delete_at(fixed_warning_id)
41
+ break
42
+ end
43
+ end
44
+ end
45
+
46
+ warnings
47
+ end
48
+
49
+ def eql_except_line_number new_warning, fixed_warning
50
+ # can't do this ahead of time, as callers may be expecting a Brakeman::Warning
51
+ if new_warning.is_a? Brakeman::Warning
52
+ new_warning = new_warning.to_hash
53
+ fixed_warning = fixed_warning.to_hash
54
+ end
55
+
56
+ if new_warning[:fingerprint] and fixed_warning[:fingerprint]
57
+ new_warning[:fingerprint] == fixed_warning[:fingerprint]
58
+ else
59
+ OLD_WARNING_KEYS.each do |attr|
60
+ return false if new_warning[attr] != fixed_warning[attr]
61
+ end
62
+
63
+ true
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,50 @@
1
+ module Brakeman
2
+ ASTFile = Struct.new(:path, :ast)
3
+
4
+ # This class handles reading and parsing files.
5
+ class FileParser
6
+ attr_reader :file_list
7
+
8
+ def initialize tracker, app_tree
9
+ @tracker = tracker
10
+ @app_tree = app_tree
11
+ @file_list = {}
12
+ end
13
+
14
+ def parse_files list, type
15
+ read_files list, type do |path, contents|
16
+ if ast = parse_ruby(contents, path)
17
+ ASTFile.new(path, ast)
18
+ end
19
+ end
20
+ end
21
+
22
+ def read_files list, type
23
+ @file_list[type] ||= []
24
+
25
+ list.each do |path|
26
+ result = yield path, read_path(path)
27
+ if result
28
+ @file_list[type] << result
29
+ end
30
+ end
31
+ end
32
+
33
+ def parse_ruby input, path
34
+ begin
35
+ Brakeman.debug "Parsing #{path}"
36
+ RubyParser.new.parse input, path
37
+ rescue Racc::ParseError => e
38
+ @tracker.error e, "Could not parse #{path}"
39
+ nil
40
+ rescue => e
41
+ @tracker.error e.exception(e.message + "\nWhile processing #{path}"), e.backtrace
42
+ nil
43
+ end
44
+ end
45
+
46
+ def read_path path
47
+ @app_tree.read_path path
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,133 @@
1
+ /* CSS style used for HTML reports */
2
+
3
+ body {
4
+ font-family: sans-serif;
5
+ color: #161616;
6
+ }
7
+
8
+ a {
9
+ color: #161616;
10
+ }
11
+
12
+ p {
13
+ font-weight: bold;
14
+ font-size: 11pt;
15
+ color: #2D0200;
16
+ }
17
+
18
+ th {
19
+ background-color: #980905;
20
+ border-bottom: 5px solid #530200;
21
+ color: white;
22
+ font-size: 11pt;
23
+ padding: 1px 8px 1px 8px;
24
+ }
25
+
26
+ td {
27
+ border-bottom: 2px solid white;
28
+ font-family: monospace;
29
+ padding: 5px 8px 1px 8px;
30
+ }
31
+
32
+ table {
33
+ background-color: #FCF4D4;
34
+ border-collapse: collapse;
35
+ }
36
+
37
+ h1 {
38
+ color: #2D0200;
39
+ font-size: 14pt;
40
+ }
41
+
42
+ h2 {
43
+ color: #2D0200;
44
+ font-size: 12pt;
45
+ }
46
+
47
+ span.high-confidence {
48
+ font-weight:bold;
49
+ color: red;
50
+ }
51
+
52
+ span.med-confidence {
53
+ }
54
+
55
+ span.weak-confidence {
56
+ color:gray;
57
+ }
58
+
59
+ div.warning_message {
60
+ cursor: pointer;
61
+ }
62
+
63
+ div.warning_message:hover {
64
+ background-color: white;
65
+ }
66
+
67
+ table caption {
68
+ background-color: #FFE;
69
+ padding: 2px;
70
+ }
71
+
72
+ table.context {
73
+ margin-top: 5px;
74
+ margin-bottom: 5px;
75
+ border-left: 1px solid #90e960;
76
+ color: #212121;
77
+ }
78
+
79
+ tr.context {
80
+ background-color: white;
81
+ }
82
+
83
+ tr.first {
84
+ border-top: 1px solid #7ecc54;
85
+ padding-top: 2px;
86
+ }
87
+
88
+ tr.error {
89
+ background-color: #f4c1c1 !important
90
+ }
91
+
92
+ tr.near_error {
93
+ background-color: #f4d4d4 !important
94
+ }
95
+
96
+ tr.alt {
97
+ background-color: #e8f4d4;
98
+ }
99
+
100
+ td.context {
101
+ padding: 2px 10px 0px 6px;
102
+ border-bottom: none;
103
+ }
104
+
105
+ td.context_line {
106
+ padding: 2px 8px 0px 7px;
107
+ border-right: 1px solid #b3bda4;
108
+ border-bottom: none;
109
+ color: #6e7465;
110
+ }
111
+
112
+ pre.context {
113
+ margin-bottom: 1px;
114
+ }
115
+
116
+ .user_input {
117
+ background-color: #fcecab;
118
+ }
119
+
120
+ div.render_path {
121
+ display: none;
122
+ background-color: #ffe;
123
+ padding: 5px;
124
+ margin: 2px 0px 2px 0px;
125
+ }
126
+
127
+ div.template_name {
128
+ cursor: pointer;
129
+ }
130
+
131
+ div.template_name:hover {
132
+ background-color: white;
133
+ }
@@ -0,0 +1,301 @@
1
+ require 'optparse'
2
+ require 'set'
3
+
4
+ #Parses command line arguments for Brakeman
5
+ module Brakeman::Options
6
+
7
+ class << self
8
+
9
+ #Parse argument array
10
+ def parse args
11
+ get_options args
12
+ end
13
+
14
+ #Parse arguments and remove them from the array as they are matched
15
+ def parse! args
16
+ get_options args, true
17
+ end
18
+
19
+ #Return hash of options and the parser
20
+ def get_options args, destructive = false
21
+ options = {}
22
+
23
+ parser = OptionParser.new do |opts|
24
+ opts.banner = "Usage: brakeman [options] rails/root/path"
25
+
26
+ opts.on "-n", "--no-threads", "Run checks sequentially" do
27
+ options[:parallel_checks] = false
28
+ end
29
+
30
+ opts.on "--[no-]progress", "Show progress reports" do |progress|
31
+ options[:report_progress] = progress
32
+ end
33
+
34
+ opts.on "-p", "--path PATH", "Specify path to Rails application" do |path|
35
+ options[:app_path] = path
36
+ end
37
+
38
+ opts.on "-q", "--[no-]quiet", "Suppress informational messages" do |quiet|
39
+ options[:quiet] = quiet
40
+ end
41
+
42
+ opts.on( "-z", "--exit-on-warn", "Exit code is non-zero if warnings found") do
43
+ options[:exit_on_warn] = true
44
+ end
45
+
46
+ opts.on "-3", "--rails3", "Force Rails 3 mode" do
47
+ options[:rails3] = true
48
+ end
49
+
50
+ opts.on "-4", "--rails4", "Force Rails 4 mode" do
51
+ options[:rails3] = true
52
+ options[:rails4] = true
53
+ end
54
+
55
+ opts.on "-5", "--rails5", "Force Rails 5 mode" do
56
+ options[:rails3] = true
57
+ options[:rails4] = true
58
+ options[:rails5] = true
59
+ end
60
+
61
+ opts.separator ""
62
+ opts.separator "Scanning options:"
63
+
64
+ opts.on "-A", "--run-all-checks", "Run all default and optional checks" do
65
+ options[:run_all_checks] = true
66
+ end
67
+
68
+ opts.on "-a", "--[no-]assume-routes", "Assume all controller methods are actions (default)" do |assume|
69
+ options[:assume_all_routes] = assume
70
+ end
71
+
72
+ opts.on "-e", "--escape-html", "Escape HTML by default" do
73
+ options[:escape_html] = true
74
+ end
75
+
76
+ opts.on "--faster", "Faster, but less accurate scan" do
77
+ options[:ignore_ifs] = true
78
+ options[:skip_libs] = true
79
+ end
80
+
81
+ opts.on "--ignore-model-output", "Consider model attributes XSS-safe" do
82
+ options[:ignore_model_output] = true
83
+ end
84
+
85
+ opts.on "--ignore-protected", "Consider models with attr_protected safe" do
86
+ options[:ignore_attr_protected] = true
87
+ end
88
+
89
+ opts.on "--[no-]index-libs", "Add libraries to call index (default)" do |index|
90
+ options[:index_libs] = index
91
+ end
92
+
93
+ opts.on "--interprocedural", "Process method calls to known methods" do
94
+ options[:interprocedural] = true
95
+ end
96
+
97
+ opts.on "--no-branching", "Disable flow sensitivity on conditionals" do
98
+ options[:ignore_ifs] = true
99
+ end
100
+
101
+ opts.on "--branch-limit LIMIT", Integer, "Limit depth of values in branches (-1 for no limit)" do |limit|
102
+ options[:branch_limit] = limit
103
+ end
104
+
105
+ opts.on "-r", "--report-direct", "Only report direct use of untrusted data" do |option|
106
+ options[:check_arguments] = !option
107
+ end
108
+
109
+ opts.on "-s", "--safe-methods meth1,meth2,etc", Array, "Set methods as safe for unescaped output in views" do |methods|
110
+ options[:safe_methods] ||= Set.new
111
+ options[:safe_methods].merge methods.map {|e| e.to_sym }
112
+ end
113
+
114
+ opts.on "--url-safe-methods method1,method2,etc", Array, "Do not warn of XSS if the link_to href parameter is wrapped in a safe method" do |methods|
115
+ options[:url_safe_methods] ||= Set.new
116
+ options[:url_safe_methods].merge methods.map {|e| e.to_sym }
117
+ end
118
+
119
+ opts.on "--skip-files file1,path2,etc", Array, "Skip processing of these files/directories. Directories are application relative and must end in \"#{File::SEPARATOR}\"" do |files|
120
+ options[:skip_files] ||= Set.new
121
+ options[:skip_files].merge files
122
+ end
123
+
124
+ opts.on "--only-files file1,path2,etc", Array, "Process only these files/directories. Directories are application relative and must end in \"#{File::SEPARATOR}\"" do |files|
125
+ options[:only_files] ||= Set.new
126
+ options[:only_files].merge files
127
+ end
128
+
129
+ opts.on "--skip-libs", "Skip processing lib directory" do
130
+ options[:skip_libs] = true
131
+ end
132
+
133
+ opts.on "--add-libs-path path1,path2,etc", Array, "An application relative lib directory (ex. app/mailers) to process" do |paths|
134
+ options[:additional_libs_path] ||= Set.new
135
+ options[:additional_libs_path].merge paths
136
+ end
137
+
138
+ opts.on "-t", "--test Check1,Check2,etc", Array, "Only run the specified checks" do |checks|
139
+ checks.each_with_index do |s, index|
140
+ if s[0,5] != "Check"
141
+ checks[index] = "Check" << s
142
+ end
143
+ end
144
+
145
+ options[:run_checks] ||= Set.new
146
+ options[:run_checks].merge checks
147
+ end
148
+
149
+ opts.on "-x", "--except Check1,Check2,etc", Array, "Skip the specified checks" do |skip|
150
+ skip.each do |s|
151
+ if s[0,5] != "Check"
152
+ s = "Check" << s
153
+ end
154
+
155
+ options[:skip_checks] ||= Set.new
156
+ options[:skip_checks] << s
157
+ end
158
+ end
159
+
160
+ opts.on "--add-checks-path path1,path2,etc", Array, "A directory containing additional out-of-tree checks to run" do |paths|
161
+ options[:additional_checks_path] ||= Set.new
162
+ options[:additional_checks_path].merge paths.map {|p| File.expand_path p}
163
+ end
164
+
165
+ opts.separator ""
166
+ opts.separator "Output options:"
167
+
168
+ opts.on "-d", "--debug", "Lots of output" do
169
+ options[:debug] = true
170
+ end
171
+
172
+ opts.on "-f",
173
+ "--format TYPE",
174
+ [:pdf, :text, :html, :csv, :tabs, :json, :markdown, :codeclimate, :cc],
175
+ "Specify output formats. Default is text" do |type|
176
+
177
+ type = "s" if type == :text
178
+ options[:output_format] = ("to_" << type.to_s).to_sym
179
+ end
180
+
181
+ opts.on "--css-file CSSFile", "Specify CSS to use for HTML output" do |file|
182
+ options[:html_style] = File.expand_path file
183
+ end
184
+
185
+ opts.on "-i IGNOREFILE", "--ignore-config IGNOREFILE", "Use configuration to ignore warnings" do |file|
186
+ options[:ignore_file] = file
187
+ end
188
+
189
+ opts.on "-I", "--interactive-ignore", "Interactively ignore warnings" do
190
+ options[:interactive_ignore] = true
191
+ end
192
+
193
+ opts.on "-l", "--[no-]combine-locations", "Combine warning locations (Default)" do |combine|
194
+ options[:combine_locations] = combine
195
+ end
196
+
197
+ opts.on "--[no-]highlights", "Highlight user input in report" do |highlight|
198
+ options[:highlight_user_input] = highlight
199
+ end
200
+
201
+ opts.on "-m", "--routes", "Report controller information" do
202
+ options[:report_routes] = true
203
+ end
204
+
205
+ opts.on "--message-limit LENGTH", "Limit message length in HTML report" do |limit|
206
+ options[:message_limit] = limit.to_i
207
+ end
208
+
209
+ opts.on "--table-width WIDTH", "Limit table width in text report" do |width|
210
+ options[:table_width] = width.to_i
211
+ end
212
+
213
+ opts.on "-o", "--output FILE", "Specify files for output. Defaults to stdout. Multiple '-o's allowed" do |file|
214
+ options[:output_files] ||= []
215
+ options[:output_files].push(file)
216
+ end
217
+
218
+ opts.on "--[no-]separate-models", "Warn on each model without attr_accessible (Default)" do |separate|
219
+ options[:collapse_mass_assignment] = !separate
220
+ end
221
+
222
+ opts.on "--summary", "Only output summary of warnings" do
223
+ options[:summary_only] = true
224
+ end
225
+
226
+ opts.on "--absolute-paths", "Output absolute file paths in reports" do
227
+ options[:absolute_paths] = true
228
+ end
229
+
230
+ opts.on "--github-repo USER/REPO[/PATH][@REF]", "Output links to GitHub in markdown and HTML reports using specified repo" do |repo|
231
+ options[:github_repo] = repo
232
+ end
233
+
234
+ opts.on "-w",
235
+ "--confidence-level LEVEL",
236
+ ["1", "2", "3"],
237
+ "Set minimal confidence level (1 - 3)" do |level|
238
+
239
+ options[:min_confidence] = 3 - level.to_i
240
+ end
241
+
242
+ opts.on "--compare FILE", "Compare the results of a previous brakeman scan (only JSON is supported)" do |file|
243
+ options[:previous_results_json] = File.expand_path(file)
244
+ end
245
+
246
+ opts.separator ""
247
+ opts.separator "Configuration files:"
248
+
249
+ opts.on "-c", "--config-file FILE", "Use specified configuration file" do |file|
250
+ options[:config_file] = File.expand_path(file)
251
+ end
252
+
253
+ opts.on "-C", "--create-config [FILE]", "Output configuration file based on options" do |file|
254
+ if file
255
+ options[:create_config] = file
256
+ else
257
+ options[:create_config] = true
258
+ end
259
+ end
260
+
261
+ opts.separator ""
262
+
263
+ opts.on "-k", "--checks", "List all available vulnerability checks" do
264
+ options[:list_checks] = true
265
+ end
266
+
267
+ opts.on "--optional-checks", "List optional checks" do
268
+ options[:list_optional_checks] = true
269
+ end
270
+
271
+ opts.on "--rake", "Create rake task to run Brakeman" do
272
+ options[:install_rake_task] = true
273
+ end
274
+
275
+ opts.on "-v", "--version", "Show Brakeman version" do
276
+ options[:show_version] = true
277
+ end
278
+
279
+ opts.on "--force-scan", "Scan application even if rails is not detected" do
280
+ options[:force_scan] = true
281
+ end
282
+
283
+ opts.on_tail "-h", "--help", "Display this message" do
284
+ options[:show_help] = true
285
+ end
286
+ end
287
+
288
+ if destructive
289
+ parser.parse! args
290
+ else
291
+ parser.parse args
292
+ end
293
+
294
+ if options[:previous_results_json] and options[:output_files]
295
+ options[:comparison_output_file] = options[:output_files].shift
296
+ end
297
+
298
+ return options, parser
299
+ end
300
+ end
301
+ end