dependabot-common 0.99.7 → 0.100.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 98884158fba0e3b064fef891c739d4c9325313302c6a29c7a5284a1509f35eab
4
- data.tar.gz: 3dbc41a9033f8e5bd13dbdd6d1dbcc5a8133a9f03efe8d7115398dba5ff2b60d
3
+ metadata.gz: f9668f1967a71d3410cbc64d841b11b6489c2fcb18c44fe93c46c41a04fba5d7
4
+ data.tar.gz: 61c5d476ca5df6fa4c0d071f325708db732de08a5104cf88d4fdf9a510f00e34
5
5
  SHA512:
6
- metadata.gz: bfc6417f509d36642bd6f6cef21b631b16b9c609a1e67eca6d4035cea92eafb5d4182153e16e88f103bfa69d9c704a31612ebc5a2858df9d560b839110a7ddf5
7
- data.tar.gz: dfb0622119af5e1b83eb544ebfa1548b5403f1db1a412208d3f6bd3677902ef84abf7d06c37e75ae2f3a1668801f41968d66a7974c9d9be527b4e3e7206cf8bb
6
+ metadata.gz: 66bccb0d40bff7af3d3bdb7e64b8818f52f33fffac90c8d789bed1257be1550269bf85516e95b2fad63548cf2c2ff60d11e0119b34bcd4e67de6531bd51ca87f
7
+ data.tar.gz: 77d31ecd4dbf6e0c46e6c9b927197d4c8494ce134bfbcb900a5f81ea3a535b6b2feced921aedbace21502bfc7460a3d1dcea36e0d60d31104a8896f1de993b7e
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubygems_version_patch"
4
+
5
+ module Dependabot
6
+ class SecurityAdvisory
7
+ attr_reader :vulnerable_versions, :safe_versions, :package_manager
8
+
9
+ def initialize(vulnerable_versions: [], safe_versions: [], package_manager:)
10
+ @vulnerable_versions = vulnerable_versions || []
11
+ @safe_versions = safe_versions || []
12
+ @package_manager = package_manager
13
+
14
+ convert_string_version_requirements
15
+ check_version_requirements
16
+ end
17
+
18
+ def vulnerable?(version)
19
+ unless version.is_a?(version_class)
20
+ raise ArgumentError, "must be a #{version_class}"
21
+ end
22
+
23
+ in_safe_range =
24
+ safe_versions.
25
+ any? { |r| r.satisfied_by?(version_class.new(version)) }
26
+
27
+ # If version is known safe for this advisory, it's not vulnerable
28
+ return false if in_safe_range
29
+
30
+ in_vulnerable_range =
31
+ vulnerable_versions.
32
+ any? { |r| r.satisfied_by?(version_class.new(version)) }
33
+
34
+ # If in the vulnerable range and not known safe, it's vulnerable
35
+ return true if in_vulnerable_range
36
+
37
+ # If a vulnerable range present but not met, it's not vulnerable
38
+ return false if vulnerable_versions.any?
39
+
40
+ # Finally, if no vulnerable range provided, but a safe range provided,
41
+ # and this versions isn't included (checked earler), it's vulnerable
42
+ safe_versions.any?
43
+ end
44
+
45
+ private
46
+
47
+ def convert_string_version_requirements
48
+ @vulnerable_versions = vulnerable_versions.flat_map do |vuln_str|
49
+ next vuln_str unless vuln_str.is_a?(String)
50
+
51
+ requirement_class.requirements_array(vuln_str)
52
+ end
53
+
54
+ @safe_versions = safe_versions.flat_map do |safe_str|
55
+ next safe_str unless safe_str.is_a?(String)
56
+
57
+ requirement_class.requirements_array(safe_str)
58
+ end
59
+ end
60
+
61
+ def check_version_requirements
62
+ unless vulnerable_versions.is_a?(Array) &&
63
+ vulnerable_versions.all? { |i| requirement_class <= i.class }
64
+ raise ArgumentError, "vulnerable_versions must be an array "\
65
+ "of #{requirement_class} instances"
66
+ end
67
+
68
+ unless safe_versions.is_a?(Array) &&
69
+ safe_versions.all? { |i| requirement_class <= i.class }
70
+ raise ArgumentError, "safe_versions must be an array "\
71
+ "of #{requirement_class} instances"
72
+ end
73
+ end
74
+
75
+ def version_class
76
+ Utils.version_class_for_package_manager(package_manager)
77
+ end
78
+
79
+ def requirement_class
80
+ Utils.requirement_class_for_package_manager(package_manager)
81
+ end
82
+ end
83
+ end
@@ -2,24 +2,28 @@
2
2
 
3
3
  require "json"
4
4
  require "dependabot/utils"
5
+ require "dependabot/security_advisory"
5
6
 
6
7
  module Dependabot
7
8
  module UpdateCheckers
8
9
  class Base
9
10
  attr_reader :dependency, :dependency_files, :credentials,
10
- :ignored_versions, :requirements_update_strategy
11
+ :ignored_versions, :security_advisories,
12
+ :requirements_update_strategy
11
13
 
12
14
  def initialize(dependency:, dependency_files:, credentials:,
13
- ignored_versions: [], requirements_update_strategy: nil)
15
+ ignored_versions: [], security_advisories: [],
16
+ requirements_update_strategy: nil)
14
17
  @dependency = dependency
15
18
  @dependency_files = dependency_files
16
19
  @credentials = credentials
17
20
  @requirements_update_strategy = requirements_update_strategy
18
21
  @ignored_versions = ignored_versions
22
+ @security_advisories = security_advisories
19
23
  end
20
24
 
21
25
  def up_to_date?
22
- if dependency.appears_in_lockfile?
26
+ if dependency.version
23
27
  version_up_to_date?
24
28
  else
25
29
  requirements_up_to_date?
@@ -30,7 +34,7 @@ module Dependabot
30
34
  # Can't update if all versions are being ignored
31
35
  return false if ignore_reqs.include?(requirement_class.new(">= 0"))
32
36
 
33
- if dependency.appears_in_lockfile?
37
+ if dependency.version
34
38
  version_can_update?(requirements_to_unlock: requirements_to_unlock)
35
39
  else
36
40
  # TODO: Handle full unlock updates for dependencies without a lockfile
@@ -57,10 +61,25 @@ module Dependabot
57
61
  raise NotImplementedError
58
62
  end
59
63
 
64
+ def preferred_resolvable_version
65
+ # If this dependency is vulnerable, prefer trying to update to the
66
+ # lowest_resolvable_security_fix_version. Otherwise update all the way
67
+ # to the latest_resolvable_version.
68
+ return lowest_resolvable_security_fix_version if vulnerable?
69
+
70
+ latest_resolvable_version
71
+ rescue NotImplementedError
72
+ latest_resolvable_version
73
+ end
74
+
60
75
  def latest_resolvable_version
61
76
  raise NotImplementedError
62
77
  end
63
78
 
79
+ def lowest_resolvable_security_fix_version
80
+ raise NotImplementedError
81
+ end
82
+
64
83
  def latest_resolvable_version_with_no_unlock
65
84
  raise NotImplementedError
66
85
  end
@@ -84,6 +103,20 @@ module Dependabot
84
103
  true
85
104
  end
86
105
 
106
+ def vulnerable?
107
+ return false if security_advisories.none?
108
+
109
+ # Can't (currently) detect whether dependencies without a version
110
+ # (i.e., for repos without a lockfile) are vulnerable
111
+ return false unless dependency.version
112
+
113
+ # Can't (currently) detect whether git dependencies are vulnerable
114
+ return false if existing_version_is_sha?
115
+
116
+ version = version_class.new(dependency.version)
117
+ security_advisories.any? { |a| a.vulnerable?(version) }
118
+ end
119
+
87
120
  private
88
121
 
89
122
  def latest_version_resolvable_with_full_unlock?
@@ -104,7 +137,7 @@ module Dependabot
104
137
  def updated_dependency_with_own_req_unlock
105
138
  Dependency.new(
106
139
  name: dependency.name,
107
- version: latest_resolvable_version.to_s,
140
+ version: preferred_resolvable_version.to_s,
108
141
  requirements: updated_requirements,
109
142
  previous_version: dependency.version,
110
143
  previous_requirements: dependency.requirements,
@@ -153,7 +186,7 @@ module Dependabot
153
186
  new_version = latest_resolvable_version_with_no_unlock
154
187
  new_version && !new_version.to_s.start_with?(dependency.version)
155
188
  when :own
156
- new_version = latest_resolvable_version
189
+ new_version = preferred_resolvable_version
157
190
  new_version && !new_version.to_s.start_with?(dependency.version)
158
191
  when :all
159
192
  latest_version_resolvable_with_full_unlock?
@@ -180,7 +213,7 @@ module Dependabot
180
213
  new_version = latest_resolvable_version_with_no_unlock
181
214
  new_version && new_version > version_class.new(dependency.version)
182
215
  when :own
183
- new_version = latest_resolvable_version
216
+ new_version = preferred_resolvable_version
184
217
  new_version && new_version > version_class.new(dependency.version)
185
218
  when :all
186
219
  latest_version_resolvable_with_full_unlock?
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dependabot
4
- VERSION = "0.99.7"
4
+ VERSION = "0.100.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-common
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.99.7
4
+ version: 0.100.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-04-10 00:00:00.000000000 Z
11
+ date: 2019-04-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-ecr
@@ -345,6 +345,7 @@ files:
345
345
  - lib/dependabot/pull_request_creator/message_builder.rb
346
346
  - lib/dependabot/pull_request_updater.rb
347
347
  - lib/dependabot/pull_request_updater/github.rb
348
+ - lib/dependabot/security_advisory.rb
348
349
  - lib/dependabot/shared_helpers.rb
349
350
  - lib/dependabot/source.rb
350
351
  - lib/dependabot/update_checkers.rb