brakeman-lib 3.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGES +872 -0
- data/FEATURES +16 -0
- data/README.md +169 -0
- data/WARNING_TYPES +95 -0
- data/bin/brakeman +89 -0
- data/lib/brakeman.rb +495 -0
- data/lib/brakeman/app_tree.rb +161 -0
- data/lib/brakeman/brakeman.rake +17 -0
- data/lib/brakeman/call_index.rb +219 -0
- data/lib/brakeman/checks.rb +191 -0
- data/lib/brakeman/checks/base_check.rb +518 -0
- data/lib/brakeman/checks/check_basic_auth.rb +88 -0
- data/lib/brakeman/checks/check_basic_auth_timing_attack.rb +33 -0
- data/lib/brakeman/checks/check_content_tag.rb +160 -0
- data/lib/brakeman/checks/check_create_with.rb +75 -0
- data/lib/brakeman/checks/check_cross_site_scripting.rb +385 -0
- data/lib/brakeman/checks/check_default_routes.rb +86 -0
- data/lib/brakeman/checks/check_deserialize.rb +57 -0
- data/lib/brakeman/checks/check_detailed_exceptions.rb +55 -0
- data/lib/brakeman/checks/check_digest_dos.rb +38 -0
- data/lib/brakeman/checks/check_dynamic_finders.rb +49 -0
- data/lib/brakeman/checks/check_escape_function.rb +21 -0
- data/lib/brakeman/checks/check_evaluation.rb +36 -0
- data/lib/brakeman/checks/check_execute.rb +167 -0
- data/lib/brakeman/checks/check_file_access.rb +63 -0
- data/lib/brakeman/checks/check_file_disclosure.rb +35 -0
- data/lib/brakeman/checks/check_filter_skipping.rb +31 -0
- data/lib/brakeman/checks/check_forgery_setting.rb +74 -0
- data/lib/brakeman/checks/check_header_dos.rb +31 -0
- data/lib/brakeman/checks/check_i18n_xss.rb +48 -0
- data/lib/brakeman/checks/check_jruby_xml.rb +38 -0
- data/lib/brakeman/checks/check_json_encoding.rb +47 -0
- data/lib/brakeman/checks/check_json_parsing.rb +107 -0
- data/lib/brakeman/checks/check_link_to.rb +132 -0
- data/lib/brakeman/checks/check_link_to_href.rb +115 -0
- data/lib/brakeman/checks/check_mail_to.rb +49 -0
- data/lib/brakeman/checks/check_mass_assignment.rb +198 -0
- data/lib/brakeman/checks/check_mime_type_dos.rb +39 -0
- data/lib/brakeman/checks/check_model_attr_accessible.rb +55 -0
- data/lib/brakeman/checks/check_model_attributes.rb +119 -0
- data/lib/brakeman/checks/check_model_serialize.rb +67 -0
- data/lib/brakeman/checks/check_nested_attributes.rb +38 -0
- data/lib/brakeman/checks/check_nested_attributes_bypass.rb +58 -0
- data/lib/brakeman/checks/check_number_to_currency.rb +74 -0
- data/lib/brakeman/checks/check_quote_table_name.rb +40 -0
- data/lib/brakeman/checks/check_redirect.rb +215 -0
- data/lib/brakeman/checks/check_regex_dos.rb +69 -0
- data/lib/brakeman/checks/check_render.rb +92 -0
- data/lib/brakeman/checks/check_render_dos.rb +37 -0
- data/lib/brakeman/checks/check_render_inline.rb +54 -0
- data/lib/brakeman/checks/check_response_splitting.rb +21 -0
- data/lib/brakeman/checks/check_route_dos.rb +42 -0
- data/lib/brakeman/checks/check_safe_buffer_manipulation.rb +31 -0
- data/lib/brakeman/checks/check_sanitize_methods.rb +79 -0
- data/lib/brakeman/checks/check_secrets.rb +40 -0
- data/lib/brakeman/checks/check_select_tag.rb +60 -0
- data/lib/brakeman/checks/check_select_vulnerability.rb +60 -0
- data/lib/brakeman/checks/check_send.rb +48 -0
- data/lib/brakeman/checks/check_send_file.rb +19 -0
- data/lib/brakeman/checks/check_session_manipulation.rb +36 -0
- data/lib/brakeman/checks/check_session_settings.rb +170 -0
- data/lib/brakeman/checks/check_simple_format.rb +59 -0
- data/lib/brakeman/checks/check_single_quotes.rb +101 -0
- data/lib/brakeman/checks/check_skip_before_filter.rb +60 -0
- data/lib/brakeman/checks/check_sql.rb +660 -0
- data/lib/brakeman/checks/check_sql_cves.rb +101 -0
- data/lib/brakeman/checks/check_ssl_verify.rb +49 -0
- data/lib/brakeman/checks/check_strip_tags.rb +89 -0
- data/lib/brakeman/checks/check_symbol_dos.rb +64 -0
- data/lib/brakeman/checks/check_symbol_dos_cve.rb +30 -0
- data/lib/brakeman/checks/check_translate_bug.rb +45 -0
- data/lib/brakeman/checks/check_unsafe_reflection.rb +51 -0
- data/lib/brakeman/checks/check_unscoped_find.rb +41 -0
- data/lib/brakeman/checks/check_validation_regex.rb +116 -0
- data/lib/brakeman/checks/check_weak_hash.rb +151 -0
- data/lib/brakeman/checks/check_without_protection.rb +80 -0
- data/lib/brakeman/checks/check_xml_dos.rb +51 -0
- data/lib/brakeman/checks/check_yaml_parsing.rb +121 -0
- data/lib/brakeman/differ.rb +66 -0
- data/lib/brakeman/file_parser.rb +50 -0
- data/lib/brakeman/format/style.css +133 -0
- data/lib/brakeman/options.rb +301 -0
- data/lib/brakeman/parsers/rails2_erubis.rb +6 -0
- data/lib/brakeman/parsers/rails2_xss_plugin_erubis.rb +48 -0
- data/lib/brakeman/parsers/rails3_erubis.rb +74 -0
- data/lib/brakeman/parsers/template_parser.rb +89 -0
- data/lib/brakeman/processor.rb +102 -0
- data/lib/brakeman/processors/alias_processor.rb +1013 -0
- data/lib/brakeman/processors/base_processor.rb +277 -0
- data/lib/brakeman/processors/config_processor.rb +14 -0
- data/lib/brakeman/processors/controller_alias_processor.rb +273 -0
- data/lib/brakeman/processors/controller_processor.rb +326 -0
- data/lib/brakeman/processors/erb_template_processor.rb +80 -0
- data/lib/brakeman/processors/erubis_template_processor.rb +104 -0
- data/lib/brakeman/processors/gem_processor.rb +57 -0
- data/lib/brakeman/processors/haml_template_processor.rb +190 -0
- data/lib/brakeman/processors/lib/basic_processor.rb +37 -0
- data/lib/brakeman/processors/lib/find_all_calls.rb +223 -0
- data/lib/brakeman/processors/lib/find_call.rb +183 -0
- data/lib/brakeman/processors/lib/find_return_value.rb +134 -0
- data/lib/brakeman/processors/lib/processor_helper.rb +75 -0
- data/lib/brakeman/processors/lib/rails2_config_processor.rb +145 -0
- data/lib/brakeman/processors/lib/rails2_route_processor.rb +313 -0
- data/lib/brakeman/processors/lib/rails3_config_processor.rb +132 -0
- data/lib/brakeman/processors/lib/rails3_route_processor.rb +308 -0
- data/lib/brakeman/processors/lib/render_helper.rb +181 -0
- data/lib/brakeman/processors/lib/render_path.rb +107 -0
- data/lib/brakeman/processors/lib/route_helper.rb +68 -0
- data/lib/brakeman/processors/lib/safe_call_helper.rb +16 -0
- data/lib/brakeman/processors/library_processor.rb +119 -0
- data/lib/brakeman/processors/model_processor.rb +191 -0
- data/lib/brakeman/processors/output_processor.rb +171 -0
- data/lib/brakeman/processors/route_processor.rb +17 -0
- data/lib/brakeman/processors/slim_template_processor.rb +107 -0
- data/lib/brakeman/processors/template_alias_processor.rb +116 -0
- data/lib/brakeman/processors/template_processor.rb +74 -0
- data/lib/brakeman/report.rb +78 -0
- data/lib/brakeman/report/config/remediation.yml +71 -0
- data/lib/brakeman/report/ignore/config.rb +135 -0
- data/lib/brakeman/report/ignore/interactive.rb +311 -0
- data/lib/brakeman/report/renderer.rb +24 -0
- data/lib/brakeman/report/report_base.rb +286 -0
- data/lib/brakeman/report/report_codeclimate.rb +70 -0
- data/lib/brakeman/report/report_csv.rb +55 -0
- data/lib/brakeman/report/report_hash.rb +23 -0
- data/lib/brakeman/report/report_html.rb +216 -0
- data/lib/brakeman/report/report_json.rb +42 -0
- data/lib/brakeman/report/report_markdown.rb +156 -0
- data/lib/brakeman/report/report_table.rb +107 -0
- data/lib/brakeman/report/report_tabs.rb +17 -0
- data/lib/brakeman/report/templates/controller_overview.html.erb +22 -0
- data/lib/brakeman/report/templates/controller_warnings.html.erb +21 -0
- data/lib/brakeman/report/templates/error_overview.html.erb +29 -0
- data/lib/brakeman/report/templates/header.html.erb +58 -0
- data/lib/brakeman/report/templates/ignored_warnings.html.erb +25 -0
- data/lib/brakeman/report/templates/model_warnings.html.erb +21 -0
- data/lib/brakeman/report/templates/overview.html.erb +38 -0
- data/lib/brakeman/report/templates/security_warnings.html.erb +23 -0
- data/lib/brakeman/report/templates/template_overview.html.erb +21 -0
- data/lib/brakeman/report/templates/view_warnings.html.erb +34 -0
- data/lib/brakeman/report/templates/warning_overview.html.erb +17 -0
- data/lib/brakeman/rescanner.rb +483 -0
- data/lib/brakeman/scanner.rb +317 -0
- data/lib/brakeman/tracker.rb +347 -0
- data/lib/brakeman/tracker/collection.rb +93 -0
- data/lib/brakeman/tracker/config.rb +101 -0
- data/lib/brakeman/tracker/constants.rb +101 -0
- data/lib/brakeman/tracker/controller.rb +161 -0
- data/lib/brakeman/tracker/library.rb +17 -0
- data/lib/brakeman/tracker/model.rb +90 -0
- data/lib/brakeman/tracker/template.rb +33 -0
- data/lib/brakeman/util.rb +481 -0
- data/lib/brakeman/version.rb +3 -0
- data/lib/brakeman/warning.rb +255 -0
- data/lib/brakeman/warning_codes.rb +111 -0
- data/lib/ruby_parser/bm_sexp.rb +610 -0
- data/lib/ruby_parser/bm_sexp_processor.rb +116 -0
- 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
|