brakeman-lib 3.3.1

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.
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