brakeman-min 2.4.3 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- checksums.yaml.gz.sig +3 -0
- data.tar.gz.sig +0 -0
- data/CHANGES +15 -0
- data/lib/brakeman.rb +22 -0
- data/lib/brakeman/checks/base_check.rb +1 -1
- data/lib/brakeman/checks/check_number_to_currency.rb +2 -0
- data/lib/brakeman/checks/check_redirect.rb +15 -1
- data/lib/brakeman/checks/check_regex_dos.rb +69 -0
- data/lib/brakeman/checks/check_select_vulnerability.rb +3 -1
- data/lib/brakeman/checks/check_skip_before_filter.rb +1 -1
- data/lib/brakeman/checks/check_sql.rb +10 -89
- data/lib/brakeman/checks/check_sql_cves.rb +89 -0
- data/lib/brakeman/checks/check_symbol_dos.rb +6 -4
- data/lib/brakeman/options.rb +6 -2
- data/lib/brakeman/processors/controller_processor.rb +4 -3
- data/lib/brakeman/processors/lib/find_all_calls.rb +13 -0
- data/lib/brakeman/processors/lib/rails3_route_processor.rb +6 -1
- data/lib/brakeman/processors/output_processor.rb +7 -0
- data/lib/brakeman/report.rb +8 -1
- data/lib/brakeman/report/report_html.rb +6 -1
- data/lib/brakeman/report/report_markdown.rb +158 -0
- data/lib/brakeman/util.rb +9 -0
- data/lib/brakeman/version.rb +1 -1
- data/lib/brakeman/warning_codes.rb +1 -0
- metadata +93 -106
- metadata.gz.sig +0 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
OTcwMjUwMDYwZjJjMmZhZTY4YjBmM2ZjZjBkMmYyZWVmZmFmYTlmZQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
N2M5MTJlYmMwMjViN2RlMWUxODYwODZlNDBmY2NmMzFhYjNhZTkxOA==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
OWRiNDM3ZmYzNWExNGJmZWUyNmE0MDRiODA5YzkxMjgzNWRlMDBlNjBiZTky
|
10
|
+
OTQ1MTZhNmU0YjQ0MjcyZDRkNzY1NzJjNDZkYmM3NjE1NzY2YTZlY2NkZjQx
|
11
|
+
NDFmOTAxYjJhYjI1NDBlMmE3NjkzNTIwZDYwNWEzYzRkNjQ5YjA=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
YzU0ZDU0YmZkNDM4MjhiYzZkMTMzNmNjNzVkY2U1NTg4MTJiODY1ODZiMTc1
|
14
|
+
YmJjYjY0OTVkZTVmZDhlYmI1YWE4ZDYyZTViMTgxYTEzMjZmNTQzZjFlZGFm
|
15
|
+
ZmFhOTc5NGQzZWQ4M2QxYzc5ZTA1YjAxMDQwNjg0MjA4Mjk1OTQ=
|
checksums.yaml.gz.sig
ADDED
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGES
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
# 2.5.0
|
2
|
+
|
3
|
+
* Add support for RailsLTS 2.3.18.7 and 2.3.18.8
|
4
|
+
* Add support for Rails 4 `before_actions` and friends
|
5
|
+
* Move SQLi CVE checks to `CheckSQLCVEs`
|
6
|
+
* Check for protected_attributes gem
|
7
|
+
* Fix SQLi detection in chain calls in scopes
|
8
|
+
* Add GitHub-flavored Markdown output format (Greg Ose)
|
9
|
+
* Fix false positives when sanitize() is used in SQL (Jeff Yip)
|
10
|
+
* Add String#intern and Hash#symbolize_keys DoS check (Jan Rusnacko)
|
11
|
+
* Check all arguments in Model.select for SQLi
|
12
|
+
* Fix false positive when :host is specified in redirect
|
13
|
+
* Handle more non-literals in routes
|
14
|
+
* Add check for regex denial of service (Ben Toews)
|
15
|
+
|
1
16
|
# 2.4.3
|
2
17
|
|
3
18
|
No changes. 2.4.2 gem release was unsigned, 2.4.3 is signed.
|
data/lib/brakeman.rb
CHANGED
@@ -24,6 +24,7 @@ module Brakeman
|
|
24
24
|
# * :config_file - configuration file
|
25
25
|
# * :escape_html - escape HTML by default (automatic)
|
26
26
|
# * :exit_on_warn - return false if warnings found, true otherwise. Not recommended for library use (default: false)
|
27
|
+
# * :github_repo - github repo to use for file links (user/repo[/path][@ref])
|
27
28
|
# * :highlight_user_input - highlight user input in reported warnings (default: true)
|
28
29
|
# * :html_style - path to CSS file
|
29
30
|
# * :ignore_model_output - consider models safe (default: false)
|
@@ -77,6 +78,7 @@ module Brakeman
|
|
77
78
|
|
78
79
|
options[:app_path] = File.expand_path(options[:app_path])
|
79
80
|
options[:output_formats] = get_output_formats options
|
81
|
+
options[:github_url] = get_github_url options
|
80
82
|
|
81
83
|
options
|
82
84
|
end
|
@@ -166,6 +168,8 @@ module Brakeman
|
|
166
168
|
[:to_tabs]
|
167
169
|
when :json, :to_json
|
168
170
|
[:to_json]
|
171
|
+
when :markdown, :to_markdown
|
172
|
+
[:to_markdown]
|
169
173
|
else
|
170
174
|
[:to_s]
|
171
175
|
end
|
@@ -185,6 +189,8 @@ module Brakeman
|
|
185
189
|
:to_tabs
|
186
190
|
when /\.json$/i
|
187
191
|
:to_json
|
192
|
+
when /\.md$/i
|
193
|
+
:to_markdown
|
188
194
|
else
|
189
195
|
:to_s
|
190
196
|
end
|
@@ -192,6 +198,22 @@ module Brakeman
|
|
192
198
|
end
|
193
199
|
private_class_method :get_formats_from_output_files
|
194
200
|
|
201
|
+
def self.get_github_url options
|
202
|
+
if github_repo = options[:github_repo]
|
203
|
+
full_repo, ref = github_repo.split '@', 2
|
204
|
+
name, repo, path = full_repo.split '/', 3
|
205
|
+
unless name && repo && !(name.empty? || repo.empty?)
|
206
|
+
raise ArgumentError, "Invalid GitHub repository format"
|
207
|
+
end
|
208
|
+
path.chomp '/' if path
|
209
|
+
ref ||= 'master'
|
210
|
+
['https://github.com', name, repo, 'blob', ref, path].compact.join '/'
|
211
|
+
else
|
212
|
+
nil
|
213
|
+
end
|
214
|
+
end
|
215
|
+
private_class_method :get_github_url
|
216
|
+
|
195
217
|
#Output list of checks (for `-k` option)
|
196
218
|
def self.list_checks
|
197
219
|
require 'brakeman/scanner'
|
@@ -177,7 +177,7 @@ class Brakeman::BaseCheck < Brakeman::SexpProcessor
|
|
177
177
|
tracker.config[:rails][:active_record][:whitelist_attributes] == Sexp.new(:true)
|
178
178
|
|
179
179
|
@mass_assign_disabled = true
|
180
|
-
elsif version_between?("4.0.0", "4.9.9")
|
180
|
+
elsif version_between?("4.0.0", "4.9.9") and not tracker.config[:gems][:protected_attributes]
|
181
181
|
#May need to revisit dependng on what Rails 4 actually does/has
|
182
182
|
@mass_assign_disabled = true
|
183
183
|
else
|
@@ -31,7 +31,11 @@ class Brakeman::CheckRedirect < Brakeman::BaseCheck
|
|
31
31
|
|
32
32
|
method = call.method
|
33
33
|
|
34
|
-
if method == :redirect_to and
|
34
|
+
if method == :redirect_to and
|
35
|
+
not only_path?(call) and
|
36
|
+
not explicit_host?(call) and
|
37
|
+
res = include_user_input?(call)
|
38
|
+
|
35
39
|
add_result result
|
36
40
|
|
37
41
|
if res.type == :immediate
|
@@ -109,6 +113,16 @@ class Brakeman::CheckRedirect < Brakeman::BaseCheck
|
|
109
113
|
false
|
110
114
|
end
|
111
115
|
|
116
|
+
def explicit_host? call
|
117
|
+
arg = call.first_arg
|
118
|
+
|
119
|
+
if hash? arg and value = hash_access(arg, :host)
|
120
|
+
return !has_immediate_user_input?(value)
|
121
|
+
end
|
122
|
+
|
123
|
+
false
|
124
|
+
end
|
125
|
+
|
112
126
|
#+url_for+ is only_path => true by default. This checks to see if it is
|
113
127
|
#set to false for some reason.
|
114
128
|
def check_url_for call
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'brakeman/checks/base_check'
|
2
|
+
|
3
|
+
#This check looks for regexes that include user input.
|
4
|
+
class Brakeman::CheckRegexDoS < Brakeman::BaseCheck
|
5
|
+
Brakeman::Checks.add self
|
6
|
+
|
7
|
+
ESCAPES = {
|
8
|
+
s(:const, :Regexp) => [
|
9
|
+
:escape,
|
10
|
+
:quote
|
11
|
+
]
|
12
|
+
}
|
13
|
+
|
14
|
+
@description = "Searches regexes including user input"
|
15
|
+
|
16
|
+
#Process calls
|
17
|
+
def run_check
|
18
|
+
Brakeman.debug "Finding dynamic regexes"
|
19
|
+
calls = tracker.find_call :method => [:brakeman_regex_interp]
|
20
|
+
|
21
|
+
Brakeman.debug "Processing dynamic regexes"
|
22
|
+
calls.each do |call|
|
23
|
+
process_result call
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
#Warns if regex includes user input
|
28
|
+
def process_result result
|
29
|
+
return if duplicate? result
|
30
|
+
add_result result
|
31
|
+
|
32
|
+
call = result[:call]
|
33
|
+
components = call[1..-1]
|
34
|
+
|
35
|
+
components.any? do |component|
|
36
|
+
next unless sexp? component
|
37
|
+
|
38
|
+
if match = has_immediate_user_input?(component)
|
39
|
+
confidence = CONFIDENCE[:high]
|
40
|
+
elsif match = has_immediate_model?(component)
|
41
|
+
match = Match.new(:model, match)
|
42
|
+
confidence = CONFIDENCE[:med]
|
43
|
+
elsif match = include_user_input?(component)
|
44
|
+
confidence = CONFIDENCE[:low]
|
45
|
+
end
|
46
|
+
|
47
|
+
if match
|
48
|
+
message = "#{friendly_type_of(match).capitalize} used in regex"
|
49
|
+
|
50
|
+
warn :result => result,
|
51
|
+
:warning_type => "Denial of Service",
|
52
|
+
:warning_code => :regex_dos,
|
53
|
+
:message => message,
|
54
|
+
:confidence => confidence,
|
55
|
+
:user_input => match.match
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def process_call(exp)
|
61
|
+
if escape_methods = ESCAPES[exp.target]
|
62
|
+
if escape_methods.include? exp.method
|
63
|
+
return exp
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
super
|
68
|
+
end
|
69
|
+
end
|
@@ -9,7 +9,9 @@ class Brakeman::CheckSelectVulnerability < Brakeman::BaseCheck
|
|
9
9
|
|
10
10
|
def run_check
|
11
11
|
|
12
|
-
if
|
12
|
+
if lts_version? "2.3.18.7"
|
13
|
+
return
|
14
|
+
elsif version_between? "3.0.0", "3.0.11"
|
13
15
|
suggested_version = "3.0.12"
|
14
16
|
elsif version_between? "3.1.0", "3.1.3"
|
15
17
|
suggested_version = "3.1.4"
|
@@ -14,7 +14,7 @@ class Brakeman::CheckSkipBeforeFilter < Brakeman::BaseCheck
|
|
14
14
|
|
15
15
|
def run_check
|
16
16
|
tracker.controllers.each do |name, controller|
|
17
|
-
filter_skips =
|
17
|
+
filter_skips = controller[:options].values_at(:skip_before_filter, :skip_filter, :skip_before_action, :skip_action_callback).compact.flatten(1)
|
18
18
|
|
19
19
|
filter_skips.each do |filter|
|
20
20
|
process_skip_filter filter, controller
|
@@ -46,13 +46,8 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
46
46
|
Brakeman.debug "Finding calls to named_scope or scope"
|
47
47
|
calls.concat find_scope_calls
|
48
48
|
|
49
|
-
Brakeman.debug "Checking version of Rails for CVE issues"
|
50
|
-
check_rails_versions_against_cve_issues
|
51
|
-
|
52
49
|
Brakeman.debug "Processing possible SQL calls"
|
53
50
|
calls.each { |call| process_result call }
|
54
|
-
|
55
|
-
check_CVE_2014_0080
|
56
51
|
end
|
57
52
|
|
58
53
|
#Find calls to named_scope() or scope() in models
|
@@ -65,7 +60,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
65
60
|
call = make_call(nil, :named_scope, args).line(args.line)
|
66
61
|
scope_calls << scope_call_hash(call, name, :named_scope)
|
67
62
|
end
|
68
|
-
elsif version_between?("3.1.0", "
|
63
|
+
elsif version_between?("3.1.0", "4.9.9")
|
69
64
|
ar_scope_calls(:scope) do |name, args|
|
70
65
|
second_arg = args[2]
|
71
66
|
next unless sexp? second_arg
|
@@ -114,8 +109,12 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
114
109
|
find_calls.process_source(block, :class => model_name, :method => scope_name)
|
115
110
|
find_calls.calls.each { |call| process_result(call) if @sql_targets.include?(call[:method]) }
|
116
111
|
elsif block.node_type == :call
|
117
|
-
|
118
|
-
|
112
|
+
while call? block
|
113
|
+
process_result :target => block.target, :method => block.method, :call => block,
|
114
|
+
:location => { :type => :class, :class => model_name, :method => scope_name }
|
115
|
+
|
116
|
+
block = block.target
|
117
|
+
end
|
119
118
|
end
|
120
119
|
end
|
121
120
|
|
@@ -179,13 +178,13 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
179
178
|
check_order_arguments call.arglist
|
180
179
|
when :joins
|
181
180
|
check_joins_arguments call.first_arg
|
182
|
-
when :from
|
181
|
+
when :from
|
183
182
|
unsafe_sql? call.first_arg
|
184
183
|
when :lock
|
185
184
|
check_lock_arguments call.first_arg
|
186
185
|
when :pluck
|
187
186
|
unsafe_sql? call.first_arg
|
188
|
-
when :update_all
|
187
|
+
when :update_all, :select
|
189
188
|
check_update_all_arguments call.args
|
190
189
|
when *@connection_calls
|
191
190
|
check_by_sql_arguments call.first_arg
|
@@ -540,7 +539,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
540
539
|
:sanitize_sql, :sanitize_sql_array, :sanitize_sql_for_assignment,
|
541
540
|
:sanitize_sql_for_conditions, :sanitize_sql_hash,
|
542
541
|
:sanitize_sql_hash_for_assignment, :sanitize_sql_hash_for_conditions,
|
543
|
-
:to_sql]
|
542
|
+
:to_sql, :sanitize]
|
544
543
|
|
545
544
|
def safe_value? exp
|
546
545
|
return true unless sexp? exp
|
@@ -639,82 +638,4 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
639
638
|
active_record_models.include? klass
|
640
639
|
end
|
641
640
|
end
|
642
|
-
|
643
|
-
# TODO: Move all SQL CVE checks to separate class
|
644
|
-
def check_CVE_2014_0080
|
645
|
-
return unless version_between? "4.0.0", "4.0.2" and
|
646
|
-
@tracker.config[:gems].include? :pg
|
647
|
-
|
648
|
-
warn :warning_type => 'SQL Injection',
|
649
|
-
:warning_code => :CVE_2014_0080,
|
650
|
-
:message => "Rails #{tracker.config[:rails_version]} contains a SQL injection vulnerability (CVE-2014-0080) with PostgreSQL. Upgrade to 4.0.3",
|
651
|
-
:confidence => CONFIDENCE[:high],
|
652
|
-
:file => gemfile_or_environment,
|
653
|
-
:link_path => "https://groups.google.com/d/msg/rubyonrails-security/Wu96YkTUR6s/pPLBMZrlwvYJ"
|
654
|
-
end
|
655
|
-
|
656
|
-
def upgrade_version? versions
|
657
|
-
versions.each do |low, high, upgrade|
|
658
|
-
return upgrade if version_between? low, high
|
659
|
-
end
|
660
|
-
|
661
|
-
false
|
662
|
-
end
|
663
|
-
|
664
|
-
def check_rails_versions_against_cve_issues
|
665
|
-
issues = [
|
666
|
-
{
|
667
|
-
:cve => "CVE-2012-2660",
|
668
|
-
:versions => [%w[2.0.0 2.3.14 2.3.17], %w[3.0.0 3.0.12 3.0.13], %w[3.1.0 3.1.4 3.1.5], %w[3.2.0 3.2.3 3.2.4]],
|
669
|
-
:url => "https://groups.google.com/d/topic/rubyonrails-security/8SA-M3as7A8/discussion"
|
670
|
-
},
|
671
|
-
{
|
672
|
-
:cve => "CVE-2012-2661",
|
673
|
-
:versions => [%w[3.0.0 3.0.12 3.0.13], %w[3.1.0 3.1.4 3.1.5], %w[3.2.0 3.2.3 3.2.5]],
|
674
|
-
:url => "https://groups.google.com/d/topic/rubyonrails-security/dUaiOOGWL1k/discussion"
|
675
|
-
},
|
676
|
-
{
|
677
|
-
:cve => "CVE-2012-2695",
|
678
|
-
:versions => [%w[2.0.0 2.3.14 2.3.15], %w[3.0.0 3.0.13 3.0.14], %w[3.1.0 3.1.5 3.1.6], %w[3.2.0 3.2.5 3.2.6]],
|
679
|
-
:url => "https://groups.google.com/d/topic/rubyonrails-security/l4L0TEVAz1k/discussion"
|
680
|
-
},
|
681
|
-
{
|
682
|
-
:cve => "CVE-2012-5664",
|
683
|
-
:versions => [%w[2.0.0 2.3.14 2.3.15], %w[3.0.0 3.0.17 3.0.18], %w[3.1.0 3.1.8 3.1.9], %w[3.2.0 3.2.9 3.2.18]],
|
684
|
-
:url => "https://groups.google.com/d/topic/rubyonrails-security/DCNTNp_qjFM/discussion"
|
685
|
-
},
|
686
|
-
{
|
687
|
-
:cve => "CVE-2013-0155",
|
688
|
-
:versions => [%w[2.0.0 2.3.15 2.3.16], %w[3.0.0 3.0.18 3.0.19], %w[3.1.0 3.1.9 3.1.10], %w[3.2.0 3.2.10 3.2.11]],
|
689
|
-
:url => "https://groups.google.com/d/topic/rubyonrails-security/c7jT-EeN9eI/discussion"
|
690
|
-
},
|
691
|
-
|
692
|
-
]
|
693
|
-
|
694
|
-
unless lts_version? '2.3.18.6'
|
695
|
-
issues << {
|
696
|
-
:cve => "CVE-2013-6417",
|
697
|
-
:versions => [%w[2.0.0 3.2.15 3.2.16], %w[4.0.0 4.0.1 4.0.2]],
|
698
|
-
:url => "https://groups.google.com/d/msg/ruby-security-ann/niK4drpSHT4/g8JW8ZsayRkJ"
|
699
|
-
}
|
700
|
-
end
|
701
|
-
|
702
|
-
issues.each do |cve_issue|
|
703
|
-
cve_warning_for cve_issue[:versions], cve_issue[:cve], cve_issue[:url]
|
704
|
-
end
|
705
|
-
end
|
706
|
-
|
707
|
-
def cve_warning_for versions, cve, link
|
708
|
-
upgrade_version = upgrade_version? versions
|
709
|
-
return unless upgrade_version
|
710
|
-
|
711
|
-
code = cve.tr('-', '_').to_sym
|
712
|
-
|
713
|
-
warn :warning_type => 'SQL Injection',
|
714
|
-
:warning_code => code,
|
715
|
-
:message => "Rails #{tracker.config[:rails_version]} contains a SQL injection vulnerability (#{cve}). Upgrade to #{upgrade_version}",
|
716
|
-
:confidence => CONFIDENCE[:high],
|
717
|
-
:file => gemfile_or_environment,
|
718
|
-
:link_path => link
|
719
|
-
end
|
720
641
|
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'brakeman/checks/base_check'
|
2
|
+
|
3
|
+
class Brakeman::CheckSQLCVEs < Brakeman::BaseCheck
|
4
|
+
Brakeman::Checks.add self
|
5
|
+
|
6
|
+
@description = "Checks for several SQL CVEs"
|
7
|
+
|
8
|
+
def run_check
|
9
|
+
check_rails_versions_against_cve_issues
|
10
|
+
check_cve_2014_0080
|
11
|
+
end
|
12
|
+
|
13
|
+
def check_rails_versions_against_cve_issues
|
14
|
+
issues = [
|
15
|
+
{
|
16
|
+
:cve => "CVE-2012-2660",
|
17
|
+
:versions => [%w[2.0.0 2.3.14 2.3.17], %w[3.0.0 3.0.12 3.0.13], %w[3.1.0 3.1.4 3.1.5], %w[3.2.0 3.2.3 3.2.4]],
|
18
|
+
:url => "https://groups.google.com/d/topic/rubyonrails-security/8SA-M3as7A8/discussion"
|
19
|
+
},
|
20
|
+
{
|
21
|
+
:cve => "CVE-2012-2661",
|
22
|
+
:versions => [%w[3.0.0 3.0.12 3.0.13], %w[3.1.0 3.1.4 3.1.5], %w[3.2.0 3.2.3 3.2.5]],
|
23
|
+
:url => "https://groups.google.com/d/topic/rubyonrails-security/dUaiOOGWL1k/discussion"
|
24
|
+
},
|
25
|
+
{
|
26
|
+
:cve => "CVE-2012-2695",
|
27
|
+
:versions => [%w[2.0.0 2.3.14 2.3.15], %w[3.0.0 3.0.13 3.0.14], %w[3.1.0 3.1.5 3.1.6], %w[3.2.0 3.2.5 3.2.6]],
|
28
|
+
:url => "https://groups.google.com/d/topic/rubyonrails-security/l4L0TEVAz1k/discussion"
|
29
|
+
},
|
30
|
+
{
|
31
|
+
:cve => "CVE-2012-5664",
|
32
|
+
:versions => [%w[2.0.0 2.3.14 2.3.15], %w[3.0.0 3.0.17 3.0.18], %w[3.1.0 3.1.8 3.1.9], %w[3.2.0 3.2.9 3.2.18]],
|
33
|
+
:url => "https://groups.google.com/d/topic/rubyonrails-security/DCNTNp_qjFM/discussion"
|
34
|
+
},
|
35
|
+
{
|
36
|
+
:cve => "CVE-2013-0155",
|
37
|
+
:versions => [%w[2.0.0 2.3.15 2.3.16], %w[3.0.0 3.0.18 3.0.19], %w[3.1.0 3.1.9 3.1.10], %w[3.2.0 3.2.10 3.2.11]],
|
38
|
+
:url => "https://groups.google.com/d/topic/rubyonrails-security/c7jT-EeN9eI/discussion"
|
39
|
+
},
|
40
|
+
|
41
|
+
]
|
42
|
+
|
43
|
+
unless lts_version? '2.3.18.6'
|
44
|
+
issues << {
|
45
|
+
:cve => "CVE-2013-6417",
|
46
|
+
:versions => [%w[2.0.0 3.2.15 3.2.16], %w[4.0.0 4.0.1 4.0.2]],
|
47
|
+
:url => "https://groups.google.com/d/msg/ruby-security-ann/niK4drpSHT4/g8JW8ZsayRkJ"
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
issues.each do |cve_issue|
|
52
|
+
cve_warning_for cve_issue[:versions], cve_issue[:cve], cve_issue[:url]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def cve_warning_for versions, cve, link
|
57
|
+
upgrade_version = upgrade_version? versions
|
58
|
+
return unless upgrade_version
|
59
|
+
|
60
|
+
code = cve.tr('-', '_').to_sym
|
61
|
+
|
62
|
+
warn :warning_type => 'SQL Injection',
|
63
|
+
:warning_code => code,
|
64
|
+
:message => "Rails #{tracker.config[:rails_version]} contains a SQL injection vulnerability (#{cve}). Upgrade to #{upgrade_version}",
|
65
|
+
:confidence => CONFIDENCE[:high],
|
66
|
+
:file => gemfile_or_environment,
|
67
|
+
:link_path => link
|
68
|
+
end
|
69
|
+
|
70
|
+
def upgrade_version? versions
|
71
|
+
versions.each do |low, high, upgrade|
|
72
|
+
return upgrade if version_between? low, high
|
73
|
+
end
|
74
|
+
|
75
|
+
false
|
76
|
+
end
|
77
|
+
|
78
|
+
def check_cve_2014_0080
|
79
|
+
return unless version_between? "4.0.0", "4.0.2" and
|
80
|
+
@tracker.config[:gems].include? :pg
|
81
|
+
|
82
|
+
warn :warning_type => 'SQL Injection',
|
83
|
+
:warning_code => :CVE_2014_0080,
|
84
|
+
:message => "Rails #{tracker.config[:rails_version]} contains a SQL injection vulnerability (CVE-2014-0080) with PostgreSQL. Upgrade to 4.0.3",
|
85
|
+
:confidence => CONFIDENCE[:high],
|
86
|
+
:file => gemfile_or_environment,
|
87
|
+
:link_path => "https://groups.google.com/d/msg/rubyonrails-security/Wu96YkTUR6s/pPLBMZrlwvYJ"
|
88
|
+
end
|
89
|
+
end
|
@@ -3,6 +3,8 @@ require 'brakeman/checks/base_check'
|
|
3
3
|
class Brakeman::CheckSymbolDoS < Brakeman::BaseCheck
|
4
4
|
Brakeman::Checks.add self
|
5
5
|
|
6
|
+
UNSAFE_METHODS = [:to_sym, :literal_to_sym, :intern, :symbolize_keys, :symbolize_keys!]
|
7
|
+
|
6
8
|
@description = "Checks for versions with ActiveRecord symbol denial of service, or code with a similar vulnerability"
|
7
9
|
|
8
10
|
def run_check
|
@@ -26,7 +28,7 @@ class Brakeman::CheckSymbolDoS < Brakeman::BaseCheck
|
|
26
28
|
:link => "https://groups.google.com/d/msg/rubyonrails-security/jgJ4cjjS8FE/BGbHRxnDRTIJ"
|
27
29
|
end
|
28
30
|
|
29
|
-
tracker.find_call(:methods =>
|
31
|
+
tracker.find_call(:methods => UNSAFE_METHODS, :nested => true).each do |result|
|
30
32
|
check_unsafe_symbol_creation(result)
|
31
33
|
end
|
32
34
|
|
@@ -39,10 +41,10 @@ class Brakeman::CheckSymbolDoS < Brakeman::BaseCheck
|
|
39
41
|
|
40
42
|
call = result[:call]
|
41
43
|
|
42
|
-
if result[:method] == :
|
43
|
-
args = [call.target]
|
44
|
-
else
|
44
|
+
if result[:method] == :literal_to_sym
|
45
45
|
args = call.select { |e| sexp? e }
|
46
|
+
else
|
47
|
+
args = [call.target]
|
46
48
|
end
|
47
49
|
|
48
50
|
if input = args.map{ |arg| has_immediate_user_input?(arg) }.compact.first
|
data/lib/brakeman/options.rb
CHANGED
@@ -142,7 +142,7 @@ module Brakeman::Options
|
|
142
142
|
|
143
143
|
opts.on "-f",
|
144
144
|
"--format TYPE",
|
145
|
-
[:pdf, :text, :html, :csv, :tabs, :json],
|
145
|
+
[:pdf, :text, :html, :csv, :tabs, :json, :markdown],
|
146
146
|
"Specify output formats. Default is text" do |type|
|
147
147
|
|
148
148
|
type = "s" if type == :text
|
@@ -158,7 +158,7 @@ module Brakeman::Options
|
|
158
158
|
end
|
159
159
|
|
160
160
|
opts.on "-I", "--interactive-ignore", "Interactively ignore warnings" do
|
161
|
-
options[:interactive_ignore] = true
|
161
|
+
options[:interactive_ignore] = true
|
162
162
|
end
|
163
163
|
|
164
164
|
opts.on "-l", "--[no-]combine-locations", "Combine warning locations (Default)" do |combine|
|
@@ -198,6 +198,10 @@ module Brakeman::Options
|
|
198
198
|
options[:absolute_paths] = true
|
199
199
|
end
|
200
200
|
|
201
|
+
opts.on "--github-repo USER/REPO[/PATH][@REF]", "Output links to GitHub in markdown and HTML reports using specified repo" do |repo|
|
202
|
+
options[:github_repo] = repo
|
203
|
+
end
|
204
|
+
|
201
205
|
opts.on "-w",
|
202
206
|
"--confidence-level LEVEL",
|
203
207
|
["1", "2", "3"],
|
@@ -116,9 +116,9 @@ class Brakeman::ControllerProcessor < Brakeman::BaseProcessor
|
|
116
116
|
case method
|
117
117
|
when :include
|
118
118
|
@controller[:includes] << class_name(first_arg) if @controller
|
119
|
-
when :before_filter, :append_before_filter
|
119
|
+
when :before_filter, :append_before_filter, :before_action, :append_before_action
|
120
120
|
@controller[:options][:before_filters] << exp.args
|
121
|
-
when :prepend_before_filter
|
121
|
+
when :prepend_before_filter, :prepend_before_action
|
122
122
|
@controller[:options][:before_filters].unshift exp.args
|
123
123
|
when :layout
|
124
124
|
if string? last_arg
|
@@ -196,7 +196,8 @@ class Brakeman::ControllerProcessor < Brakeman::BaseProcessor
|
|
196
196
|
|
197
197
|
#Look for before_filters and add fake ones if necessary
|
198
198
|
def process_iter exp
|
199
|
-
|
199
|
+
block_call_name = exp.block_call.method
|
200
|
+
if block_call_name == :before_filter or block_call_name == :before_action
|
200
201
|
add_fake_filter exp
|
201
202
|
else
|
202
203
|
super
|
@@ -106,6 +106,19 @@ class Brakeman::FindAllCalls < Brakeman::BaseProcessor
|
|
106
106
|
exp
|
107
107
|
end
|
108
108
|
|
109
|
+
# Process a dynamic regex like a call
|
110
|
+
def process_dregx exp
|
111
|
+
exp.each { |arg| process arg if sexp? arg }
|
112
|
+
|
113
|
+
@calls << { :target => nil,
|
114
|
+
:method => :brakeman_regex_interp,
|
115
|
+
:call => exp,
|
116
|
+
:nested => false,
|
117
|
+
:location => make_location }
|
118
|
+
|
119
|
+
exp
|
120
|
+
end
|
121
|
+
|
109
122
|
#Process an assignment like a call
|
110
123
|
def process_attrasgn exp
|
111
124
|
process_call exp
|
@@ -58,7 +58,10 @@ class Brakeman::Rails3RoutesProcessor < Brakeman::BaseProcessor
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def process_namespace exp
|
61
|
-
|
61
|
+
arg = exp.block_call.first_arg
|
62
|
+
return exp unless symbol? arg or string? arg
|
63
|
+
|
64
|
+
name = arg.value
|
62
65
|
block = exp.block
|
63
66
|
|
64
67
|
@prefix << camelize(name)
|
@@ -197,6 +200,8 @@ class Brakeman::Rails3RoutesProcessor < Brakeman::BaseProcessor
|
|
197
200
|
first_arg = exp.first_arg
|
198
201
|
second_arg = exp.second_arg
|
199
202
|
|
203
|
+
return exp unless symbol? first_arg or string? first_arg
|
204
|
+
|
200
205
|
if second_arg and second_arg.node_type == :hash
|
201
206
|
self.current_controller = first_arg.value
|
202
207
|
#handle hash
|
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]
|
9
|
+
VALID_FORMATS = [:to_html, :to_pdf, :to_csv, :to_json, :to_tabs, :to_hash, :to_s, :to_markdown]
|
10
10
|
|
11
11
|
def initialize app_tree, tracker
|
12
12
|
@app_tree = app_tree
|
@@ -29,6 +29,8 @@ class Brakeman::Report
|
|
29
29
|
when :to_hash
|
30
30
|
require_report 'hash'
|
31
31
|
Brakeman::Report::Hash
|
32
|
+
when :to_markdown
|
33
|
+
return self.to_markdown
|
32
34
|
when :to_s
|
33
35
|
return self.to_s
|
34
36
|
when :to_pdf
|
@@ -62,6 +64,11 @@ class Brakeman::Report
|
|
62
64
|
generate Brakeman::Report::Table
|
63
65
|
end
|
64
66
|
|
67
|
+
def to_markdown
|
68
|
+
require_report 'markdown'
|
69
|
+
generate Brakeman::Report::Markdown
|
70
|
+
end
|
71
|
+
|
65
72
|
def generate reporter
|
66
73
|
reporter.new(@app_tree, @tracker).generate_report
|
67
74
|
end
|
@@ -139,7 +139,7 @@ class Brakeman::Report::HTML < Brakeman::Report::Base
|
|
139
139
|
message
|
140
140
|
end <<
|
141
141
|
"<table id='#{code_id}' class='context' style='display:none'>" <<
|
142
|
-
"<caption>#{warning_file(warning) || ''}</caption>"
|
142
|
+
"<caption>#{CGI.escapeHTML warning_file(warning) || ''}</caption>"
|
143
143
|
|
144
144
|
unless context.empty?
|
145
145
|
if warning.line - 1 == 1 or warning.line + 1 == 1
|
@@ -193,6 +193,11 @@ class Brakeman::Report::HTML < Brakeman::Report::Base
|
|
193
193
|
def html_message warning, message
|
194
194
|
message = CGI.escapeHTML(message)
|
195
195
|
|
196
|
+
if warning.file
|
197
|
+
github_url = github_url warning.file, warning.line
|
198
|
+
message.gsub!(/(near line \d+)/, "<a href='#{URI.escape github_url, /'/}' target='_blank'>\\1</a>") if github_url
|
199
|
+
end
|
200
|
+
|
196
201
|
if @highlight_user_input and warning.user_input
|
197
202
|
user_input = CGI.escapeHTML(warning.format_user_input)
|
198
203
|
message.gsub!(user_input, "<span class=\"user_input\">#{user_input}</span>")
|
@@ -0,0 +1,158 @@
|
|
1
|
+
Brakeman.load_brakeman_dependency 'terminal-table'
|
2
|
+
|
3
|
+
class Brakeman::Report::Markdown < Brakeman::Report::Base
|
4
|
+
|
5
|
+
class MarkdownTable < Terminal::Table
|
6
|
+
|
7
|
+
def initialize options = {}, &block
|
8
|
+
options[:style] ||= {}
|
9
|
+
options[:style].merge!({
|
10
|
+
:border_x => '-',
|
11
|
+
:border_y => '|',
|
12
|
+
:border_i => '|'
|
13
|
+
})
|
14
|
+
super options, &block
|
15
|
+
end
|
16
|
+
|
17
|
+
def render
|
18
|
+
super.split("\n")[1...-1].join("\n")
|
19
|
+
end
|
20
|
+
alias :to_s :render
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
def generate_report
|
25
|
+
out = "# BRAKEMAN REPORT\n\n" <<
|
26
|
+
generate_metadata.to_s << "\n\n" <<
|
27
|
+
generate_checks.to_s << "\n\n" <<
|
28
|
+
"### SUMMARY\n\n" <<
|
29
|
+
generate_overview.to_s << "\n\n" <<
|
30
|
+
generate_warning_overview.to_s << "\n\n"
|
31
|
+
|
32
|
+
#Return output early if only summarizing
|
33
|
+
return out if tracker.options[:summary_only]
|
34
|
+
|
35
|
+
if tracker.options[:report_routes] or tracker.options[:debug]
|
36
|
+
out << "### CONTROLLERS" << "\n\n" <<
|
37
|
+
generate_controllers.to_s << "\n\n"
|
38
|
+
end
|
39
|
+
|
40
|
+
if tracker.options[:debug]
|
41
|
+
out << "### TEMPLATES\n\n" <<
|
42
|
+
generate_templates.to_s << "\n\n"
|
43
|
+
end
|
44
|
+
|
45
|
+
res = generate_errors
|
46
|
+
out << "### Errors\n\n" << res.to_s << "\n\n" if res
|
47
|
+
|
48
|
+
res = generate_warnings
|
49
|
+
out << "### SECURITY WARNINGS\n\n" << res.to_s << "\n\n" if res
|
50
|
+
|
51
|
+
res = generate_controller_warnings
|
52
|
+
out << "### Controller Warnings:\n\n" << res.to_s << "\n\n" if res
|
53
|
+
|
54
|
+
res = generate_model_warnings
|
55
|
+
out << "### Model Warnings:\n\n" << res.to_s << "\n\n" if res
|
56
|
+
|
57
|
+
res = generate_template_warnings
|
58
|
+
out << "### View Warnings:\n\n" << res.to_s << "\n\n" if res
|
59
|
+
|
60
|
+
out
|
61
|
+
end
|
62
|
+
|
63
|
+
def generate_metadata
|
64
|
+
MarkdownTable.new(
|
65
|
+
:headings =>
|
66
|
+
['Application path', 'Rails version', 'Brakeman version', 'Started at', 'Duration']
|
67
|
+
) do |t|
|
68
|
+
t.add_row([
|
69
|
+
File.expand_path(tracker.options[:app_path]),
|
70
|
+
rails_version,
|
71
|
+
Brakeman::Version,
|
72
|
+
tracker.start_time,
|
73
|
+
"#{tracker.duration} seconds",
|
74
|
+
])
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def generate_checks
|
79
|
+
MarkdownTable.new(:headings => ['Checks performed']) do |t|
|
80
|
+
t.add_row([checks.checks_run.sort.join(", ")])
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def generate_overview
|
85
|
+
num_warnings = all_warnings.length
|
86
|
+
|
87
|
+
MarkdownTable.new(:headings => ['Scanned/Reported', 'Total']) do |t|
|
88
|
+
t.add_row ['Controllers', tracker.controllers.length]
|
89
|
+
t.add_row ['Models', tracker.models.length - 1]
|
90
|
+
t.add_row ['Templates', number_of_templates(@tracker)]
|
91
|
+
t.add_row ['Errors', tracker.errors.length]
|
92
|
+
t.add_row ['Security Warnings', "#{num_warnings} (#{warnings_summary[:high_confidence]})"]
|
93
|
+
t.add_row ['Ignored Warnings', ignored_warnings.length] unless ignored_warnings.empty?
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
#Generate listings of templates and their output
|
98
|
+
def generate_templates
|
99
|
+
out_processor = Brakeman::OutputProcessor.new
|
100
|
+
template_rows = {}
|
101
|
+
tracker.templates.each do |name, template|
|
102
|
+
unless template[:outputs].empty?
|
103
|
+
template[:outputs].each do |out|
|
104
|
+
out = out_processor.format out
|
105
|
+
template_rows[name] ||= []
|
106
|
+
template_rows[name] << out.gsub("\n", ";").gsub(/\s+/, " ")
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
template_rows = template_rows.sort_by{|name, value| name.to_s}
|
112
|
+
|
113
|
+
output = ''
|
114
|
+
template_rows.each do |template|
|
115
|
+
output << template.first.to_s << "\n\n"
|
116
|
+
table = MarkdownTable.new(:headings => ['Output']) do |t|
|
117
|
+
# template[1] is an array of calls
|
118
|
+
template[1].each do |v|
|
119
|
+
t.add_row [v]
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
output << table.to_s << "\n\n"
|
124
|
+
end
|
125
|
+
|
126
|
+
output
|
127
|
+
end
|
128
|
+
|
129
|
+
def render_array template, headings, value_array, locals
|
130
|
+
return if value_array.empty?
|
131
|
+
|
132
|
+
MarkdownTable.new(:headings => headings) do |t|
|
133
|
+
value_array.each { |value_row| t.add_row value_row }
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def convert_warning warning, original
|
138
|
+
warning["Confidence"] = TEXT_CONFIDENCE[warning["Confidence"]]
|
139
|
+
warning["Message"] = markdown_message original, warning["Message"]
|
140
|
+
warning["Warning Type"] = "[#{warning['Warning Type']}](#{original.link})" if original.link
|
141
|
+
warning
|
142
|
+
end
|
143
|
+
|
144
|
+
# Escape and code format warning message
|
145
|
+
def markdown_message warning, message
|
146
|
+
if warning.file
|
147
|
+
github_url = github_url warning.file, warning.line
|
148
|
+
message.gsub!(/(near line \d+)/, "[\\1](#{github_url})") if github_url
|
149
|
+
end
|
150
|
+
if warning.code
|
151
|
+
code = warning.format_code
|
152
|
+
message.gsub(code, "`#{code.gsub('`','``').gsub(/\A``|``\z/, '` `')}`")
|
153
|
+
else
|
154
|
+
message
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
data/lib/brakeman/util.rb
CHANGED
@@ -383,6 +383,15 @@ module Brakeman::Util
|
|
383
383
|
end
|
384
384
|
end
|
385
385
|
|
386
|
+
def github_url file, line=nil
|
387
|
+
if repo_url = @tracker.options[:github_url] and file and not file.empty? and file.start_with? '/'
|
388
|
+
url = "#{repo_url}/#{relative_path(file)}"
|
389
|
+
url << "#L#{line}" if line
|
390
|
+
else
|
391
|
+
nil
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
386
395
|
def truncate_table str
|
387
396
|
@terminal_width ||= if @tracker.options[:table_width]
|
388
397
|
@tracker.options[:table_width]
|
data/lib/brakeman/version.rb
CHANGED
metadata
CHANGED
@@ -1,107 +1,103 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: brakeman-min
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 2
|
8
|
-
- 4
|
9
|
-
- 3
|
10
|
-
version: 2.4.3
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.5.0
|
11
5
|
platform: ruby
|
12
|
-
authors:
|
6
|
+
authors:
|
13
7
|
- Justin Collins
|
14
8
|
autorequire:
|
15
9
|
bindir: bin
|
16
|
-
cert_chain:
|
17
|
-
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
10
|
+
cert_chain:
|
11
|
+
- !binary |-
|
12
|
+
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURMakNDQWhhZ0F3SUJB
|
13
|
+
Z0lCQURBTkJna3Foa2lHOXcwQkFRVUZBREE5TVF3d0NnWURWUVFEREFOblpX
|
14
|
+
MHgKR0RBV0Jnb0praWFKay9Jc1pBRVpGZ2hpY21GclpXMWhiakVUTUJFR0Nn
|
15
|
+
bVNKb21UOGl4a0FSa1dBMjl5WnpBZQpGdzB4TXpFeU1USXdNRE14TlRkYUZ3
|
16
|
+
MHhOREV5TVRJd01ETXhOVGRhTUQweEREQUtCZ05WQkFNTUEyZGxiVEVZCk1C
|
17
|
+
WUdDZ21TSm9tVDhpeGtBUmtXQ0dKeVlXdGxiV0Z1TVJNd0VRWUtDWkltaVpQ
|
18
|
+
eUxHUUJHUllEYjNKbk1JSUIKSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4
|
19
|
+
QU1JSUJDZ0tDQVFFQXhDSG1YQ2FBY1o0YlZqaWpLb3lRRng0TgpkeU43Qjdi
|
20
|
+
cVk4d09YeTZmL1VaNm1kQzhJUkFqODJLYVdRak5FMkxUL09iRlVXcENSeUxk
|
21
|
+
cndqa0RqZEZEeU9UCm1aQ1praU9lRXkyWnhZR2Z4WE1JL3hnMjRjOHI1WG1o
|
22
|
+
MTZFcnNZdXByUmNnKy9LWjZzNFVqc2VCTlRBUm1CSzQKSUhjcUlkbm9XYllh
|
23
|
+
M0JXSG9mbEpQYUpVSWFVKy95VGNsekZRSHBzd1U3a2E4ZnRJQVdlb0RRbzIy
|
24
|
+
Z2FzUC80TgpIdEp2QUl5ZzFEY1dQTGNuMHFiWm1kZWhnOEhadjhDKzJNdUxL
|
25
|
+
WC8ycVpHOWVzZWVnTXFNbEhIYWJ3d0V5OVZ2CmYvdC8rbHRMakMwQ1JhMlRx
|
26
|
+
WjJFdVE1RUV6Yk9zcUFmdGFaSkZtd3Y5VXQxVWhqbWR2UjVSZk42ZFdNUTVR
|
27
|
+
SUQKQVFBQm96a3dOekFMQmdOVkhROEVCQU1DQkxBd0hRWURWUjBPQkJZRUZQ
|
28
|
+
eUVLZVJ5MDlpOHFTcis5S0ZiZVRxdwprTUNTTUFrR0ExVWRFd1FDTUFBd0RR
|
29
|
+
WUpLb1pJaHZjTkFRRUZCUUFEZ2dFQkFMRWs4L1dubDJWQXFjaHhXbGJnClJO
|
30
|
+
ME1rVlVXTWY4TDB4eFVpVktvNVFlTDROQlZpQUxNQnJVNklTNHk2enluK0Zv
|
31
|
+
VUxBTUVhd1VqWmxaZjRIY2cKUzl1bmV2M3ArUlRXVXlrc0FuQTI3d0hacy9O
|
32
|
+
UklrVzM0czFaSTVOTkUveHl1NFVMT1FqZmgxd09qbFd6eUh1OQowdDQxL0N0
|
33
|
+
cGdOUE0ydUFqRzNSSXFscDdRS1hsYnk1MGNRcVdKUUNnVEgzSk5qTWhtUk9F
|
34
|
+
aFRzSTZDT29BcHZkCkNlN0JyMzl5amVvYXJ2ZWtxMHdDWEJZYWtVQncvRGRa
|
35
|
+
Q0c3bUZaNnhnaDAxZXFuWlVzTmQ4dk0rNlY2djIzVnUKamsydE1qRlQ0TDFk
|
36
|
+
QTNNRXN6MytNUDE0NFBEaFBDaDd0UGU2eXk4MUJPdnlZVFZrS3pyQWtnS3dI
|
37
|
+
RDFDdXZzSApiZHc9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
|
38
|
+
date: 2014-04-30 00:00:00.000000000 Z
|
39
|
+
dependencies:
|
40
|
+
- !ruby/object:Gem::Dependency
|
42
41
|
name: ruby_parser
|
43
|
-
|
44
|
-
|
45
|
-
none: false
|
46
|
-
requirements:
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
47
44
|
- - ~>
|
48
|
-
- !ruby/object:Gem::Version
|
49
|
-
hash: 23
|
50
|
-
segments:
|
51
|
-
- 3
|
52
|
-
- 4
|
53
|
-
- 0
|
45
|
+
- !ruby/object:Gem::Version
|
54
46
|
version: 3.4.0
|
55
47
|
type: :runtime
|
56
|
-
version_requirements: *id001
|
57
|
-
- !ruby/object:Gem::Dependency
|
58
|
-
name: ruby2ruby
|
59
48
|
prerelease: false
|
60
|
-
|
61
|
-
|
62
|
-
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 3.4.0
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: ruby2ruby
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
63
58
|
- - ~>
|
64
|
-
- !ruby/object:Gem::Version
|
65
|
-
hash: 5
|
66
|
-
segments:
|
67
|
-
- 2
|
68
|
-
- 0
|
69
|
-
- 5
|
59
|
+
- !ruby/object:Gem::Version
|
70
60
|
version: 2.0.5
|
71
61
|
type: :runtime
|
72
|
-
version_requirements: *id002
|
73
|
-
- !ruby/object:Gem::Dependency
|
74
|
-
name: multi_json
|
75
62
|
prerelease: false
|
76
|
-
|
77
|
-
|
78
|
-
requirements:
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
79
65
|
- - ~>
|
80
|
-
- !ruby/object:Gem::Version
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 2.0.5
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: multi_json
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ~>
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '1.2'
|
86
75
|
type: :runtime
|
87
|
-
|
88
|
-
|
76
|
+
prerelease: false
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ~>
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '1.2'
|
82
|
+
description: Brakeman detects security vulnerabilities in Ruby on Rails applications
|
83
|
+
via static analysis. This version of the gem only requires the minimum number of
|
84
|
+
dependencies. Use the 'brakeman' gem for a full install.
|
89
85
|
email: gem@brakeman.org
|
90
|
-
executables:
|
86
|
+
executables:
|
91
87
|
- brakeman
|
92
88
|
extensions: []
|
93
|
-
|
94
89
|
extra_rdoc_files: []
|
95
|
-
|
96
|
-
files:
|
97
|
-
- bin/brakeman
|
90
|
+
files:
|
98
91
|
- CHANGES
|
99
|
-
- WARNING_TYPES
|
100
92
|
- FEATURES
|
101
93
|
- README.md
|
94
|
+
- WARNING_TYPES
|
95
|
+
- bin/brakeman
|
96
|
+
- lib/brakeman.rb
|
102
97
|
- lib/brakeman/app_tree.rb
|
103
98
|
- lib/brakeman/brakeman.rake
|
104
99
|
- lib/brakeman/call_index.rb
|
100
|
+
- lib/brakeman/checks.rb
|
105
101
|
- lib/brakeman/checks/base_check.rb
|
106
102
|
- lib/brakeman/checks/check_basic_auth.rb
|
107
103
|
- lib/brakeman/checks/check_content_tag.rb
|
@@ -131,6 +127,7 @@ files:
|
|
131
127
|
- lib/brakeman/checks/check_number_to_currency.rb
|
132
128
|
- lib/brakeman/checks/check_quote_table_name.rb
|
133
129
|
- lib/brakeman/checks/check_redirect.rb
|
130
|
+
- lib/brakeman/checks/check_regex_dos.rb
|
134
131
|
- lib/brakeman/checks/check_render.rb
|
135
132
|
- lib/brakeman/checks/check_render_dos.rb
|
136
133
|
- lib/brakeman/checks/check_response_splitting.rb
|
@@ -145,6 +142,7 @@ files:
|
|
145
142
|
- lib/brakeman/checks/check_single_quotes.rb
|
146
143
|
- lib/brakeman/checks/check_skip_before_filter.rb
|
147
144
|
- lib/brakeman/checks/check_sql.rb
|
145
|
+
- lib/brakeman/checks/check_sql_cves.rb
|
148
146
|
- lib/brakeman/checks/check_ssl_verify.rb
|
149
147
|
- lib/brakeman/checks/check_strip_tags.rb
|
150
148
|
- lib/brakeman/checks/check_symbol_dos.rb
|
@@ -153,7 +151,6 @@ files:
|
|
153
151
|
- lib/brakeman/checks/check_validation_regex.rb
|
154
152
|
- lib/brakeman/checks/check_without_protection.rb
|
155
153
|
- lib/brakeman/checks/check_yaml_parsing.rb
|
156
|
-
- lib/brakeman/checks.rb
|
157
154
|
- lib/brakeman/differ.rb
|
158
155
|
- lib/brakeman/format/style.css
|
159
156
|
- lib/brakeman/options.rb
|
@@ -187,6 +184,7 @@ files:
|
|
187
184
|
- lib/brakeman/processors/slim_template_processor.rb
|
188
185
|
- lib/brakeman/processors/template_alias_processor.rb
|
189
186
|
- lib/brakeman/processors/template_processor.rb
|
187
|
+
- lib/brakeman/report.rb
|
190
188
|
- lib/brakeman/report/ignore/config.rb
|
191
189
|
- lib/brakeman/report/ignore/interactive.rb
|
192
190
|
- lib/brakeman/report/initializers/faster_csv.rb
|
@@ -197,6 +195,7 @@ files:
|
|
197
195
|
- lib/brakeman/report/report_hash.rb
|
198
196
|
- lib/brakeman/report/report_html.rb
|
199
197
|
- lib/brakeman/report/report_json.rb
|
198
|
+
- lib/brakeman/report/report_markdown.rb
|
200
199
|
- lib/brakeman/report/report_table.rb
|
201
200
|
- lib/brakeman/report/report_tabs.rb
|
202
201
|
- lib/brakeman/report/templates/controller_overview.html.erb
|
@@ -210,7 +209,6 @@ files:
|
|
210
209
|
- lib/brakeman/report/templates/template_overview.html.erb
|
211
210
|
- lib/brakeman/report/templates/view_warnings.html.erb
|
212
211
|
- lib/brakeman/report/templates/warning_overview.html.erb
|
213
|
-
- lib/brakeman/report.rb
|
214
212
|
- lib/brakeman/rescanner.rb
|
215
213
|
- lib/brakeman/scanner.rb
|
216
214
|
- lib/brakeman/tracker.rb
|
@@ -218,41 +216,30 @@ files:
|
|
218
216
|
- lib/brakeman/version.rb
|
219
217
|
- lib/brakeman/warning.rb
|
220
218
|
- lib/brakeman/warning_codes.rb
|
221
|
-
- lib/brakeman.rb
|
222
219
|
- lib/ruby_parser/bm_sexp.rb
|
223
220
|
- lib/ruby_parser/bm_sexp_processor.rb
|
224
221
|
homepage: http://brakemanscanner.org
|
225
|
-
licenses:
|
222
|
+
licenses:
|
226
223
|
- MIT
|
224
|
+
metadata: {}
|
227
225
|
post_install_message:
|
228
226
|
rdoc_options: []
|
229
|
-
|
230
|
-
require_paths:
|
227
|
+
require_paths:
|
231
228
|
- lib
|
232
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
none: false
|
243
|
-
requirements:
|
244
|
-
- - ">="
|
245
|
-
- !ruby/object:Gem::Version
|
246
|
-
hash: 3
|
247
|
-
segments:
|
248
|
-
- 0
|
249
|
-
version: "0"
|
229
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
230
|
+
requirements:
|
231
|
+
- - ! '>='
|
232
|
+
- !ruby/object:Gem::Version
|
233
|
+
version: '0'
|
234
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
235
|
+
requirements:
|
236
|
+
- - ! '>='
|
237
|
+
- !ruby/object:Gem::Version
|
238
|
+
version: '0'
|
250
239
|
requirements: []
|
251
|
-
|
252
240
|
rubyforge_project:
|
253
|
-
rubygems_version:
|
241
|
+
rubygems_version: 2.2.2
|
254
242
|
signing_key:
|
255
|
-
specification_version:
|
243
|
+
specification_version: 4
|
256
244
|
summary: Security vulnerability scanner for Ruby on Rails.
|
257
245
|
test_files: []
|
258
|
-
|
metadata.gz.sig
CHANGED
Binary file
|