cvss-suite 1.2.3 → 2.0.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.
@@ -13,14 +13,12 @@ require_relative '../cvss_metric'
13
13
  require_relative '../helpers/cvss3_helper'
14
14
  require_relative '../helpers/cvss31_helper'
15
15
 
16
- ##
17
- # This class represents a CVSS Environmental metric in version 3.1.
18
-
19
16
  module CvssSuite
17
+ ##
18
+ # This class represents a CVSS Environmental metric in version 3.1.
20
19
  class Cvss31Environmental < CvssMetric
21
20
  ##
22
21
  # Property of this metric
23
-
24
22
  attr_reader :confidentiality_requirement, :integrity_requirement, :availability_requirement,
25
23
  :modified_attack_vector, :modified_attack_complexity, :modified_privileges_required,
26
24
  :modified_user_interaction, :modified_scope, :modified_confidentiality,
@@ -28,20 +26,8 @@ module CvssSuite
28
26
 
29
27
  ##
30
28
  # Returns score of this metric
31
- def score(base, temporal)
32
- @base = base
33
-
34
- merged_modified_privileges_required = @modified_privileges_required
35
- if @modified_privileges_required.selected_choice[:name] == 'Not Defined'
36
- merged_modified_privileges_required = @base.privileges_required
37
- end
38
-
39
- merged_modified_scope = @modified_scope
40
- if @modified_scope.selected_choice[:name] == 'Not Defined'
41
- merged_modified_scope = @base.scope
42
- end
43
-
44
- privilege_score = Cvss3Helper.privileges_required_score(merged_modified_privileges_required, merged_modified_scope)
29
+ def score(temporal_score)
30
+ privilege_score = Cvss3Helper.privileges_required_score(@modified_privileges_required, @modified_scope)
45
31
 
46
32
  modified_exploitability_sub_score = modified_exploitability_sub(privilege_score)
47
33
 
@@ -49,7 +35,7 @@ module CvssSuite
49
35
 
50
36
  return 0 if modified_impact_sub_score <= 0
51
37
 
52
- calculate_score modified_impact_sub_score, modified_exploitability_sub_score, temporal.score
38
+ calculate_score modified_impact_sub_score, modified_exploitability_sub_score, temporal_score
53
39
  end
54
40
 
55
41
  private
@@ -57,81 +43,72 @@ module CvssSuite
57
43
  def init_properties
58
44
  @properties.push(@confidentiality_requirement =
59
45
  CvssProperty.new(name: 'Confidentiality Requirement', abbreviation: 'CR', position: [8, 11],
60
- choices: [{ name: 'Low', abbreviation: 'L', weight: 0.5 },
46
+ values: [{ name: 'Low', abbreviation: 'L', weight: 0.5 },
61
47
  { name: 'Medium', abbreviation: 'M', weight: 1.0 },
62
48
  { name: 'High', abbreviation: 'H', weight: 1.5 },
63
49
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
64
50
  @properties.push(@integrity_requirement =
65
51
  CvssProperty.new(name: 'Integrity Requirement', abbreviation: 'IR', position: [9, 12],
66
- choices: [{ name: 'Low', abbreviation: 'L', weight: 0.5 },
52
+ values: [{ name: 'Low', abbreviation: 'L', weight: 0.5 },
67
53
  { name: 'Medium', abbreviation: 'M', weight: 1.0 },
68
54
  { name: 'High', abbreviation: 'H', weight: 1.5 },
69
55
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
70
56
 
71
57
  @properties.push(@availability_requirement =
72
58
  CvssProperty.new(name: 'Availability Requirement', abbreviation: 'AR', position: [10, 13],
73
- choices: [{ name: 'Low', abbreviation: 'L', weight: 0.5 },
59
+ values: [{ name: 'Low', abbreviation: 'L', weight: 0.5 },
74
60
  { name: 'Medium', abbreviation: 'M', weight: 1.0 },
75
61
  { name: 'High', abbreviation: 'H', weight: 1.5 },
76
62
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
77
63
  @properties.push(@modified_attack_vector =
78
64
  CvssProperty.new(name: 'Modified Attack Vector', abbreviation: 'MAV', position: [11, 14],
79
- choices: [{ name: 'Network', abbreviation: 'N', weight: 0.85 },
65
+ values: [{ name: 'Network', abbreviation: 'N', weight: 0.85 },
80
66
  { name: 'Adjacent Network', abbreviation: 'A', weight: 0.62 },
81
67
  { name: 'Local', abbreviation: 'L', weight: 0.55 },
82
68
  { name: 'Physical', abbreviation: 'P', weight: 0.2 },
83
69
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
84
70
  @properties.push(@modified_attack_complexity =
85
71
  CvssProperty.new(name: 'Modified Attack Complexity', abbreviation: 'MAC', position: [12, 15],
86
- choices: [{ name: 'Low', abbreviation: 'L', weight: 0.77 },
72
+ values: [{ name: 'Low', abbreviation: 'L', weight: 0.77 },
87
73
  { name: 'High', abbreviation: 'H', weight: 0.44 },
88
74
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
89
75
  @properties.push(@modified_privileges_required =
90
76
  CvssProperty.new(name: 'Modified Privileges Required', abbreviation: 'MPR', position: [13, 16],
91
- choices: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
77
+ values: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
92
78
  { name: 'Low', abbreviation: 'L', weight: 0.62 },
93
79
  { name: 'High', abbreviation: 'H', weight: 0.27 },
94
80
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
95
81
  @properties.push(@modified_user_interaction =
96
82
  CvssProperty.new(name: 'Modified User Interaction', abbreviation: 'MUI', position: [14, 17],
97
- choices: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
83
+ values: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
98
84
  { name: 'Required', abbreviation: 'R', weight: 0.62 },
99
85
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
100
86
  @properties.push(@modified_scope =
101
87
  CvssProperty.new(name: 'Modified Scope', abbreviation: 'MS', position: [15, 18],
102
- choices: [{ name: 'Changed', abbreviation: 'C' },
103
- { name: 'Unchanged', abbreviation: 'U' },
104
- { name: 'Not Defined', abbreviation: 'X' }]))
88
+ values: [{ name: 'Changed', abbreviation: 'C' },
89
+ { name: 'Unchanged', abbreviation: 'U' }]))
105
90
  @properties.push(@modified_confidentiality =
106
91
  CvssProperty.new(name: 'Modified Confidentiality', abbreviation: 'MC', position: [16, 19],
107
- choices: [{ name: 'None', abbreviation: 'N', weight: 0 },
92
+ values: [{ name: 'None', abbreviation: 'N', weight: 0 },
108
93
  { name: 'Low', abbreviation: 'L', weight: 0.22 },
109
94
  { name: 'High', abbreviation: 'H', weight: 0.56 },
110
95
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
111
96
  @properties.push(@modified_integrity =
112
97
  CvssProperty.new(name: 'Modified Integrity', abbreviation: 'MI', position: [17, 20],
113
- choices: [{ name: 'None', abbreviation: 'N', weight: 0 },
98
+ values: [{ name: 'None', abbreviation: 'N', weight: 0 },
114
99
  { name: 'Low', abbreviation: 'L', weight: 0.22 },
115
100
  { name: 'High', abbreviation: 'H', weight: 0.56 },
116
101
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
117
102
  @properties.push(@modified_availability =
118
103
  CvssProperty.new(name: 'Modified Availability', abbreviation: 'MA', position: [18, 21],
119
- choices: [{ name: 'None', abbreviation: 'N', weight: 0 },
104
+ values: [{ name: 'None', abbreviation: 'N', weight: 0 },
120
105
  { name: 'Low', abbreviation: 'L', weight: 0.22 },
121
106
  { name: 'High', abbreviation: 'H', weight: 0.56 },
122
107
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
123
108
  end
124
109
 
125
110
  def modified_impact_sub(isc_modified)
126
- if @modified_scope.selected_choice[:name] == 'Not Defined'
127
- if @base.scope.selected_choice[:name] == 'Changed'
128
- return 7.52 * (isc_modified - 0.029) - 3.25 * (isc_modified * 0.9731 - 0.02)**13
129
- else
130
- return 6.42 * isc_modified
131
- end
132
- end
133
-
134
- if @modified_scope.selected_choice[:name] == 'Changed'
111
+ if @modified_scope.selected_value[:name] == 'Changed'
135
112
  7.52 * (isc_modified - 0.029) - 3.25 * (isc_modified * 0.9731 - 0.02)**13
136
113
  else
137
114
  6.42 * isc_modified
@@ -139,54 +116,20 @@ module CvssSuite
139
116
  end
140
117
 
141
118
  def isc_modified
142
- merged_modified_confidentiality = @modified_confidentiality
143
- if @modified_confidentiality.selected_choice[:name] == 'Not Defined'
144
- merged_modified_confidentiality = @base.confidentiality
145
- end
146
-
147
- merged_modified_integrity = @modified_integrity
148
- if @modified_integrity.selected_choice[:name] == 'Not Defined'
149
- merged_modified_integrity = @base.integrity
150
- end
151
-
152
- merged_modified_availability = @modified_availability
153
- if @modified_availability.selected_choice[:name] == 'Not Defined'
154
- merged_modified_availability = @base.availability
155
- end
156
-
157
- confidentiality_score = 1 - merged_modified_confidentiality.score * @confidentiality_requirement.score
158
- integrity_score = 1 - merged_modified_integrity.score * @integrity_requirement.score
159
- availability_score = 1 - merged_modified_availability.score * @availability_requirement.score
119
+ confidentiality_score = 1 - @modified_confidentiality.score * @confidentiality_requirement.score
120
+ integrity_score = 1 - @modified_integrity.score * @integrity_requirement.score
121
+ availability_score = 1 - @modified_availability.score * @availability_requirement.score
160
122
 
161
123
  [0.915, (1 - confidentiality_score * integrity_score * availability_score)].min
162
124
  end
163
125
 
164
126
  def modified_exploitability_sub(privilege_score)
165
- merged_modified_attack_vector = @modified_attack_vector
166
- if @modified_attack_vector.selected_choice[:name] == 'Not Defined'
167
- merged_modified_attack_vector = @base.attack_vector
168
- end
169
-
170
- merged_modified_attack_complexity = @modified_attack_complexity
171
- if @modified_attack_complexity.selected_choice[:name] == 'Not Defined'
172
- merged_modified_attack_complexity = @base.attack_complexity
173
- end
174
-
175
- merged_modified_user_interaction = @modified_user_interaction
176
- if @modified_user_interaction.selected_choice[:name] == 'Not Defined'
177
- merged_modified_user_interaction = @base.user_interaction
178
- end
179
-
180
- 8.22 * merged_modified_attack_vector.score * merged_modified_attack_complexity.score *
181
- privilege_score * merged_modified_user_interaction.score
127
+ 8.22 * @modified_attack_vector.score * @modified_attack_complexity.score *
128
+ privilege_score * @modified_user_interaction.score
182
129
  end
183
130
 
184
131
  def calculate_score(modified_impact_sub_score, modified_exploitability_sub_score, temporal_score)
185
- if @modified_scope.selected_choice[:name] == 'Not Defined'
186
- factor = @base.scope.selected_choice[:name] == 'Changed' ? 1.08 : 1.0
187
- else
188
- factor = @modified_scope.selected_choice[:name] == 'Changed' ? 1.08 : 1.0
189
- end
132
+ factor = @modified_scope.selected_value[:name] == 'Changed' ? 1.08 : 1.0
190
133
 
191
134
  Cvss31Helper.round_up(
192
135
  [factor * (modified_impact_sub_score + modified_exploitability_sub_score), 10].min
@@ -11,19 +11,16 @@
11
11
  require_relative '../cvss_property'
12
12
  require_relative '../cvss_metric'
13
13
 
14
- ##
15
- # This class represents a CVSS Temporal metric in version 3.1.
16
-
17
14
  module CvssSuite
15
+ ##
16
+ # This class represents a CVSS Temporal metric in version 3.1.
18
17
  class Cvss31Temporal < CvssMetric
19
18
  ##
20
19
  # Property of this metric
21
-
22
20
  attr_reader :exploit_code_maturity, :remediation_level, :report_confidence
23
21
 
24
22
  ##
25
23
  # Returns score of this metric
26
-
27
24
  def score
28
25
  return 1.0 unless valid?
29
26
 
@@ -35,14 +32,14 @@ module CvssSuite
35
32
  def init_properties
36
33
  @properties.push(@exploit_code_maturity =
37
34
  CvssProperty.new(name: 'Exploit Code Maturity', abbreviation: 'E', position: [8],
38
- choices: [{ name: 'Not Defined', abbreviation: 'X', weight: 1.0 },
35
+ values: [{ name: 'Not Defined', abbreviation: 'X', weight: 1.0 },
39
36
  { name: 'Unproven', abbreviation: 'U', weight: 0.91 },
40
37
  { name: 'Proof-of-Concept', abbreviation: 'P', weight: 0.94 },
41
38
  { name: 'Functional', abbreviation: 'F', weight: 0.97 },
42
39
  { name: 'High', abbreviation: 'H', weight: 1.0 }]))
43
40
  @properties.push(@remediation_level =
44
41
  CvssProperty.new(name: 'Remediation Level', abbreviation: 'RL', position: [9],
45
- choices: [{ name: 'Not Defined', abbreviation: 'X', weight: 1.0 },
42
+ values: [{ name: 'Not Defined', abbreviation: 'X', weight: 1.0 },
46
43
  { name: 'Official Fix', abbreviation: 'O', weight: 0.95 },
47
44
  { name: 'Temporary Fix', abbreviation: 'T', weight: 0.96 },
48
45
  { name: 'Workaround', abbreviation: 'W', weight: 0.97 },
@@ -50,7 +47,7 @@ module CvssSuite
50
47
 
51
48
  @properties.push(@report_confidence =
52
49
  CvssProperty.new(name: 'Report Confidence', abbreviation: 'RC', position: [10],
53
- choices: [{ name: 'Not Defined', abbreviation: 'X', weight: 1.0 },
50
+ values: [{ name: 'Not Defined', abbreviation: 'X', weight: 1.0 },
54
51
  { name: 'Unknown', abbreviation: 'U', weight: 0.92 },
55
52
  { name: 'Reasonable', abbreviation: 'R', weight: 0.96 },
56
53
  { name: 'Confirmed', abbreviation: 'C', weight: 1.0 }]))
@@ -8,23 +8,20 @@
8
8
  # This work is licensed under the terms of the MIT license.
9
9
  # See the LICENSE.md file in the top-level directory.
10
10
 
11
- ##
12
- # This class represents any CVSS metric.
13
-
14
11
  module CvssSuite
12
+ ##
13
+ # This class represents any CVSS metric.
15
14
  class CvssMetric
16
15
  ##
17
16
  # Creates a new CVSS metric by +properties+
18
-
19
17
  def initialize(selected_properties)
20
18
  @properties = []
21
19
  init_properties
22
- extract_selected_choices_from selected_properties
20
+ extract_selected_values_from selected_properties
23
21
  end
24
22
 
25
23
  ##
26
24
  # Returns if the metric is valid.
27
-
28
25
  def valid?
29
26
  @properties.each do |property|
30
27
  return false unless property.valid?
@@ -34,19 +31,18 @@ module CvssSuite
34
31
 
35
32
  ##
36
33
  # Returns number of properties for this metric.
37
-
38
34
  def count
39
35
  @properties.count
40
36
  end
41
37
 
42
38
  private
43
39
 
44
- def extract_selected_choices_from(selected_properties)
40
+ def extract_selected_values_from(selected_properties)
45
41
  selected_properties.each do |selected_property|
46
42
  property = @properties.detect do |p|
47
43
  p.abbreviation == selected_property[:name] && p.position.include?(selected_property[:position])
48
44
  end
49
- property.set_selected_choice selected_property[:selected] unless property.nil?
45
+ property&.set_selected_value selected_property[:selected]
50
46
  end
51
47
  end
52
48
  end
@@ -8,21 +8,20 @@
8
8
  # This work is licensed under the terms of the MIT license.
9
9
  # See the LICENSE.md file in the top-level directory.
10
10
 
11
- ##
12
- # This class represents a CVSS property of a CVSS metric.
13
-
14
11
  module CvssSuite
12
+ ##
13
+ # This class represents a CVSS property of a CVSS metric.
15
14
  class CvssProperty
16
15
  ##
17
16
  # Creates a new CVSS property by a +property+.
18
17
  #
19
18
  # +Property+ needs to consist of a name, a abbreviation,
20
19
  # the possible positions in the CVSS vector, a weight, and the
21
- # available choices for the property.
20
+ # available values for the property.
22
21
 
23
22
  def initialize(property)
24
23
  @property = property
25
- @property[:default_choice] ||= 'Not Available'
24
+ @property[:default_value] ||= 'Not Available'
26
25
  end
27
26
 
28
27
  ##
@@ -40,10 +39,10 @@ module CvssSuite
40
39
  end
41
40
 
42
41
  ##
43
- # Returns all available choices of the property.
42
+ # Returns all available values of the property.
44
43
 
45
- def choices
46
- @property[:choices]
44
+ def values
45
+ @property[:values]
47
46
  end
48
47
 
49
48
  ##
@@ -54,34 +53,34 @@ module CvssSuite
54
53
  end
55
54
 
56
55
  ##
57
- # Returns the selected choice of the property.
56
+ # Returns the selected value of the property.
58
57
 
59
- def selected_choice
60
- @selected_choice || @property[:default_choice]
58
+ def selected_value
59
+ @selected_value || @property[:default_value]
61
60
  end
62
61
 
63
62
  ##
64
63
  # Returns true if the property is valid.
65
64
 
66
65
  def valid?
67
- !@selected_choice.nil?
66
+ !@selected_value.nil?
68
67
  end
69
68
 
70
69
  ##
71
- # Returns the score of the selected choice.
70
+ # Returns the score of the selected value.
72
71
 
73
72
  def score
74
- @selected_choice[:weight]
73
+ @selected_value[:weight]
75
74
  end
76
75
 
77
76
  ##
78
- # Sets the selected choice by a +choice+.
77
+ # Sets the selected value by a +value+.
79
78
 
80
- def set_selected_choice(selected_choice)
81
- choices.each do |choice|
82
- choice[:selected] = selected_choice.eql?(choice[:abbreviation])
79
+ def set_selected_value(selected_value)
80
+ values.each do |value|
81
+ value[:selected] = selected_value.eql?(value[:abbreviation])
83
82
  end
84
- @selected_choice = choices.detect { |choice| choice[:selected] }
83
+ @selected_value = values.detect { |value| value[:selected] }
85
84
  end
86
85
  end
87
86
  end
@@ -8,10 +8,9 @@
8
8
  # This work is licensed under the terms of the MIT license.
9
9
  # See the LICENSE.md file in the top-level directory.
10
10
 
11
- ##
12
- # This module includes methods which are used by the CVSS 3 classes.
13
-
14
11
  module CvssSuite
12
+ ##
13
+ # This module includes methods which are used by the CVSS 3 classes.
15
14
  module Cvss3Helper
16
15
  ##
17
16
  # Since CVSS 3 all float values are rounded up, therefore this method is used
@@ -21,14 +20,14 @@ module CvssSuite
21
20
  end
22
21
 
23
22
  ##
24
- # Since CVSS 3 the Privilege Required score depends on the selected choice of the Scope metric.
23
+ # Since CVSS 3 the Privilege Required score depends on the selected value of the Scope metric.
25
24
  # This method takes a +Privilege+ +Required+ and a +Scope+ metric and returns the newly calculated score.
26
25
  def self.privileges_required_score(privileges_required, scope)
27
- changed = scope.selected_choice[:name] == 'Changed'
26
+ changed = scope.selected_value[:name] == 'Changed'
28
27
  privilege_score = privileges_required.score
29
28
  if changed
30
- privilege_score = 0.68 if privileges_required.selected_choice[:name] == 'Low'
31
- privilege_score = 0.50 if privileges_required.selected_choice[:name] == 'High'
29
+ privilege_score = 0.68 if privileges_required.selected_value[:name] == 'Low'
30
+ privilege_score = 0.50 if privileges_required.selected_value[:name] == 'High'
32
31
  end
33
32
  privilege_score
34
33
  end
@@ -8,47 +8,40 @@
8
8
  # This work is licensed under the terms of the MIT license.
9
9
  # See the LICENSE.md file in the top-level directory.
10
10
 
11
- # ##
12
- # # This class represents a invalid CVSS vector.
13
-
14
11
  module CvssSuite
12
+ ##
13
+ # This class represents a invalid CVSS vector.
15
14
  class InvalidCvss < Cvss
16
15
  ##
17
16
  # Creates a new invalid CVSS vector.
18
-
19
17
  def initialize; end
20
18
 
21
19
  ##
22
20
  # Since this is an invalid CVSS vector, it always returns false.
23
-
24
21
  def valid?
25
22
  false
26
23
  end
27
24
 
28
25
  ##
29
26
  # Since this is an invalid CVSS vector, it always throws an exception.
30
-
31
27
  def version
32
28
  check_validity
33
29
  end
34
30
 
35
31
  ##
36
32
  # Since this is an invalid CVSS vector, it always throws an exception.
37
-
38
33
  def base_score
39
34
  check_validity
40
35
  end
41
36
 
42
37
  ##
43
38
  # Since this is an invalid CVSS vector, it always throws an exception.
44
-
45
39
  def temporal_score
46
40
  check_validity
47
41
  end
48
42
 
49
43
  ##
50
44
  # Since this is an invalid CVSS vector, it always throws an exception.
51
-
52
45
  def environmental_score
53
46
  check_validity
54
47
  end
@@ -9,5 +9,5 @@
9
9
  # See the LICENSE.md file in the top-level directory.
10
10
 
11
11
  module CvssSuite
12
- VERSION = '1.2.3'
12
+ VERSION = '2.0.0'.freeze
13
13
  end
data/lib/cvss_suite.rb CHANGED
@@ -17,18 +17,15 @@ require 'cvss_suite/invalid_cvss'
17
17
 
18
18
  ##
19
19
  # Module of this gem.
20
-
21
20
  module CvssSuite
22
21
  CVSS_VECTOR_BEGINNINGS = [
23
22
  { string: 'AV:', version: 2 },
24
- { string: '(AV:', version: 2 },
25
23
  { string: 'CVSS:3.0/', version: 3.0 },
26
24
  { string: 'CVSS:3.1/', version: 3.1 }
27
- ]
25
+ ].freeze
28
26
 
29
27
  ##
30
28
  # Returns a CVSS class by a +vector+.
31
-
32
29
  def self.new(vector)
33
30
  return InvalidCvss.new unless vector.is_a? String
34
31
 
@@ -49,9 +46,7 @@ module CvssSuite
49
46
 
50
47
  def self.version
51
48
  CVSS_VECTOR_BEGINNINGS.each do |beginning|
52
- if @vector_string.start_with? beginning[:string]
53
- return beginning[:version]
54
- end
49
+ return beginning[:version] if @vector_string.start_with? beginning[:string]
55
50
  end
56
51
  end
57
52
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cvss-suite
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.3
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oliver Hamboerger
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-12-05 00:00:00.000000000 Z
11
+ date: 2020-05-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -79,6 +79,7 @@ files:
79
79
  - ".github/ISSUE_TEMPLATE/custom.md"
80
80
  - ".github/ISSUE_TEMPLATE/feature_request.md"
81
81
  - ".github/workflows/rspec.yml"
82
+ - ".github/workflows/rubocop.yml"
82
83
  - ".gitignore"
83
84
  - ".rspec"
84
85
  - ".rubocop.yml"
@@ -118,8 +119,7 @@ homepage: https://siemens.github.io/cvss-suite/
118
119
  licenses:
119
120
  - MIT
120
121
  metadata: {}
121
- post_install_message: Version 1.x of this gem is no longer supported, please update
122
- to a supported version.
122
+ post_install_message:
123
123
  rdoc_options: []
124
124
  require_paths:
125
125
  - lib
@@ -127,7 +127,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
127
127
  requirements:
128
128
  - - ">="
129
129
  - !ruby/object:Gem::Version
130
- version: 2.0.0
130
+ version: 2.4.0
131
131
  required_rubygems_version: !ruby/object:Gem::Requirement
132
132
  requirements:
133
133
  - - ">="