brakeman 3.1.2 → 3.1.3
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 +4 -4
- data/CHANGES +14 -0
- data/README.md +4 -2
- data/bin/brakeman +1 -1
- data/lib/brakeman.rb +7 -4
- data/lib/brakeman/checks/check_mass_assignment.rb +1 -1
- data/lib/brakeman/checks/check_session_settings.rb +36 -14
- data/lib/brakeman/checks/check_without_protection.rb +18 -0
- data/lib/brakeman/options.rb +1 -1
- data/lib/brakeman/processors/alias_processor.rb +12 -7
- data/lib/brakeman/processors/controller_processor.rb +8 -3
- data/lib/brakeman/processors/lib/find_all_calls.rb +20 -1
- data/lib/brakeman/report.rb +4 -1
- data/lib/brakeman/report/config/remediation.yml +71 -0
- data/lib/brakeman/report/report_codeclimate.rb +68 -0
- data/lib/brakeman/version.rb +1 -1
- data/lib/brakeman/warning.rb +2 -0
- metadata +16 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0a5242c2a00eaa622ccfd793730c516642f1835c
|
4
|
+
data.tar.gz: 9e684857baaddfc23a7c8b517797e9361fd9d0a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 75051e388396af7a75b9f9773ba4f16971f1033441fc74dcc2968a0b5421e8cd4117d6f0e18b23d61c891aba78dcd02a24bb255786e559bd12f1b661be984089
|
7
|
+
data.tar.gz: 403638a85e9dff267149e9204cf4789a439112cbebb35df79191f8a036d981f916dc7dfb1a22488f677cda45ffee21f29e18123136db834be2febd0d82962fb7
|
data/CHANGES
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
# 3.1.3
|
2
|
+
|
3
|
+
* Check for session secret in secrets.yml
|
4
|
+
* Respect `exit_on_warn` in config file
|
5
|
+
* Avoid warning on `without_protection: true` with hash literals
|
6
|
+
* Make sure before_filter call with block is still a call
|
7
|
+
* CallIndex improvements
|
8
|
+
* Restore minimum Highline version (Kevin Glowacz)
|
9
|
+
* Add Code Climate output format (Ashley Baldwin-Hunter/Devon Blandin/John Pignata/Michael Bernstein)
|
10
|
+
* Iteratively replace values
|
11
|
+
* Output nil instead of false for user_input in JSON
|
12
|
+
* Depend on safe_yaml 1.0 or later
|
13
|
+
* Test coverage improvements for Brakema module (Bethany Rentz)
|
14
|
+
|
1
15
|
# 3.1.2
|
2
16
|
|
3
17
|
* Treat `current_user` like a model
|
data/README.md
CHANGED
@@ -6,7 +6,9 @@
|
|
6
6
|
|
7
7
|
# Brakeman
|
8
8
|
|
9
|
-
Brakeman is
|
9
|
+
Brakeman is an open source static analysis tool which checks Ruby on Rails applications for security vulnerabilities.
|
10
|
+
|
11
|
+
Check out [Brakeman Pro](https://brakemanpro.com/) if you are looking for a commercially-supported version with a GUI and advanced features.
|
10
12
|
|
11
13
|
# Installation
|
12
14
|
|
@@ -42,7 +44,7 @@ To specify an output file for the results:
|
|
42
44
|
|
43
45
|
brakeman -o output_file
|
44
46
|
|
45
|
-
The output format is determined by the file extension or by using the `-f` option. Current options are: `text`, `html`, `tabs`, `json`, `markdown`, and `
|
47
|
+
The output format is determined by the file extension or by using the `-f` option. Current options are: `text`, `html`, `tabs`, `json`, `markdown`, `csv`, and `codeclimate`.
|
46
48
|
|
47
49
|
Multiple output files can be specified:
|
48
50
|
|
data/bin/brakeman
CHANGED
@@ -78,7 +78,7 @@ begin
|
|
78
78
|
tracker = Brakeman.run options.merge(:print_report => true, :quiet => options[:quiet])
|
79
79
|
|
80
80
|
#Return error code if --exit-on-warn is used and warnings were found
|
81
|
-
if options[:exit_on_warn] and not tracker.filtered_warnings.empty?
|
81
|
+
if tracker.options[:exit_on_warn] and not tracker.filtered_warnings.empty?
|
82
82
|
exit Brakeman::Warnings_Found_Exit_Code
|
83
83
|
end
|
84
84
|
end
|
data/lib/brakeman.rb
CHANGED
@@ -97,7 +97,7 @@ module Brakeman
|
|
97
97
|
|
98
98
|
if options
|
99
99
|
options.each { |k, v| options[k] = Set.new v if v.is_a? Array }
|
100
|
-
|
100
|
+
|
101
101
|
# After parsing the yaml config file for options, convert any string keys into symbols.
|
102
102
|
options.keys.select {|k| k.is_a? String}.map {|k| k.to_sym }.each {|k| options[k] = options[k.to_s]; options.delete(k.to_s) }
|
103
103
|
|
@@ -180,6 +180,8 @@ module Brakeman
|
|
180
180
|
[:to_json]
|
181
181
|
when :markdown, :to_markdown
|
182
182
|
[:to_markdown]
|
183
|
+
when :cc, :to_cc, :codeclimate, :to_codeclimate
|
184
|
+
[:to_codeclimate]
|
183
185
|
else
|
184
186
|
[:to_s]
|
185
187
|
end
|
@@ -201,6 +203,8 @@ module Brakeman
|
|
201
203
|
:to_json
|
202
204
|
when /\.md$/i
|
203
205
|
:to_markdown
|
206
|
+
when /(\.cc|\.codeclimate)$/i
|
207
|
+
:to_codeclimate
|
204
208
|
else
|
205
209
|
:to_s
|
206
210
|
end
|
@@ -303,11 +307,10 @@ module Brakeman
|
|
303
307
|
File.open file, "w" do |f|
|
304
308
|
YAML.dump options, f
|
305
309
|
end
|
306
|
-
|
310
|
+
notify "Output configuration to #{file}"
|
307
311
|
else
|
308
|
-
|
312
|
+
notify YAML.dump(options)
|
309
313
|
end
|
310
|
-
exit
|
311
314
|
end
|
312
315
|
|
313
316
|
#Run a scan. Generally called from Brakeman.run instead of directly.
|
@@ -155,7 +155,7 @@ class Brakeman::CheckMassAssignment < Brakeman::BaseCheck
|
|
155
155
|
# Look for and warn about uses of Parameters#permit! for mass assignment
|
156
156
|
def check_permit!
|
157
157
|
tracker.find_call(:method => :permit!).each do |result|
|
158
|
-
if params? result[:target
|
158
|
+
if params? result[:call].target
|
159
159
|
warn_on_permit! result
|
160
160
|
end
|
161
161
|
end
|
@@ -19,13 +19,17 @@ class Brakeman::CheckSessionSettings < Brakeman::BaseCheck
|
|
19
19
|
def run_check
|
20
20
|
settings = tracker.config.session_settings
|
21
21
|
|
22
|
-
check_for_issues settings, "
|
22
|
+
check_for_issues settings, @app_tree.expand_path("config/environment.rb")
|
23
23
|
|
24
24
|
["session_store.rb", "secret_token.rb"].each do |file|
|
25
25
|
if tracker.initializers[file] and not ignored? file
|
26
26
|
process tracker.initializers[file]
|
27
27
|
end
|
28
28
|
end
|
29
|
+
|
30
|
+
if tracker.options[:rails4]
|
31
|
+
check_secrets_yaml
|
32
|
+
end
|
29
33
|
end
|
30
34
|
|
31
35
|
#Looks for ActionController::Base.session = { ... }
|
@@ -38,13 +42,13 @@ class Brakeman::CheckSessionSettings < Brakeman::BaseCheck
|
|
38
42
|
#in Rails 4.x apps
|
39
43
|
def process_attrasgn exp
|
40
44
|
if not tracker.options[:rails3] and exp.target == @session_settings and exp.method == :session=
|
41
|
-
check_for_issues exp.first_arg, "
|
45
|
+
check_for_issues exp.first_arg, @app_tree.expand_path("config/initializers/session_store.rb")
|
42
46
|
end
|
43
47
|
|
44
48
|
if tracker.options[:rails3] and settings_target?(exp.target) and
|
45
49
|
(exp.method == :secret_token= or exp.method == :secret_key_base=) and string? exp.first_arg
|
46
50
|
|
47
|
-
warn_about_secret_token exp, "
|
51
|
+
warn_about_secret_token exp.line, @app_tree.expand_path("config/initializers/secret_token.rb")
|
48
52
|
end
|
49
53
|
|
50
54
|
exp
|
@@ -54,7 +58,7 @@ class Brakeman::CheckSessionSettings < Brakeman::BaseCheck
|
|
54
58
|
#in Rails 3.x apps
|
55
59
|
def process_call exp
|
56
60
|
if tracker.options[:rails3] and settings_target?(exp.target) and exp.method == :session_store
|
57
|
-
check_for_rails3_issues exp.second_arg, "
|
61
|
+
check_for_rails3_issues exp.second_arg, @app_tree.expand_path("config/initializers/session_store.rb")
|
58
62
|
end
|
59
63
|
|
60
64
|
exp
|
@@ -76,13 +80,13 @@ class Brakeman::CheckSessionSettings < Brakeman::BaseCheck
|
|
76
80
|
hash_access(settings, :httponly))
|
77
81
|
|
78
82
|
if false? value
|
79
|
-
warn_about_http_only value, file
|
83
|
+
warn_about_http_only value.line, file
|
80
84
|
end
|
81
85
|
end
|
82
86
|
|
83
87
|
if value = hash_access(settings, :secret)
|
84
88
|
if string? value
|
85
|
-
warn_about_secret_token value, file
|
89
|
+
warn_about_secret_token value.line, file
|
86
90
|
end
|
87
91
|
end
|
88
92
|
end
|
@@ -92,43 +96,61 @@ class Brakeman::CheckSessionSettings < Brakeman::BaseCheck
|
|
92
96
|
if settings and hash? settings
|
93
97
|
if value = hash_access(settings, :httponly)
|
94
98
|
if false? value
|
95
|
-
warn_about_http_only value, file
|
99
|
+
warn_about_http_only value.line, file
|
96
100
|
end
|
97
101
|
end
|
98
102
|
|
99
103
|
if value = hash_access(settings, :secure)
|
100
104
|
if false? value
|
101
|
-
warn_about_secure_only value, file
|
105
|
+
warn_about_secure_only value.line, file
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def check_secrets_yaml
|
112
|
+
secrets_file = "config/secrets.yml"
|
113
|
+
|
114
|
+
if @app_tree.exists? secrets_file
|
115
|
+
yaml = @app_tree.read secrets_file
|
116
|
+
require 'safe_yaml/load'
|
117
|
+
secrets = SafeYAML.load yaml
|
118
|
+
|
119
|
+
if secrets["production"] and secret = secrets["production"]["secret_key_base"]
|
120
|
+
unless secret.include? "<%="
|
121
|
+
line = yaml.lines.find_index { |l| l.include? secret } + 1
|
122
|
+
|
123
|
+
warn_about_secret_token line, @app_tree.expand_path(secrets_file)
|
102
124
|
end
|
103
125
|
end
|
104
126
|
end
|
105
127
|
end
|
106
128
|
|
107
|
-
def warn_about_http_only
|
129
|
+
def warn_about_http_only line, file
|
108
130
|
warn :warning_type => "Session Setting",
|
109
131
|
:warning_code => :http_cookies,
|
110
132
|
:message => "Session cookies should be set to HTTP only",
|
111
133
|
:confidence => CONFIDENCE[:high],
|
112
|
-
:line =>
|
134
|
+
:line => line,
|
113
135
|
:file => file
|
114
136
|
|
115
137
|
end
|
116
138
|
|
117
|
-
def warn_about_secret_token
|
139
|
+
def warn_about_secret_token line, file
|
118
140
|
warn :warning_type => "Session Setting",
|
119
141
|
:warning_code => :session_secret,
|
120
142
|
:message => "Session secret should not be included in version control",
|
121
143
|
:confidence => CONFIDENCE[:high],
|
122
|
-
:line =>
|
144
|
+
:line => line,
|
123
145
|
:file => file
|
124
146
|
end
|
125
147
|
|
126
|
-
def warn_about_secure_only
|
148
|
+
def warn_about_secure_only line, file
|
127
149
|
warn :warning_type => "Session Setting",
|
128
150
|
:warning_code => :secure_cookies,
|
129
151
|
:message => "Session cookie should be set to secure only",
|
130
152
|
:confidence => CONFIDENCE[:high],
|
131
|
-
:line =>
|
153
|
+
:line => line,
|
132
154
|
:file => file
|
133
155
|
end
|
134
156
|
|
@@ -43,6 +43,8 @@ class Brakeman::CheckWithoutProtection < Brakeman::BaseCheck
|
|
43
43
|
|
44
44
|
if input = include_user_input?(call.arglist)
|
45
45
|
confidence = CONFIDENCE[:high]
|
46
|
+
elsif all_literals? call
|
47
|
+
return
|
46
48
|
else
|
47
49
|
confidence = CONFIDENCE[:med]
|
48
50
|
end
|
@@ -59,4 +61,20 @@ class Brakeman::CheckWithoutProtection < Brakeman::BaseCheck
|
|
59
61
|
end
|
60
62
|
end
|
61
63
|
end
|
64
|
+
|
65
|
+
def all_literals? call
|
66
|
+
call.each_arg do |arg|
|
67
|
+
if hash? arg
|
68
|
+
hash_iterate arg do |k, v|
|
69
|
+
unless node_type? k, :str, :lit, :false, :true and node_type? v, :str, :lit, :false, :true
|
70
|
+
return false
|
71
|
+
end
|
72
|
+
end
|
73
|
+
else
|
74
|
+
return false
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
true
|
79
|
+
end
|
62
80
|
end
|
data/lib/brakeman/options.rb
CHANGED
@@ -165,7 +165,7 @@ module Brakeman::Options
|
|
165
165
|
|
166
166
|
opts.on "-f",
|
167
167
|
"--format TYPE",
|
168
|
-
[:pdf, :text, :html, :csv, :tabs, :json, :markdown],
|
168
|
+
[:pdf, :text, :html, :csv, :tabs, :json, :markdown, :codeclimate, :cc],
|
169
169
|
"Specify output formats. Default is text" do |type|
|
170
170
|
|
171
171
|
type = "s" if type == :text
|
@@ -62,18 +62,23 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
62
62
|
@tracker.error err if @tracker
|
63
63
|
end
|
64
64
|
|
65
|
-
|
66
|
-
|
67
|
-
result = replacement.deep_clone(exp.line)
|
68
|
-
else
|
69
|
-
result = exp
|
70
|
-
end
|
71
|
-
|
65
|
+
result = replace(exp)
|
66
|
+
|
72
67
|
@exp_context.pop
|
73
68
|
|
74
69
|
result
|
75
70
|
end
|
76
71
|
|
72
|
+
def replace exp, int = 0
|
73
|
+
return exp if int > 3
|
74
|
+
|
75
|
+
if replacement = env[exp] and not duplicate? replacement
|
76
|
+
replace(replacement.deep_clone(exp.line), int + 1)
|
77
|
+
else
|
78
|
+
exp
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
77
82
|
ARRAY_CONST = s(:const, :Array)
|
78
83
|
HASH_CONST = s(:const, :Hash)
|
79
84
|
|
@@ -236,9 +236,14 @@ class Brakeman::ControllerProcessor < Brakeman::BaseProcessor
|
|
236
236
|
|
237
237
|
#Look for before_filters and add fake ones if necessary
|
238
238
|
def process_iter exp
|
239
|
-
|
240
|
-
|
241
|
-
|
239
|
+
if @current_method.nil? and call? exp.block_call
|
240
|
+
block_call_name = exp.block_call.method
|
241
|
+
|
242
|
+
if block_call_name == :before_filter or block_call_name == :before_action
|
243
|
+
add_fake_filter exp
|
244
|
+
else
|
245
|
+
super
|
246
|
+
end
|
242
247
|
else
|
243
248
|
super
|
244
249
|
end
|
@@ -126,7 +126,7 @@ class Brakeman::FindAllCalls < Brakeman::BasicProcessor
|
|
126
126
|
|
127
127
|
#Gets the target of a call as a Symbol
|
128
128
|
#if possible
|
129
|
-
def get_target exp
|
129
|
+
def get_target exp, include_calls = false
|
130
130
|
if sexp? exp
|
131
131
|
case exp.node_type
|
132
132
|
when :ivar, :lvar, :const, :lit
|
@@ -137,6 +137,23 @@ class Brakeman::FindAllCalls < Brakeman::BasicProcessor
|
|
137
137
|
class_name exp
|
138
138
|
when :self
|
139
139
|
@current_class || @current_module || nil
|
140
|
+
when :params, :session, :cookies
|
141
|
+
exp.node_type
|
142
|
+
when :call
|
143
|
+
if include_calls
|
144
|
+
if exp.target.nil?
|
145
|
+
exp.method
|
146
|
+
else
|
147
|
+
t = get_target(exp.target, :include_calls)
|
148
|
+
if t.is_a? Symbol
|
149
|
+
:"#{t}.#{exp.method}"
|
150
|
+
else
|
151
|
+
exp
|
152
|
+
end
|
153
|
+
end
|
154
|
+
else
|
155
|
+
exp
|
156
|
+
end
|
140
157
|
else
|
141
158
|
exp
|
142
159
|
end
|
@@ -187,6 +204,8 @@ class Brakeman::FindAllCalls < Brakeman::BasicProcessor
|
|
187
204
|
@in_target = true
|
188
205
|
process target
|
189
206
|
@in_target = already_in_target
|
207
|
+
|
208
|
+
target = get_target(target, :include_calls)
|
190
209
|
end
|
191
210
|
|
192
211
|
method = exp.method
|
data/lib/brakeman/report.rb
CHANGED
@@ -6,7 +6,7 @@ require 'brakeman/report/report_base'
|
|
6
6
|
class Brakeman::Report
|
7
7
|
attr_reader :tracker
|
8
8
|
|
9
|
-
VALID_FORMATS = [:to_html, :to_pdf, :to_csv, :to_json, :to_tabs, :to_hash, :to_s, :to_markdown]
|
9
|
+
VALID_FORMATS = [:to_html, :to_pdf, :to_csv, :to_json, :to_tabs, :to_hash, :to_s, :to_markdown, :to_codeclimate]
|
10
10
|
|
11
11
|
def initialize app_tree, tracker
|
12
12
|
@app_tree = app_tree
|
@@ -15,6 +15,9 @@ class Brakeman::Report
|
|
15
15
|
|
16
16
|
def format format
|
17
17
|
reporter = case format
|
18
|
+
when :to_codeclimate
|
19
|
+
require_report 'codeclimate'
|
20
|
+
Brakeman::Report::CodeClimate
|
18
21
|
when :to_csv
|
19
22
|
require_report 'csv'
|
20
23
|
Brakeman::Report::CSV
|
@@ -0,0 +1,71 @@
|
|
1
|
+
---
|
2
|
+
basic_auth_password: 300000
|
3
|
+
cross_site_scripting: 300000
|
4
|
+
xss_content_tag: 300000
|
5
|
+
CVE_2014_3514_call: 600000
|
6
|
+
all_default_routes: 2000000
|
7
|
+
unsafe_deserialize: 2000000
|
8
|
+
local_request_config: 100000
|
9
|
+
CVE_2012_3424: 4000000
|
10
|
+
CVE_2011_2932: 8000000
|
11
|
+
code_eval: 2000000
|
12
|
+
command_injection: 2000000
|
13
|
+
file_access: 2000000
|
14
|
+
CVE_2014_7829: 4000000
|
15
|
+
CVE_2011_2929: 4000000
|
16
|
+
csrf_protection_disabled: 4000000
|
17
|
+
CVE_2013_6414: 4000000
|
18
|
+
CVE_2013_4491: 4000000
|
19
|
+
CVE_2013_1856: 4000000
|
20
|
+
CVE_2015_3226: 4000000
|
21
|
+
CVE_2013_0333: 4000000
|
22
|
+
xss_link_to: 300000
|
23
|
+
xss_link_to_href: 300000
|
24
|
+
CVE_2011_0446: 300000
|
25
|
+
mass_assign_call: 2000000
|
26
|
+
dangerous_attr_accessible: 2000000
|
27
|
+
no_attr_accessible: 2000000
|
28
|
+
CVE_2013_0277: 2000000
|
29
|
+
CVE_2010_3933: 4000000
|
30
|
+
CVE_2014_0081: 300000
|
31
|
+
CVE_2011_2930: 600000
|
32
|
+
open_redirect: 300000
|
33
|
+
regex_dos: 600000
|
34
|
+
dynamic_render_path: 4000000
|
35
|
+
CVE_2014_0082: 4000000
|
36
|
+
cross_site_scripting_inline: 600000
|
37
|
+
CVE_2011_3186: 2000000
|
38
|
+
safe_buffer_vuln: 4000000
|
39
|
+
CVE_2013_1855: 4000000
|
40
|
+
CVE_2013_1857: 4000000
|
41
|
+
CVE_2012_3463: 600000
|
42
|
+
select_options_vuln: 4000000
|
43
|
+
dangerous_send: 600000
|
44
|
+
session_key_manipulation: 600000
|
45
|
+
http_cookies: 600000
|
46
|
+
session_secret: 600000
|
47
|
+
secure_cookies: 600000
|
48
|
+
CVE_2013_6416: 600000
|
49
|
+
CVE_2012_3464: 4000000
|
50
|
+
csrf_blacklist: 300000
|
51
|
+
auth_blacklist: 300000
|
52
|
+
sql_injection: 1200000
|
53
|
+
CVE-2012-2660: 4000000
|
54
|
+
CVE-2012-2661: 4000000
|
55
|
+
CVE-2012-2695: 4000000
|
56
|
+
CVE-2012-5664: 4000000
|
57
|
+
CVE-2013-0155: 4000000
|
58
|
+
CVE-2013-6417: 4000000
|
59
|
+
CVE-2014-3482: 4000000
|
60
|
+
CVE-2014-3483: 4000000
|
61
|
+
ssl_verification_bypass: 2500000
|
62
|
+
CVE_2011_2931: 4000000
|
63
|
+
unsafe_symbol_creation: 300000
|
64
|
+
translate_vuln: 300000
|
65
|
+
unsafe_constantize: 600000
|
66
|
+
unscoped_find: 300000
|
67
|
+
validation_regex: 300000
|
68
|
+
mass_assign_without_protection: 600000
|
69
|
+
CVE_2015_3227: 4000000
|
70
|
+
CVE_2013_0156: 4000000
|
71
|
+
weak_hash_digest: 800000
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require "json"
|
2
|
+
require "yaml"
|
3
|
+
|
4
|
+
class Brakeman::Report::CodeClimate < Brakeman::Report::Base
|
5
|
+
DOCUMENTATION_PATH = File.expand_path("../../../../docs/warning_types", __FILE__)
|
6
|
+
REMEDIATION_POINTS_CONFIG_PATH = File.expand_path("../config/remediation.yml", __FILE__)
|
7
|
+
REMEDIATION_POINTS_DEFAULT = 300_000
|
8
|
+
|
9
|
+
def generate_report
|
10
|
+
all_warnings.map { |warning| issue_json(warning) }.join("\0")
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def issue_json(warning)
|
16
|
+
warning_code_name = name_for(warning.warning_code)
|
17
|
+
|
18
|
+
{
|
19
|
+
type: "Issue",
|
20
|
+
check_name: warning_code_name,
|
21
|
+
description: warning.message,
|
22
|
+
categories: ["Security"],
|
23
|
+
severity: severity_level_for(warning.confidence),
|
24
|
+
remediation_points: remediation_points_for(warning_code_name),
|
25
|
+
location: {
|
26
|
+
path: warning.relative_path,
|
27
|
+
lines: {
|
28
|
+
begin: warning.line || 1
|
29
|
+
}
|
30
|
+
},
|
31
|
+
content: {
|
32
|
+
body: content_for(warning.warning_code, warning.link)
|
33
|
+
}
|
34
|
+
}.to_json
|
35
|
+
end
|
36
|
+
|
37
|
+
def severity_level_for(confidence)
|
38
|
+
if confidence == 0
|
39
|
+
"critical"
|
40
|
+
else
|
41
|
+
"normal"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def remediation_points_for(warning_code)
|
46
|
+
@remediation_points ||= YAML.load_file(REMEDIATION_POINTS_CONFIG_PATH)
|
47
|
+
@remediation_points.fetch(name_for(warning_code), REMEDIATION_POINTS_DEFAULT)
|
48
|
+
end
|
49
|
+
|
50
|
+
def name_for(warning_code)
|
51
|
+
@warning_codes ||= Brakeman::WarningCodes::Codes.invert
|
52
|
+
@warning_codes[warning_code].to_s
|
53
|
+
end
|
54
|
+
|
55
|
+
def content_for(warning_code, link)
|
56
|
+
@contents ||= {}
|
57
|
+
unless link.nil?
|
58
|
+
@contents[warning_code] ||= local_content_for(link) || "Read more: #{link}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def local_content_for(link)
|
63
|
+
directory = link.split("/").last
|
64
|
+
filename = File.join(DOCUMENTATION_PATH, directory, "index.markdown")
|
65
|
+
|
66
|
+
File.read(filename) if File.exist?(filename)
|
67
|
+
end
|
68
|
+
end
|
data/lib/brakeman/version.rb
CHANGED
data/lib/brakeman/warning.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: brakeman
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.1.
|
4
|
+
version: 3.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Collins
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain:
|
11
11
|
- brakeman-public_cert.pem
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-12-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: test-unit
|
@@ -91,16 +91,22 @@ dependencies:
|
|
91
91
|
name: highline
|
92
92
|
requirement: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - "
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
96
|
+
version: 1.6.20
|
97
|
+
- - "<"
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '2.0'
|
97
100
|
type: :runtime
|
98
101
|
prerelease: false
|
99
102
|
version_requirements: !ruby/object:Gem::Requirement
|
100
103
|
requirements:
|
101
|
-
- - "
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: 1.6.20
|
107
|
+
- - "<"
|
102
108
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
109
|
+
version: '2.0'
|
104
110
|
- !ruby/object:Gem::Dependency
|
105
111
|
name: erubis
|
106
112
|
requirement: !ruby/object:Gem::Requirement
|
@@ -189,14 +195,14 @@ dependencies:
|
|
189
195
|
requirements:
|
190
196
|
- - ">="
|
191
197
|
- !ruby/object:Gem::Version
|
192
|
-
version: '0'
|
198
|
+
version: '1.0'
|
193
199
|
type: :runtime
|
194
200
|
prerelease: false
|
195
201
|
version_requirements: !ruby/object:Gem::Requirement
|
196
202
|
requirements:
|
197
203
|
- - ">="
|
198
204
|
- !ruby/object:Gem::Version
|
199
|
-
version: '0'
|
205
|
+
version: '1.0'
|
200
206
|
description: Brakeman detects security vulnerabilities in Ruby on Rails applications
|
201
207
|
via static analysis.
|
202
208
|
email: gem@brakeman.org
|
@@ -315,12 +321,14 @@ files:
|
|
315
321
|
- lib/brakeman/processors/template_alias_processor.rb
|
316
322
|
- lib/brakeman/processors/template_processor.rb
|
317
323
|
- lib/brakeman/report.rb
|
324
|
+
- lib/brakeman/report/config/remediation.yml
|
318
325
|
- lib/brakeman/report/ignore/config.rb
|
319
326
|
- lib/brakeman/report/ignore/interactive.rb
|
320
327
|
- lib/brakeman/report/initializers/faster_csv.rb
|
321
328
|
- lib/brakeman/report/initializers/multi_json.rb
|
322
329
|
- lib/brakeman/report/renderer.rb
|
323
330
|
- lib/brakeman/report/report_base.rb
|
331
|
+
- lib/brakeman/report/report_codeclimate.rb
|
324
332
|
- lib/brakeman/report/report_csv.rb
|
325
333
|
- lib/brakeman/report/report_hash.rb
|
326
334
|
- lib/brakeman/report/report_html.rb
|