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