cvss_rating 0.2.2 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 18833ffe0a2110713321717882552cbd95baa964
4
- data.tar.gz: c9517ce89d7c9a16ec78f6e915b4c4ad24f57d2b
3
+ metadata.gz: ba239c3a20044c1f0bdec1bf20040f292fc58a0a
4
+ data.tar.gz: dd3f4a378df8d13d73240ba8ec36dcb4a20c0a63
5
5
  SHA512:
6
- metadata.gz: 67676bd99e61cb6d0946f490c358013a7956b71b44cb8033da4dfe8231364b74c9488d3e0d3da7d381e82dfd03858132507ed1951cccd9460f5eac444066fdb5
7
- data.tar.gz: 6ebbd458fdbd4a627ff5198e6909e537d87c410a3aaf1a64aea7e82e28617bf625c257f5324a27de35734f630d185c6a7ed10e8d37f042dbde327a3b36991283
6
+ metadata.gz: 7c09e29ab6844f87a3279fec34da5ec3bbdc7c68b9dd2f583745f214feeffab34e6d35c70c3ac99b2a67dd2b760ce3bed39da5c0689f37f0d21a36a50bf7325d
7
+ data.tar.gz: 80391b4cc42fa467640cacc70dd06af7ee5a413abefa1410d234a0ce81ab9093e6c9914ac33f26aa0bc733760c3a20c637aad19d79dce1e74da2bc2cfd9c8478
data/README.md CHANGED
@@ -2,7 +2,9 @@
2
2
 
3
3
  [![Build Status](https://travis-ci.org/mort666/cvss_rating.svg)](https://travis-ci.org/mort666/cvss_rating)
4
4
 
5
- Implements CVSS Risk Rating version 2.0
5
+ Implements vulnerability scoring system CVSS versions 2.0 and 3.0.
6
+
7
+ More information on the standard is available at [https://www.first.org/cvss](https://www.first.org/cvss)
6
8
 
7
9
  ## Installation
8
10
 
@@ -20,10 +22,37 @@ Or install it yourself as:
20
22
 
21
23
  ## Usage
22
24
 
23
- Check out the unit tests for examples of usage.
25
+ The following is basic usage to handle a CVSS 2.0 vector:
26
+
27
+ cvs = Cvss2::Rating.new
28
+ cvss.parse("AV:N/AC:M/Au:N/C:P/I:P/A:P")
29
+
30
+ # Calculate overallscore
31
+ cvss.overallscore
32
+
33
+ The following is basic usage to handle a CVSS 3.0 vector:
34
+
35
+ cvss = Cvss3::Rating.new
36
+ cvss.parse("AV:P/AC:H/PR:H/UI:R/S:C/C:H/I:L/A:N/E:U/RL:O/RC:U/CR:L/IR:L/AR:L")
37
+
38
+ # Calculate Base Score (returns array of score and risk level)
39
+ cvss.cvss_base_score
40
+
41
+ # Calculate Temporal Score (returns array of score and risk level)
42
+ cvss.cvss_temporal_score
43
+
44
+ # Calculate Environmental Score (returns array of score and risk level)
45
+ cvss.cvss_environmental_score
46
+
47
+ Check out the unit tests for more examples of usage.
24
48
 
25
49
  ## TODO
26
50
 
27
- * CVSS 3.0 Support
28
51
  * Code and API clean up
29
52
  * More Unit Tests
53
+
54
+ ## License
55
+
56
+ Copyright (c) Stephen Kapp 2015.
57
+
58
+ Released under the MIT License
data/cvss_rating.gemspec CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ["Stephen Kapp"]
10
10
  spec.email = ["mort666@virus.org"]
11
11
  spec.summary = %q{CVSS Risk Rating Calculation and Vector parsing}
12
- spec.description = %q{CVSS Risk Rating Calculation and Vector parsing, implements CVSS 2.0 rating}
12
+ spec.description = %q{CVSS Risk Rating Calculation and Vector parsing, implements CVSS 2.0 & 3.0 rating}
13
13
  spec.homepage = "https://github.com/mort666/cvss_rating"
14
14
  spec.license = "MIT"
15
15
 
@@ -0,0 +1,106 @@
1
+ # @author Stephen Kapp
2
+
3
+ require "cvss_rating/version"
4
+ require "cvss_rating/cvss3_formulas"
5
+ require "cvss_rating/cvss3_metrics"
6
+ require "cvss_rating/cvss3_vectors"
7
+
8
+ module Cvss3
9
+ class Rating
10
+ attr_accessor :exploitability, :base, :impact, :temporal, :environmental
11
+
12
+ include Cvss3Vectors
13
+
14
+ #
15
+ # Initialize the object, creates a clean initialized Cvss3::Rating object
16
+ #
17
+ # @param list [Hash] list of CVSS 3.0 attributes to be used during initialization
18
+ #
19
+
20
+ def initialize(attributes = {})
21
+ init
22
+
23
+ attributes.each do |name, value|
24
+ send("#{name}=", value)
25
+ end
26
+ end
27
+
28
+
29
+ #
30
+ # Takes score and determines risk level from None to Critical
31
+ #
32
+ # @param score [Float] risk score to be converted to risk level
33
+ # @return [String] risk level based on score
34
+
35
+ def risk_score(score)
36
+ risk_score = case score
37
+ when 0.0
38
+ "None"
39
+ when 0.1..3.9
40
+ "Low"
41
+ when 4.0..6.9
42
+ "Medium"
43
+ when 7.0..8.9
44
+ "High"
45
+ when 9.0..10.0
46
+ "Critical"
47
+ else
48
+ nil
49
+ end
50
+ end
51
+
52
+
53
+ #
54
+ # Calculate the CVSS 3.0 Base Score
55
+ #
56
+ # @return [Array] the CVSS 3.0 Base score with its risk level
57
+
58
+ def cvss_base_score
59
+ @exploitability = ::Cvss3::Formulas.new.exploitability_sub_score(@av, @ac, @pr, @ui)
60
+
61
+ @impact = ::Cvss3::Formulas.new.impact_sub_score_base(@ai, @ci, @ii)
62
+
63
+ @base = ::Cvss3::Formulas.new.cvss_base_formula(@impact, @sc, @exploitability)
64
+
65
+ @base_level = risk_score(@base)
66
+
67
+ return @base, @base_level
68
+ end
69
+
70
+ ##
71
+ #
72
+ # Calculate the CVSS 3.0 Temporal Score
73
+ #
74
+ # @return [Array] the CVSS 3.0 Temporal score with its risk level
75
+
76
+ def cvss_temporal_score
77
+ @temporal = ::Cvss3::Formulas.new.cvss_temporal_formula(@base, @ex, @rl, @rc)
78
+
79
+ @temporal_level = risk_score(@temporal)
80
+
81
+ return @temporal, @temporal_level
82
+ end
83
+
84
+ ##
85
+ #
86
+ # Calculate the CVSS 3.0 Temporal Score
87
+ #
88
+ # @return [Array] the CVSS 3.0 Temporal score with its risk level
89
+
90
+ def cvss_environmental_score
91
+ exploitability_sub_score_value_modified = ::Cvss3::Formulas.new.exploitability_sub_score_modified(self.mav(true),
92
+ self.mac(true), self.mpr(true), self.mui(true))
93
+
94
+ impact_sub_score_value_modified = ::Cvss3::Formulas.new.impact_sub_score_modified_base(self.ma(true), self.mc(true),
95
+ self.mi(true), @cr, @ir, @ar)
96
+
97
+ @environmental = ::Cvss3::Formulas.new.cvss_environmental_formula(impact_sub_score_value_modified,
98
+ exploitability_sub_score_value_modified,
99
+ @ex, @rl, @rc, self.ms(true))
100
+
101
+ @environmental_level = risk_score(@environmental)
102
+
103
+ return @environmental, @environmental_level
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,103 @@
1
+ module Cvss3
2
+ class Formulas
3
+ EXPLOITABILITY_COEFFICIENT = 8.22
4
+ IMPACT_COEFFICIENT = 6.42
5
+ IMPACT_MOD_COEFFICIENT = 7.52
6
+
7
+ def exploitability_sub_score(attack_vector_value, attack_complexity_value, privileges_required_value, user_interaction_value)
8
+
9
+ exploitability_sub_score_value = EXPLOITABILITY_COEFFICIENT * attack_vector_value * attack_complexity_value * privileges_required_value * user_interaction_value
10
+
11
+ return exploitability_sub_score_value
12
+ end
13
+
14
+ def exploitability_sub_score_modified(attack_vector_value_modified, attack_complexity_value_modified,
15
+ privileges_required_value_modified, user_interaction_value_modified)
16
+
17
+ exploitability_sub_score_value_modified = EXPLOITABILITY_COEFFICIENT * attack_vector_value_modified * attack_complexity_value_modified * privileges_required_value_modified * user_interaction_value_modified
18
+
19
+ return exploitability_sub_score_value_modified
20
+ end
21
+
22
+ def impact_sub_score_base(availability_value, confidentiality_value, integrity_value)
23
+
24
+ impact_sub_score_value = 1 - ((1 - confidentiality_value) * (1 - integrity_value) * (1 - availability_value))
25
+
26
+ return impact_sub_score_value
27
+ end
28
+
29
+ def impact_sub_score_modified_base(availability_value_modified, confidentiality_value_modified, integrity_value_modified,
30
+ confidentiality_requirement_value, integrity_requirement_value, availability_requirement_value)
31
+
32
+ impact_sub_score_value_modified = min(0.915, 1 - (1 - confidentiality_value_modified * confidentiality_requirement_value) * (1 - integrity_value_modified * integrity_requirement_value) * (1 - availability_value_modified * availability_requirement_value))
33
+
34
+ return impact_sub_score_value_modified
35
+ end
36
+
37
+ def cvss_base_formula(impact_sub_score_value, scope_value, exploitability_sub_score_value)
38
+
39
+ if scope_value == "unchanged"
40
+ impact_value = IMPACT_COEFFICIENT * impact_sub_score_value
41
+ cvss_base_value = min(10, impact_value + exploitability_sub_score_value)
42
+ elsif scope_value == "changed"
43
+ impact_value = IMPACT_MOD_COEFFICIENT * (impact_sub_score_value - 0.029) - 3.25 * ((impact_sub_score_value - 0.02) ** 15)
44
+ cvss_base_value = min(10, 1.08 * (impact_value + exploitability_sub_score_value))
45
+ end
46
+
47
+ if impact_sub_score_value <= 0
48
+ cvss_base_value = 0.0
49
+ else
50
+ cvss_base_value = cvss_base_value.ceil2(1)
51
+ end
52
+
53
+ return cvss_base_value
54
+ end
55
+
56
+ def cvss_temporal_formula(cvss_base_value, exploit_code_maturity_value, remediation_level_value, report_confidence_value)
57
+
58
+ cvss_temporal_value = cvss_base_value * exploit_code_maturity_value * remediation_level_value * \
59
+ report_confidence_value
60
+
61
+ cvss_temporal_value = cvss_temporal_value.ceil2(1)
62
+
63
+ return cvss_temporal_value
64
+ end
65
+
66
+ def cvss_environmental_formula(impact_sub_score_value_modified, exploitability_sub_score_value_modified,
67
+ exploit_code_maturity_value, remediation_level_value, report_confidence_value, scope_value_modified)
68
+
69
+ if scope_value_modified == "unchanged"
70
+ impact_value_modified = IMPACT_COEFFICIENT * impact_sub_score_value_modified
71
+ temp_score = min(10, impact_value_modified + exploitability_sub_score_value_modified)
72
+ temp_score2 = temp_score.ceil2(1)
73
+ temp_score3 = temp_score2 * exploit_code_maturity_value * remediation_level_value * report_confidence_value
74
+ elsif scope_value_modified == "changed"
75
+ impact_value_modified = IMPACT_MOD_COEFFICIENT * (impact_sub_score_value_modified - 0.029) - 3.25 * ((impact_sub_score_value_modified - 0.02) ** 15)
76
+ temp_score = min(10, 1.08 * (impact_value_modified + exploitability_sub_score_value_modified))
77
+ temp_score2 = temp_score.ceil2(1)
78
+ temp_score3 = temp_score2 * exploit_code_maturity_value * remediation_level_value * report_confidence_value
79
+ end
80
+
81
+ if impact_sub_score_value_modified <= 0
82
+ cvss_environmental_value = 0.0
83
+ else
84
+ cvss_environmental_value = temp_score3.ceil2(1)
85
+ end
86
+
87
+ return cvss_environmental_value
88
+ end
89
+
90
+
91
+ def min(*values)
92
+ values.min
93
+ end
94
+ end
95
+ end
96
+
97
+
98
+ class Float
99
+ def ceil2(exp = 0)
100
+ multiplier = 10 ** exp
101
+ ((self * multiplier).ceil).to_f/multiplier.to_f
102
+ end
103
+ end
@@ -0,0 +1,52 @@
1
+ module Cvss3
2
+ class Metrics
3
+ # Base Metrics
4
+ ATTACK_VECTOR = { :physical => 0.2, :local => 0.55, :adjacent_network => 0.62, :network => 0.85, :not_defined => 0.85 }
5
+ ATTACK_COMPLEXITY = { :high => 0.44, :low => 0.77, :not_defined => 0.77 }
6
+
7
+ PRIVILEGE_REQUIRED = { :not_defined => 0.85, :none => 0.85, :low => 0.62, :high => 0.27 }
8
+ PRIVILEGE_REQUIRED_CHANGED = { :not_defined => 0.85, :none => 0.85, :low => 0.68, :high => 0.50 }
9
+
10
+ USER_INTERACTION = {:not_defined => 0.85, :none => 0.85, :required => 0.62 }
11
+
12
+ CIA_IMPACT = { :none => 0.0, :low => 0.22, :high => 0.56, :not_defined => 0.56 }
13
+
14
+ # Environmental Metrics
15
+ CIA_REQUIREMENT = { :low => 0.5, :medium => 1.0, :high => 1.50, :not_defined => 1.0 }
16
+
17
+ # Temporal Metrics
18
+ EXPLOITABILITY = { :unproven => 0.91, :poc => 0.94, :functional => 0.97, :high => 1.0, :not_defined => 1.0 }
19
+
20
+ REMEDIATION_LEVEL = { :official => 0.95, :temporary => 0.96, :workaround => 0.97, :unavailable => 1.0, :not_defined => 1.0 }
21
+
22
+ REPORT_CONFIDENCE = { :unknown => 0.92, :reasonable => 0.96, :confirmed => 1.0, :not_defined => 1.0 }
23
+
24
+ # Key Lookup values
25
+
26
+ ATTACK_VECTOR_KEY = { :physical => 'P', :local => 'L', :adjacent_network => 'A', :network => 'N' }
27
+ ATTACK_COMPLEXITY_KEY = { :high => 'H', :low => 'L' }
28
+ PRIVILEGE_REQUIRED_KEY = { :none => 'N', :low => 'L', :high => 'H' }
29
+ PRIVILEGE_REQUIRED_CHANGED_KEY = { :none => 'N', :low => 'L', :high => 'H' }
30
+ USER_INTERACTION_KEY = { :none => 'N', :required => 'R' }
31
+
32
+ SCOPE_KEY = { :changed => 'C', :unchanged => 'U' }
33
+
34
+ CIA_IMPACT_KEY = { :none => 'N', :low => 'L', :high => 'H' }
35
+
36
+ CIA_REQUIREMENT_KEY = { :low => 'L', :medium => 'M', :high => 'H', :notdefined => 'ND' }
37
+
38
+ EXPLOITABILITY_KEY = { :unproven => 'U', :poc => 'P', :functional => 'F', :high => 'H', :not_defined => 'ND' }
39
+ REMEDIATION_LEVEL_KEY = { :official => 'O', :temporary => "T", :workaround => 'W', :unavailable => 'U', :not_defined => 'ND' }
40
+ REPORT_CONFIDENCE_KEY = { :unknown => 'U', :reasonable => 'R', :confirmed => 'C', :not_defined => 'ND' }
41
+
42
+ MODIFIED_ATTACK_VECTOR_KEY = { :physical => 'P', :local => 'L', :adjacent_network => 'A', :network => 'N' }
43
+ MODIFIED_ATTACK_COMPLEXITY_KEY = { :high => 'H', :low => 'L' }
44
+ MODIFIED_PRIVILEGE_REQUIRED_KEY = { :none => 'N', :low => 'L', :high => 'H' }
45
+ MODIFIED_PRIVILEGE_REQUIRED_CHANGED_KEY = { :none => 'N', :low => 'L', :high => 'H' }
46
+ MODIFIED_USER_INTERACTION_KEY = { :none => 'N', :required => 'R' }
47
+
48
+ MODIFIED_SCOPE_KEY = { :changed => 'C', :unchanged => 'U' }
49
+
50
+ MODIFIED_CIA_IMPACT_KEY = { :none => 'N', :low => 'L', :high => 'H' }
51
+ end
52
+ end
@@ -0,0 +1,551 @@
1
+ module Cvss3Vectors
2
+ attr_reader :av, :ac, :ui, :sc, :ci, :ai, :ii, :ex, :rl, :rc, :pr, :td, :cr, :ir
3
+
4
+ VECTORS = {
5
+ "cvss" => "cvss3=",
6
+ "av" => "av=",
7
+ "ac" => "ac=",
8
+ "ui" => "ui=",
9
+ "s" => "sc=",
10
+ "c" => "ci=",
11
+ "i" => "ii=",
12
+ "a" => "ai=",
13
+ "e" => "ex=",
14
+ "rl" => "rl=",
15
+ "rc" => "rc=",
16
+ "pr" => "pr=",
17
+ "cr" => "cr=",
18
+ "ir" => "ir=",
19
+ "ar" => "ar=",
20
+ "mav" => "mav=",
21
+ "mac" => "mac=",
22
+ "ms" => "ms=",
23
+ "mpr" => "mpr=",
24
+ "mui" => "mui=",
25
+ "mc" => "mc=",
26
+ "mi" => "mi=",
27
+ "ma" => "ma="
28
+ }
29
+
30
+ def parse(vector)
31
+ string = vector.split("/")
32
+ len = string.length
33
+
34
+ init
35
+
36
+ @originalkey = vector
37
+
38
+ string.each do |section|
39
+ tmp = section.split(":")
40
+ send(VECTORS[tmp[0].downcase].to_sym, tmp[1])
41
+ end
42
+ end
43
+
44
+ def set_key
45
+ @key = "AV:%s/AC:%s/PR:%s/UI:%s/C:%s/I:%s/A:%s" % [ self.av,
46
+ self.ac, self.pr, self.ui,
47
+ self.ci, self.ii, self.ai]
48
+
49
+ @key += "/E:%s" % self.ex if !@ex.nil?
50
+ @key += "/RL:%s" % self.rl if !@rl.nil?
51
+ @key += "/RC:%s" % self.rc if !@rc.nil?
52
+
53
+ @key += "/CR:%s" % self.cr if !@cr.nil?
54
+ @key += "/IR:%s" % self.ir if !@ir.nil?
55
+ @key += "/AR:%s" % self.ar if !@ar.nil?
56
+
57
+ @key += "/MAV:%s" % self.mav if !@mav.nil?
58
+ @key += "/MAC:%s" % self.mac if !@mac.nil?
59
+ @key += "/MPR:%s" % self.mpr if !@mpr.nil?
60
+ @key += "/MUI:%s" % self.mui if !@mui.nil?
61
+ @key += "/MS:%s" % self.ms if !@ms.nil?
62
+
63
+ @key += "/MC:%s" % self.mc if !@mc.nil?
64
+ @key += "/MI:%s" % self.mi if !@mi.nil?
65
+ @key += "/MA:%s" % self.ma if !@ma.nil?
66
+
67
+ end
68
+
69
+ def key
70
+ self.set_key
71
+ return @key
72
+ end
73
+
74
+ def get_key(vector, value)
75
+ get_key = eval("::Cvss3::Metrics::" + vector + "_KEY")[(eval("::Cvss3::Metrics::" + vector).select { |k,v| v == value }).keys[0]]
76
+ end
77
+
78
+ def cvss3=(cvss3)
79
+ if cvss3 != "3.0"
80
+ raise "Bad CVSS 3.0 Vector String"
81
+ end
82
+ end
83
+
84
+ def av=(av)
85
+ @av = case av
86
+ when "physical", "P"
87
+ ::Cvss3::Metrics::ATTACK_VECTOR[:physical]
88
+ when "local", "L"
89
+ ::Cvss3::Metrics::ATTACK_VECTOR[:local]
90
+ when "adjacent network", "A"
91
+ ::Cvss3::Metrics::ATTACK_VECTOR[:adjacent_network]
92
+ when "network", "N"
93
+ ::Cvss3::Metrics::ATTACK_VECTOR[:network]
94
+ else
95
+ raise "Bad Argument"
96
+ end
97
+ end
98
+
99
+ def av
100
+ av = get_key("ATTACK_VECTOR", @av) if !@av.nil?
101
+ end
102
+
103
+ def ac=(ac)
104
+ @ac = case ac
105
+ when "high", "H"
106
+ ::Cvss3::Metrics::ATTACK_COMPLEXITY[:high]
107
+ when "low", "L"
108
+ ::Cvss3::Metrics::ATTACK_COMPLEXITY[:low]
109
+ else
110
+ raise "Bad Argument"
111
+ end
112
+ end
113
+
114
+ def ac
115
+ ac = get_key("ATTACK_COMPLEXITY", @ac) if !@ac.nil?
116
+ end
117
+
118
+ def ui=(ui)
119
+ @ui = case ui
120
+ when "none", "N"
121
+ ::Cvss3::Metrics::USER_INTERACTION[:none]
122
+ when "required", "R"
123
+ ::Cvss3::Metrics::USER_INTERACTION[:required]
124
+ else
125
+ raise "Bad Argument"
126
+ end
127
+ end
128
+
129
+ def ui
130
+ ui = get_key("USER_INTERACTION", @ui) if !@ui.nil?
131
+ end
132
+
133
+ def pr=(pr)
134
+ @pr = case pr
135
+ when "none", "N"
136
+ ::Cvss3::Metrics::PRIVILEGE_REQUIRED[:none]
137
+ when "low", "L"
138
+ ::Cvss3::Metrics::PRIVILEGE_REQUIRED[:low]
139
+ when "high", "H"
140
+ ::Cvss3::Metrics::PRIVILEGE_REQUIRED[:high]
141
+ else
142
+ raise "Bad Argument"
143
+ end
144
+ end
145
+
146
+ def pr
147
+ if @sc == "changed"
148
+ pr = get_key("PRIVILEGE_REQUIRED_CHANGED", @pr) if !@pr.nil?
149
+ else
150
+ pr = get_key("PRIVILEGE_REQUIRED", @pr) if !@pr.nil?
151
+ end
152
+ end
153
+
154
+ def sc=(sc)
155
+ @sc = case sc
156
+ when "changed", "C"
157
+ "changed"
158
+ when "unchanged", "U"
159
+ "unchanged"
160
+ else
161
+ raise "Bad Argument"
162
+ end
163
+
164
+ if @sc == "changed"
165
+ @pr = case get_key("PRIVILEGE_REQUIRED", @pr).nil? ? get_key("PRIVILEGE_REQUIRED_CHANGED", @pr) : get_key("PRIVILEGE_REQUIRED", @pr)
166
+ when "none", "N",
167
+ ::Cvss3::Metrics::PRIVILEGE_REQUIRED_CHANGED[:none]
168
+ when "low", "L"
169
+ ::Cvss3::Metrics::PRIVILEGE_REQUIRED_CHANGED[:low]
170
+ when "high", "H"
171
+ ::Cvss3::Metrics::PRIVILEGE_REQUIRED_CHANGED[:high]
172
+ else
173
+ raise "Bad Argument"
174
+ end
175
+ else
176
+ self.pr = get_key("PRIVILEGE_REQUIRED", @pr).nil? ? get_key("PRIVILEGE_REQUIRED_CHANGED", @pr) : get_key("PRIVILEGE_REQUIRED", @pr)
177
+ end
178
+ end
179
+
180
+ def sc
181
+ sc = ::Cvss3::Metrics::SCOPE_KEY[@sc.to_sym] if !@sc.nil?
182
+ end
183
+
184
+ def ci=(ci)
185
+ @ci = case ci
186
+ when "none", "N"
187
+ ::Cvss3::Metrics::CIA_IMPACT[:none]
188
+ when "low", "L"
189
+ ::Cvss3::Metrics::CIA_IMPACT[:low]
190
+ when "high", "H"
191
+ ::Cvss3::Metrics::CIA_IMPACT[:high]
192
+ else
193
+ raise "Bad Argument"
194
+ end
195
+ end
196
+
197
+ def ci
198
+ ci = get_key("CIA_IMPACT", @ci) if !@ci.nil?
199
+ end
200
+
201
+ def ii=(ii)
202
+ @ii = case ii
203
+ when "none", "N"
204
+ ::Cvss3::Metrics::CIA_IMPACT[:none]
205
+ when "low", "L"
206
+ ::Cvss3::Metrics::CIA_IMPACT[:low]
207
+ when "high", "H"
208
+ ::Cvss3::Metrics::CIA_IMPACT[:high]
209
+ else
210
+ raise "Bad Argument"
211
+ end
212
+ end
213
+
214
+ def ii
215
+ ii = get_key("CIA_IMPACT", @ii) if !@ii.nil?
216
+ end
217
+
218
+ def ai=(ai)
219
+ @ai = case ai
220
+ when "none", "N"
221
+ ::Cvss3::Metrics::CIA_IMPACT[:none]
222
+ when "low", "L"
223
+ ::Cvss3::Metrics::CIA_IMPACT[:low]
224
+ when "high", "H"
225
+ ::Cvss3::Metrics::CIA_IMPACT[:high]
226
+ else
227
+ raise "Bad Argument"
228
+ end
229
+ end
230
+
231
+ def ai
232
+ ai = get_key("CIA_IMPACT", @ai) if !@ai.nil?
233
+ end
234
+
235
+ def mav=(mav)
236
+ @mav = case mav
237
+ when "physical", "P"
238
+ ::Cvss3::Metrics::ATTACK_VECTOR[:physical]
239
+ when "local", "L"
240
+ ::Cvss3::Metrics::ATTACK_VECTOR[:local]
241
+ when "adjacent network", "A"
242
+ ::Cvss3::Metrics::ATTACK_VECTOR[:adjacent_network]
243
+ when "network", "N"
244
+ ::Cvss3::Metrics::ATTACK_VECTOR[:network]
245
+ when "not_defined", "ND"
246
+ nil
247
+ else
248
+ raise "Bad Argument"
249
+ end
250
+ end
251
+
252
+ def mav(raw=false)
253
+ if raw
254
+ @mav ||= @av
255
+ else
256
+ mav = get_key("ATTACK_VECTOR", @mav) if !@mav.nil?
257
+ end
258
+ end
259
+
260
+ def mac=(mac)
261
+ @mac = case mac
262
+ when "high", "H"
263
+ ::Cvss3::Metrics::ATTACK_COMPLEXITY[:high]
264
+ when "low", "L"
265
+ ::Cvss3::Metrics::ATTACK_COMPLEXITY[:low]
266
+ when "not_defined", "ND"
267
+ nil
268
+ else
269
+ raise "Bad Argument"
270
+ end
271
+ end
272
+
273
+ def mac(raw=false)
274
+ if raw
275
+ @mac ||= @ac
276
+ else
277
+ mac = get_key("ATTACK_COMPLEXITY", @mac) if !@mac.nil?
278
+ end
279
+ end
280
+
281
+ def mui=(mui)
282
+ @mui = case mui
283
+ when "none", "N"
284
+ ::Cvss3::Metrics::USER_INTERACTION[:none]
285
+ when "required", "R"
286
+ ::Cvss3::Metrics::USER_INTERACTION[:required]
287
+ when "not_defined", "ND"
288
+ nil
289
+ else
290
+ raise "Bad Argument"
291
+ end
292
+ end
293
+
294
+ def mui(raw=false)
295
+ if raw
296
+ @mui ||= @ui
297
+ else
298
+ mui = get_key("USER_INTERACTION", @mui) if !@mui.nil?
299
+ end
300
+ end
301
+
302
+ def mpr=(mpr)
303
+ @mpr = case mpr
304
+ when "none", "N"
305
+ ::Cvss3::Metrics::PRIVILEGE_REQUIRED[:none]
306
+ when "low", "L"
307
+ ::Cvss3::Metrics::PRIVILEGE_REQUIRED[:low]
308
+ when "high", "H"
309
+ ::Cvss3::Metrics::PRIVILEGE_REQUIRED[:high]
310
+ when "not_defined", "ND"
311
+ nil
312
+ else
313
+ raise "Bad Argument"
314
+ end
315
+ end
316
+
317
+ def mpr(raw=false)
318
+ if raw
319
+ @mpr ||= @pr
320
+ else
321
+ if @ms == "changed"
322
+ mpr = get_key("PRIVILEGE_REQUIRED_CHANGED", @mpr) if !@mpr.nil?
323
+ else
324
+ mpr = get_key("PRIVILEGE_REQUIRED", @mpr) if !@mpr.nil?
325
+ end
326
+ end
327
+ end
328
+
329
+ def ms=(ms)
330
+ @ms = case ms
331
+ when "changed", "C"
332
+ "changed"
333
+ when "unchanged", "U"
334
+ "unchanged"
335
+ when "not_defined", "ND"
336
+ nil
337
+ else
338
+ raise "Bad Argument"
339
+ end
340
+
341
+ if @ms == "changed"
342
+ @mpr = case get_key("PRIVILEGE_REQUIRED", self.mpr(true)).nil? ? get_key("PRIVILEGE_REQUIRED_CHANGED", self.mpr(true)) : get_key("PRIVILEGE_REQUIRED", self.mpr(true))
343
+ when "none", "N",
344
+ ::Cvss3::Metrics::PRIVILEGE_REQUIRED_CHANGED[:none]
345
+ when "low", "L"
346
+ ::Cvss3::Metrics::PRIVILEGE_REQUIRED_CHANGED[:low]
347
+ when "high", "H"
348
+ ::Cvss3::Metrics::PRIVILEGE_REQUIRED_CHANGED[:high]
349
+ else
350
+ raise "Bad Argument"
351
+ end
352
+ else
353
+ self.mpr = get_key("PRIVILEGE_REQUIRED", self.mpr(true)).nil? ? get_key("PRIVILEGE_REQUIRED_CHANGED", self.mpr(true)) : get_key("PRIVILEGE_REQUIRED", self.mpr(true))
354
+ end
355
+ end
356
+
357
+ def ms(raw=false)
358
+ if raw
359
+ @ms ||= @sc
360
+ else
361
+ if @ms.nil?
362
+ ms = ::Cvss3::Metrics::SCOPE_KEY[@sc.to_sym] if !@sc.nil?
363
+ else
364
+ ms = ::Cvss3::Metrics::SCOPE_KEY[@ms.to_sym] if !@ms.nil?
365
+ end
366
+ end
367
+ end
368
+
369
+ def mc=(mc)
370
+ @mc = case mc
371
+ when "none", "N"
372
+ ::Cvss3::Metrics::CIA_IMPACT[:none]
373
+ when "low", "L"
374
+ ::Cvss3::Metrics::CIA_IMPACT[:low]
375
+ when "high", "H"
376
+ ::Cvss3::Metrics::CIA_IMPACT[:high]
377
+ when "not_defined", "ND"
378
+ nil
379
+ else
380
+ raise "Bad Argument"
381
+ end
382
+ end
383
+
384
+ def mc(raw=false)
385
+ if raw
386
+ @mv ||= @ci
387
+ else
388
+ mc = get_key("CIA_IMPACT", @mc) if !@mc.nil?
389
+ end
390
+ end
391
+
392
+ def mi=(mi)
393
+ @mi = case mi
394
+ when "none", "N"
395
+ ::Cvss3::Metrics::CIA_IMPACT[:none]
396
+ when "low", "L"
397
+ ::Cvss3::Metrics::CIA_IMPACT[:low]
398
+ when "high", "H"
399
+ ::Cvss3::Metrics::CIA_IMPACT[:high]
400
+ when "not_defined", "ND"
401
+ nil
402
+ else
403
+ raise "Bad Argument"
404
+ end
405
+ end
406
+
407
+ def mi(raw=false)
408
+ if raw
409
+ @mi ||= @ii
410
+ else
411
+ mi = get_key("CIA_IMPACT", @mi) if !@mi.nil?
412
+ end
413
+ end
414
+
415
+ def ma=(ma)
416
+ @ma = case ma
417
+ when "none", "N"
418
+ ::Cvss3::Metrics::CIA_IMPACT[:none]
419
+ when "low", "L"
420
+ ::Cvss3::Metrics::CIA_IMPACT[:low]
421
+ when "high", "H"
422
+ ::Cvss3::Metrics::CIA_IMPACT[:high]
423
+ when "not_defined", "ND"
424
+ nil
425
+ else
426
+ raise "Bad Argument"
427
+ end
428
+ end
429
+
430
+ def ma(raw=false)
431
+ if raw
432
+ @ma ||= @ai
433
+ else
434
+ ma = get_key("CIA_IMPACT", @ma) if !@ma.nil?
435
+ end
436
+ end
437
+
438
+ def ex=(ex)
439
+ @ex = case ex
440
+ when "unproven", "U" then ::Cvss3::Metrics::EXPLOITABILITY[:unproven]
441
+ when "proof-of-concept", "P", "POC" then ::Cvss3::Metrics::EXPLOITABILITY[:poc]
442
+ when "functional", "F" then ::Cvss3::Metrics::EXPLOITABILITY[:functional]
443
+ when "high", "H" then ::Cvss3::Metrics::EXPLOITABILITY[:high]
444
+ when "not defined", "ND", "X" then ::Cvss3::Metrics::EXPLOITABILITY[:not_defined]
445
+ else
446
+ raise "Bad Argument"
447
+ end
448
+ end
449
+
450
+ def ex
451
+ ex = get_key("EXPLOITABILITY", @ex) if !@ex.nil?
452
+ end
453
+
454
+ def rl=(rl)
455
+ @rl = case rl
456
+ when "official-fix", "O" then ::Cvss3::Metrics::REMEDIATION_LEVEL[:official]
457
+ when "temporary-fix", "T", "TF" then ::Cvss3::Metrics::REMEDIATION_LEVEL[:temporary]
458
+ when "workaround", "W" then ::Cvss3::Metrics::REMEDIATION_LEVEL[:workaround]
459
+ when "unavailable", "U" then ::Cvss3::Metrics::REMEDIATION_LEVEL[:unavailable]
460
+ when "not defined", "ND", "X" then ::Cvss3::Metrics::REMEDIATION_LEVEL[:not_defined]
461
+ else
462
+ raise "Bad Argument"
463
+ end
464
+ end
465
+
466
+ def rl
467
+ rl = get_key("REMEDIATION_LEVEL", @rl) if !@rl.nil?
468
+ end
469
+
470
+ def rc=(rc)
471
+ @rc = case rc
472
+ when "unknown", "U" then ::Cvss3::Metrics::REPORT_CONFIDENCE[:unknown]
473
+ when "reasonable", "R" then ::Cvss3::Metrics::REPORT_CONFIDENCE[:reasonable]
474
+ when "confirmed", "C" then ::Cvss3::Metrics::REPORT_CONFIDENCE[:confirmed]
475
+ when "not defined", "ND", "X" then ::Cvss3::Metrics::REPORT_CONFIDENCE[:not_defined]
476
+ else
477
+ raise "Bad Argument"
478
+ end
479
+ end
480
+
481
+ def rc
482
+ rc = get_key("REPORT_CONFIDENCE", @rc) if !@av.nil?
483
+ end
484
+
485
+ def cr=(cr)
486
+ @cr = case cr
487
+ when "low", "L" then ::Cvss3::Metrics::CIA_REQUIREMENT[:low]
488
+ when "medium", "M" then ::Cvss3::Metrics::CIA_REQUIREMENT[:medium]
489
+ when "high", "H" then ::Cvss3::Metrics::CIA_REQUIREMENT[:high]
490
+ when "not defined", "ND", "X" then ::Cvss3::Metrics::CIA_REQUIREMENT[:not_defined]
491
+ else
492
+ raise "Bad Argument"
493
+ end
494
+ end
495
+
496
+ def cr
497
+ cr = get_key("CIA_REQUIREMENT", @cr) if !@cr.nil?
498
+ end
499
+
500
+ def ir=(ir)
501
+ @ir = case ir
502
+ when "low", "L" then ::Cvss3::Metrics::CIA_REQUIREMENT[:low]
503
+ when "medium", "M" then ::Cvss3::Metrics::CIA_REQUIREMENT[:medium]
504
+ when "high", "H" then ::Cvss3::Metrics::CIA_REQUIREMENT[:high]
505
+ when "not defined", "ND", "X" then ::Cvss3::Metrics::CIA_REQUIREMENT[:not_defined]
506
+ else
507
+ raise "Bad Argument"
508
+ end
509
+ end
510
+
511
+ def ir
512
+ ir = get_key("CIA_REQUIREMENT", @ir) if !@ir.nil?
513
+ end
514
+
515
+ def ar=(ar)
516
+ @ar = case ar
517
+ when "low", "L" then ::Cvss3::Metrics::CIA_REQUIREMENT[:low]
518
+ when "medium", "M" then ::Cvss3::Metrics::CIA_REQUIREMENT[:medium]
519
+ when "high", "H" then ::Cvss3::Metrics::CIA_REQUIREMENT[:high]
520
+ when "not defined", "ND", "X" then ::Cvss3::Metrics::CIA_REQUIREMENT[:not_defined]
521
+ else
522
+ raise "Bad Argument"
523
+ end
524
+ end
525
+
526
+ def ar
527
+ ar = get_key("CIA_REQUIREMENT", @ar) if !@ar.nil?
528
+ end
529
+
530
+
531
+ def init(ex = "ND", rl = "ND", rc = "ND", cd = "ND", td = "ND", cr = "ND", ir = "ND", ar = "ND",
532
+ mav = "ND", mac = "ND", mpv = "ND", mui = "ND", mc = "ND", mi = "ND", ma = "ND")
533
+ self.ex = ex
534
+ self.rl = rl
535
+ self.rc = rc
536
+
537
+ self.cr = cr
538
+ self.ir = ir
539
+ self.ar = ar
540
+
541
+ self.mav = mav
542
+ self.mac = mac
543
+ self.mpr = mpv
544
+ self.mui = mui
545
+
546
+ self.mc = mc
547
+ self.mi = mi
548
+ self.ma = ma
549
+ end
550
+
551
+ end
@@ -1,5 +1,5 @@
1
1
  module Cvss2
2
2
  class Rating
3
- VERSION = "0.2.2"
3
+ VERSION = "0.5.3"
4
4
  end
5
5
  end
@@ -2,7 +2,7 @@ require 'minitest/autorun'
2
2
  require 'active_support'
3
3
  require 'cvss2_rating'
4
4
 
5
- class CvssRatingTest < MiniTest::Unit::TestCase
5
+ class CvssRatingTest < MiniTest::Test
6
6
  def setup
7
7
  @cvss = Cvss2::Rating.new
8
8
  @cvss.av = "N"
@@ -0,0 +1,235 @@
1
+ require 'minitest/autorun'
2
+ require 'active_support'
3
+ require 'cvss3_rating'
4
+
5
+ class Cvss3RatingTest < MiniTest::Test
6
+ def setup
7
+ @cvss = Cvss3::Rating.new
8
+ @cvss.av = "P"
9
+ @cvss.ac = "H"
10
+ @cvss.ui = "R"
11
+ @cvss.pr = "L"
12
+ @cvss.sc = "C"
13
+ @cvss.ci = "H"
14
+ @cvss.ii = "low"
15
+ @cvss.ai = "N"
16
+
17
+ @cvss_2 = Cvss3::Rating.new
18
+ @cvss_2.av = "P"
19
+ @cvss_2.ac = "H"
20
+ @cvss_2.ui = "R"
21
+ @cvss_2.pr = "H"
22
+ @cvss_2.sc = "C"
23
+ @cvss_2.ci = "H"
24
+ @cvss_2.ii = "low"
25
+ @cvss_2.ai = "N"
26
+ @cvss_2.ex = "U"
27
+ @cvss_2.rl = "O"
28
+ @cvss_2.rc = "U"
29
+ @cvss_2.cr = "L"
30
+ @cvss_2.ir = "L"
31
+ @cvss_2.ar = "L"
32
+ end
33
+
34
+ def test_cvss_rating_from_vector
35
+ cvss = Cvss3::Rating.new
36
+ cvss.parse("AV:P/AC:H/PR:L/UI:R/S:C/C:H/I:L/A:N")
37
+
38
+ assert_equal @cvss.ai, cvss.ai
39
+
40
+ assert_equal @cvss.ii, cvss.ii
41
+
42
+ assert_equal @cvss.av, cvss.av
43
+
44
+ assert_equal @cvss.ui, cvss.ui
45
+
46
+ assert_equal @cvss.key, cvss.key
47
+
48
+ cvss = Cvss3::Rating.new
49
+ cvss.parse("AV:P/AC:H/PR:H/UI:R/S:C/C:H/I:L/A:N/E:U/RL:O/RC:U/CR:L/IR:L/AR:L")
50
+
51
+ assert_equal @cvss_2.ai, cvss.ai
52
+
53
+ assert_equal @cvss_2.ii, cvss.ii
54
+
55
+ assert_equal @cvss_2.av, cvss.av
56
+
57
+ assert_equal @cvss_2.key, cvss.key
58
+ end
59
+
60
+ def test_valid_vector
61
+ cvss = Cvss3::Rating.new
62
+
63
+ err = assert_raises RuntimeError do
64
+ cvss.parse("AV:P/AC:H/PR:L/UI:R/S:U/C:H/I:X/A:N")
65
+ end
66
+
67
+ assert_match /Bad Argument/, err.message
68
+
69
+ err = assert_raises RuntimeError do
70
+ cvss.parse("CVSS:9.9/AV:P/AC:H/PR:L/UI:R/S:U/C:H/I:L/A:N")
71
+ end
72
+
73
+ assert_match /Bad CVSS 3.0 Vector String/, err.message
74
+ end
75
+
76
+ def test_cvss_rating_parameters
77
+ cvss = Cvss3::Rating.new
78
+
79
+ cvss.av = "physical"
80
+
81
+ assert_equal @cvss.av, cvss.av
82
+
83
+ cvss.pr = 'low'
84
+
85
+ assert_equal @cvss.pr, cvss.pr
86
+
87
+ cvss.ci = 'high'
88
+
89
+ assert_equal @cvss.ci, cvss.ci
90
+
91
+ cvss.ai = 'none'
92
+
93
+ assert_equal @cvss.ai, cvss.ai
94
+
95
+ end
96
+
97
+ def test_cvss_risk_rating
98
+ cvss = Cvss3::Rating.new
99
+
100
+ assert_equal "None", cvss.risk_score(0.0)
101
+
102
+ assert_equal "Low", cvss.risk_score(2.0)
103
+
104
+ assert_equal "Medium", cvss.risk_score(5.1)
105
+
106
+ assert_equal "High", cvss.risk_score(7.1)
107
+
108
+ assert_equal "Critical", cvss.risk_score(10.0)
109
+
110
+ assert_equal nil, cvss.risk_score(11.0)
111
+ end
112
+
113
+ def test_base_score
114
+ cvss = Cvss3::Rating.new
115
+ cvss.parse("AV:P/AC:H/PR:L/UI:R/S:U/C:H/I:N/A:N")
116
+
117
+ score = cvss.cvss_base_score
118
+
119
+ assert_equal 3.9, score[0]
120
+
121
+ assert_equal "Low", score[1]
122
+
123
+ cvss = Cvss3::Rating.new
124
+ cvss.parse("AV:P/AC:H/PR:H/UI:R/S:C/C:H/I:L/A:N/E:U/RL:O/RC:U/CR:L/IR:L/AR:L")
125
+
126
+ score = cvss.cvss_base_score
127
+
128
+ assert_equal 5.4, score[0]
129
+
130
+ assert_equal "Medium", score[1]
131
+
132
+ end
133
+
134
+ def test_temporal_score
135
+ cvss = Cvss3::Rating.new
136
+ cvss.parse("AV:P/AC:H/PR:L/UI:R/S:U/C:H/I:N/A:N")
137
+
138
+ cvss.cvss_base_score
139
+
140
+ score = cvss.cvss_temporal_score
141
+
142
+ assert_equal 3.9, score[0]
143
+
144
+ assert_equal "Low", score[1]
145
+
146
+ cvss = Cvss3::Rating.new
147
+ cvss.parse("AV:P/AC:H/PR:H/UI:R/S:C/C:H/I:L/A:N/E:U/RL:O/RC:U/CR:L/IR:L/AR:L")
148
+
149
+ cvss.cvss_base_score
150
+
151
+ score = cvss.cvss_temporal_score
152
+
153
+ assert_equal 4.3, score[0]
154
+
155
+ assert_equal "Medium", score[1]
156
+ end
157
+
158
+ def test_environmental_score
159
+ cvss = Cvss3::Rating.new
160
+ cvss.parse("AV:P/AC:H/PR:L/UI:R/S:U/C:H/I:N/A:N")
161
+
162
+ cvss.cvss_base_score
163
+
164
+ score = cvss.cvss_environmental_score
165
+
166
+ assert_equal 3.9, score[0]
167
+
168
+ assert_equal "Low", score[1]
169
+
170
+ cvss = Cvss3::Rating.new
171
+ cvss.parse("AV:P/AC:H/PR:H/UI:R/S:C/C:H/I:L/A:N/E:U/RL:O/RC:U/CR:L/IR:L/AR:L")
172
+
173
+ cvss.cvss_base_score
174
+
175
+ score = cvss.cvss_environmental_score
176
+
177
+ assert_equal 2.4, score[0]
178
+
179
+ assert_equal "Low", score[1]
180
+
181
+ cvss = Cvss3::Rating.new
182
+ cvss.parse("AV:P/AC:H/PR:H/UI:R/S:C/C:H/I:L/A:N/E:U/RL:O/RC:U/IR:L/AR:L/MAV:A/MPR:N")
183
+
184
+ cvss.cvss_base_score
185
+
186
+ score = cvss.cvss_environmental_score
187
+
188
+ assert_equal 4.8, score[0]
189
+
190
+ assert_equal "Medium", score[1]
191
+
192
+ cvss = Cvss3::Rating.new
193
+ cvss.parse("CVSS:3.0/AV:P/AC:H/PR:H/UI:R/S:C/C:H/I:L/A:N/E:U/RL:O/RC:U/MAV:N/MS:U")
194
+
195
+ cvss.cvss_base_score
196
+
197
+ score = cvss.cvss_environmental_score
198
+
199
+ assert_equal 3.9, score[0]
200
+
201
+ assert_equal "Low", score[1]
202
+ end
203
+
204
+ def test_all_scores
205
+ cvss = Cvss3::Rating.new
206
+ cvss.parse("AV:P/AC:H/PR:H/UI:R/S:U/C:N/I:N/A:N/E:X/RL:X/RC:X")
207
+
208
+ score = cvss.cvss_base_score
209
+
210
+ assert_equal 0.0, score[0]
211
+
212
+ score = cvss.cvss_temporal_score
213
+
214
+ assert_equal 0.0, score[0]
215
+
216
+ score = cvss.cvss_environmental_score
217
+
218
+ assert_equal 0.0, score[0]
219
+
220
+ cvss.parse("AV:L/AC:L/PR:H/UI:R/S:U/C:H/I:N/A:H/E:H/RL:W/RC:U/CR:H/IR:H/AR:M/MAV:L/MAC:L/MPR:H/MUI:N/MS:C/MC:N/MI:H/MA:L")
221
+
222
+ score = cvss.cvss_base_score
223
+
224
+ assert_equal 5.8, score[0]
225
+
226
+ score = cvss.cvss_temporal_score
227
+
228
+ assert_equal 5.2, score[0]
229
+
230
+ score = cvss.cvss_environmental_score
231
+
232
+ assert_equal 7.4, score[0]
233
+ end
234
+
235
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cvss_rating
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.5.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen Kapp
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-19 00:00:00.000000000 Z
11
+ date: 2015-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -67,7 +67,7 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  description: CVSS Risk Rating Calculation and Vector parsing, implements CVSS 2.0
70
- rating
70
+ & 3.0 rating
71
71
  email:
72
72
  - mort666@virus.org
73
73
  executables: []
@@ -82,8 +82,13 @@ files:
82
82
  - Rakefile
83
83
  - cvss_rating.gemspec
84
84
  - lib/cvss2_rating.rb
85
+ - lib/cvss3_rating.rb
86
+ - lib/cvss_rating/cvss3_formulas.rb
87
+ - lib/cvss_rating/cvss3_metrics.rb
88
+ - lib/cvss_rating/cvss3_vectors.rb
85
89
  - lib/cvss_rating/version.rb
86
90
  - test/cvss2_rating_test.rb
91
+ - test/cvss3_rating_test.rb
87
92
  homepage: https://github.com/mort666/cvss_rating
88
93
  licenses:
89
94
  - MIT
@@ -110,3 +115,4 @@ specification_version: 4
110
115
  summary: CVSS Risk Rating Calculation and Vector parsing
111
116
  test_files:
112
117
  - test/cvss2_rating_test.rb
118
+ - test/cvss3_rating_test.rb