cvss-suite 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/rspec.yml +23 -0
- data/.rubocop.yml +6 -1
- data/.rubocop_todo.yml +124 -0
- data/CHANGES.md +24 -0
- data/README.md +5 -2
- data/_config.yml +1 -0
- data/bin/console +3 -3
- data/cvss_suite.gemspec +13 -13
- data/lib/cvss_suite.rb +7 -8
- data/lib/cvss_suite/cvss.rb +81 -85
- data/lib/cvss_suite/cvss2/cvss2.rb +34 -26
- data/lib/cvss_suite/cvss2/cvss2_base.rb +70 -73
- data/lib/cvss_suite/cvss2/cvss2_environmental.rb +49 -50
- data/lib/cvss_suite/cvss2/cvss2_temporal.rb +41 -39
- data/lib/cvss_suite/cvss3/cvss3.rb +34 -26
- data/lib/cvss_suite/cvss3/cvss3_base.rb +64 -65
- data/lib/cvss_suite/cvss3/cvss3_environmental.rb +108 -111
- data/lib/cvss_suite/cvss3/cvss3_temporal.rb +42 -40
- data/lib/cvss_suite/cvss31/cvss31.rb +35 -26
- data/lib/cvss_suite/cvss31/cvss31_base.rb +64 -65
- data/lib/cvss_suite/cvss31/cvss31_environmental.rb +109 -111
- data/lib/cvss_suite/cvss31/cvss31_temporal.rb +42 -40
- data/lib/cvss_suite/cvss_metric.rb +31 -31
- data/lib/cvss_suite/cvss_property.rb +56 -54
- data/lib/cvss_suite/helpers/cvss31_helper.rb +27 -0
- data/lib/cvss_suite/helpers/cvss3_helper.rb +20 -13
- data/lib/cvss_suite/invalid_cvss.rb +31 -32
- data/lib/cvss_suite/version.rb +1 -1
- metadata +10 -22
- data/.travis.yml +0 -4
- data/lib/cvss_suite/helpers/extensions.rb +0 -56
@@ -8,45 +8,54 @@
|
|
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
|
-
require_relative '
|
11
|
+
require_relative '../cvss'
|
12
12
|
require_relative 'cvss31_base'
|
13
13
|
require_relative 'cvss31_temporal'
|
14
14
|
require_relative 'cvss31_environmental'
|
15
|
+
require_relative '../helpers/cvss31_helper'
|
15
16
|
|
16
17
|
##
|
17
18
|
# This class represents a CVSS vector in version 3.1.
|
18
19
|
|
19
|
-
|
20
|
+
module CvssSuite
|
21
|
+
class Cvss31 < Cvss
|
22
|
+
##
|
23
|
+
# Returns the Version of the CVSS vector.
|
20
24
|
|
21
|
-
|
22
|
-
|
25
|
+
def version
|
26
|
+
3.1
|
27
|
+
end
|
23
28
|
|
24
|
-
|
25
|
-
|
26
|
-
@base.score.roundup
|
27
|
-
end
|
29
|
+
##
|
30
|
+
# Returns the Base Score of the CVSS vector.
|
28
31
|
|
29
|
-
|
30
|
-
|
32
|
+
def base_score
|
33
|
+
check_validity
|
34
|
+
Cvss31Helper.round_up(@base.score)
|
35
|
+
end
|
31
36
|
|
32
|
-
|
33
|
-
|
34
|
-
end
|
37
|
+
##
|
38
|
+
# Returns the Temporal Score of the CVSS vector.
|
35
39
|
|
36
|
-
|
37
|
-
|
40
|
+
def temporal_score
|
41
|
+
Cvss31Helper.round_up(Cvss31Helper.round_up(@base.score) * @temporal.score)
|
42
|
+
end
|
38
43
|
|
39
|
-
|
40
|
-
|
41
|
-
(@environmental.score @temporal.score).roundup
|
42
|
-
end
|
44
|
+
##
|
45
|
+
# Returns the Environmental Score of the CVSS vector.
|
43
46
|
|
44
|
-
|
47
|
+
def environmental_score
|
48
|
+
return temporal_score unless @environmental.valid?
|
45
49
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
end
|
50
|
+
Cvss31Helper.round_up(@environmental.score(@temporal.score))
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
51
54
|
|
52
|
-
|
55
|
+
def init_metrics
|
56
|
+
@base = Cvss31Base.new(@properties)
|
57
|
+
@temporal = Cvss31Temporal.new(@properties)
|
58
|
+
@environmental = Cvss31Environmental.new(@properties)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -15,81 +15,80 @@ require_relative '../helpers/cvss3_helper'
|
|
15
15
|
##
|
16
16
|
# This class represents a CVSS Base metric in version 3.1.
|
17
17
|
|
18
|
-
|
18
|
+
module CvssSuite
|
19
|
+
class Cvss31Base < CvssMetric
|
20
|
+
##
|
21
|
+
# Property of this metric
|
19
22
|
|
20
|
-
|
21
|
-
|
23
|
+
attr_reader :attack_vector, :attack_complexity, :privileges_required, :user_interaction,
|
24
|
+
:scope, :confidentiality, :integrity, :availability
|
22
25
|
|
23
|
-
|
24
|
-
|
26
|
+
##
|
27
|
+
# Returns score of this metric
|
25
28
|
|
26
|
-
|
27
|
-
|
29
|
+
def score
|
30
|
+
privilege_score = Cvss3Helper.privileges_required_score(@privileges_required, @scope)
|
28
31
|
|
29
|
-
|
32
|
+
exploitability = 8.22 * @attack_vector.score * @attack_complexity.score * privilege_score * @user_interaction.score
|
30
33
|
|
31
|
-
|
34
|
+
isc_base = 1 - ((1 - @confidentiality.score) * (1 - @integrity.score) * (1 - @availability.score))
|
32
35
|
|
33
|
-
|
36
|
+
impact_sub_score = if @scope.selected_choice[:name] == 'Changed'
|
37
|
+
7.52 * (isc_base - 0.029) - 3.25 * (isc_base - 0.02)**15
|
38
|
+
else
|
39
|
+
6.42 * isc_base
|
40
|
+
end
|
34
41
|
|
35
|
-
|
42
|
+
return 0 if impact_sub_score <= 0
|
36
43
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
44
|
+
if @scope.selected_choice[:name] == 'Changed'
|
45
|
+
[10, 1.08 * (impact_sub_score + exploitability)].min
|
46
|
+
else
|
47
|
+
[10, impact_sub_score + exploitability].min
|
48
|
+
end
|
41
49
|
end
|
42
50
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
51
|
+
private
|
52
|
+
|
53
|
+
def init_properties
|
54
|
+
@properties.push(@attack_vector =
|
55
|
+
CvssProperty.new(name: 'Attack Vector', abbreviation: 'AV', position: [0],
|
56
|
+
choices: [{ name: 'Network', abbreviation: 'N', weight: 0.85 },
|
57
|
+
{ name: 'Adjacent', abbreviation: 'A', weight: 0.62 },
|
58
|
+
{ name: 'Local', abbreviation: 'L', weight: 0.55 },
|
59
|
+
{ name: 'Physical', abbreviation: 'P', weight: 0.2 }]))
|
60
|
+
@properties.push(@attack_complexity =
|
61
|
+
CvssProperty.new(name: 'Attack Complexity', abbreviation: 'AC', position: [1],
|
62
|
+
choices: [{ name: 'Low', abbreviation: 'L', weight: 0.77 },
|
63
|
+
{ name: 'High', abbreviation: 'H', weight: 0.44 }]))
|
64
|
+
@properties.push(@privileges_required =
|
65
|
+
CvssProperty.new(name: 'Privileges Required', abbreviation: 'PR', position: [2],
|
66
|
+
choices: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
|
67
|
+
{ name: 'Low', abbreviation: 'L', weight: 0.62 },
|
68
|
+
{ name: 'High', abbreviation: 'H', weight: 0.27 }]))
|
69
|
+
@properties.push(@user_interaction =
|
70
|
+
CvssProperty.new(name: 'User Interaction', abbreviation: 'UI', position: [3],
|
71
|
+
choices: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
|
72
|
+
{ name: 'Required', abbreviation: 'R', weight: 0.62 }]))
|
73
|
+
@properties.push(@scope =
|
74
|
+
CvssProperty.new(name: 'Scope', abbreviation: 'S', position: [4],
|
75
|
+
choices: [{ name: 'Unchanged', abbreviation: 'U' },
|
76
|
+
{ name: 'Changed', abbreviation: 'C' }]))
|
77
|
+
@properties.push(@confidentiality =
|
78
|
+
CvssProperty.new(name: 'Confidentiality', abbreviation: 'C', position: [5],
|
79
|
+
choices: [{ name: 'None', abbreviation: 'N', weight: 0.0 },
|
80
|
+
{ name: 'Low', abbreviation: 'L', weight: 0.22 },
|
81
|
+
{ name: 'High', abbreviation: 'H', weight: 0.56 }]))
|
82
|
+
@properties.push(@integrity =
|
83
|
+
CvssProperty.new(name: 'Integrity', abbreviation: 'I', position: [6],
|
84
|
+
choices: [{ name: 'None', abbreviation: 'N', weight: 0.0 },
|
85
|
+
{ name: 'Low', abbreviation: 'L', weight: 0.22 },
|
86
|
+
{ name: 'High', abbreviation: 'H', weight: 0.56 }]))
|
87
|
+
@properties.push(@availability =
|
88
|
+
CvssProperty.new(name: 'Availability', abbreviation: 'A', position: [7],
|
89
|
+
choices: [{ name: 'None', abbreviation: 'N', weight: 0.0 },
|
90
|
+
{ name: 'Low', abbreviation: 'L', weight: 0.22 },
|
91
|
+
{ name: 'High', abbreviation: 'H', weight: 0.56 }]))
|
49
92
|
end
|
50
93
|
end
|
51
|
-
|
52
|
-
private
|
53
|
-
|
54
|
-
def init_properties
|
55
|
-
@properties.push(@attack_vector =
|
56
|
-
CvssProperty.new(name: 'Attack Vector', abbreviation: 'AV', position: [0],
|
57
|
-
choices: [{ name: 'Network', abbreviation: 'N', weight: 0.85 },
|
58
|
-
{ name: 'Adjacent', abbreviation: 'A', weight: 0.62 },
|
59
|
-
{ name: 'Local', abbreviation: 'L', weight: 0.55 },
|
60
|
-
{ name: 'Physical', abbreviation: 'P', weight: 0.2 }]))
|
61
|
-
@properties.push(@attack_complexity =
|
62
|
-
CvssProperty.new(name: 'Attack Complexity', abbreviation: 'AC', position: [1],
|
63
|
-
choices: [{ name: 'Low', abbreviation: 'L', weight: 0.77 },
|
64
|
-
{ name: 'High', abbreviation: 'H', weight: 0.44 }]))
|
65
|
-
@properties.push(@privileges_required =
|
66
|
-
CvssProperty.new(name: 'Privileges Required', abbreviation: 'PR', position: [2],
|
67
|
-
choices: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
|
68
|
-
{ name: 'Low', abbreviation: 'L', weight: 0.62 },
|
69
|
-
{ name: 'High', abbreviation: 'H', weight: 0.27 }]))
|
70
|
-
@properties.push(@user_interaction =
|
71
|
-
CvssProperty.new(name: 'User Interaction', abbreviation: 'UI', position: [3],
|
72
|
-
choices: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
|
73
|
-
{ name: 'Required', abbreviation: 'R', weight: 0.62 }]))
|
74
|
-
@properties.push(@scope =
|
75
|
-
CvssProperty.new(name: 'Scope', abbreviation: 'S', position: [4],
|
76
|
-
choices: [{ name: 'Unchanged', abbreviation: 'U' },
|
77
|
-
{ name: 'Changed', abbreviation: 'C' }]))
|
78
|
-
@properties.push(@confidentiality =
|
79
|
-
CvssProperty.new(name: 'Confidentiality', abbreviation: 'C', position: [5],
|
80
|
-
choices: [{ name: 'None', abbreviation: 'N', weight: 0.0 },
|
81
|
-
{ name: 'Low', abbreviation: 'L', weight: 0.22 },
|
82
|
-
{ name: 'High', abbreviation: 'H', weight: 0.56 }]))
|
83
|
-
@properties.push(@integrity =
|
84
|
-
CvssProperty.new(name: 'Integrity', abbreviation: 'I', position: [6],
|
85
|
-
choices: [{ name: 'None', abbreviation: 'N', weight: 0.0 },
|
86
|
-
{ name: 'Low', abbreviation: 'L', weight: 0.22 },
|
87
|
-
{ name: 'High', abbreviation: 'H', weight: 0.56 }]))
|
88
|
-
@properties.push(@availability =
|
89
|
-
CvssProperty.new(name: 'Availability', abbreviation: 'A', position: [7],
|
90
|
-
choices: [{ name: 'None', abbreviation: 'N', weight: 0.0 },
|
91
|
-
{ name: 'Low', abbreviation: 'L', weight: 0.22 },
|
92
|
-
{ name: 'High', abbreviation: 'H', weight: 0.56 }]))
|
93
|
-
end
|
94
94
|
end
|
95
|
-
|
@@ -11,134 +11,132 @@
|
|
11
11
|
require_relative '../cvss_property'
|
12
12
|
require_relative '../cvss_metric'
|
13
13
|
require_relative '../helpers/cvss3_helper'
|
14
|
+
require_relative '../helpers/cvss31_helper'
|
14
15
|
|
15
16
|
##
|
16
17
|
# This class represents a CVSS Environmental metric in version 3.1.
|
17
18
|
|
18
|
-
|
19
|
+
module CvssSuite
|
20
|
+
class Cvss31Environmental < CvssMetric
|
21
|
+
##
|
22
|
+
# Property of this metric
|
19
23
|
|
20
|
-
|
21
|
-
|
24
|
+
attr_reader :confidentiality_requirement, :integrity_requirement, :availability_requirement,
|
25
|
+
:modified_attack_vector, :modified_attack_complexity, :modified_privileges_required,
|
26
|
+
:modified_user_interaction, :modified_scope, :modified_confidentiality,
|
27
|
+
:modified_integrity, :modified_availability
|
22
28
|
|
23
|
-
|
24
|
-
|
25
|
-
:modified_user_interaction, :modified_scope, :modified_confidentiality,
|
26
|
-
:modified_integrity, :modified_availability
|
29
|
+
##
|
30
|
+
# Returns score of this metric
|
27
31
|
|
28
|
-
|
29
|
-
|
32
|
+
def score(temporal_score)
|
33
|
+
privilege_score = Cvss3Helper.privileges_required_score(@modified_privileges_required, @modified_scope)
|
30
34
|
|
31
|
-
|
35
|
+
modified_exploitability_sub_score = modified_exploitability_sub(privilege_score)
|
32
36
|
|
33
|
-
|
37
|
+
modified_impact_sub_score = modified_impact_sub(isc_modified)
|
34
38
|
|
35
|
-
|
39
|
+
return 0 if modified_impact_sub_score <= 0
|
36
40
|
|
37
|
-
|
38
|
-
|
39
|
-
modified_impact_sub_score = modified_impact_sub isc_modified_score
|
40
|
-
|
41
|
-
return 0 if modified_impact_sub_score <= 0
|
42
|
-
|
43
|
-
calculate_score modified_impact_sub_score, modified_exploitability_sub_score, temporal_score
|
44
|
-
end
|
45
|
-
|
46
|
-
private
|
47
|
-
|
48
|
-
def init_properties
|
49
|
-
@properties.push(@confidentiality_requirement =
|
50
|
-
CvssProperty.new(name: 'Confidentiality Requirement', abbreviation: 'CR', position: [8, 11],
|
51
|
-
choices: [{name: 'Low', abbreviation: 'L', weight: 0.5},
|
52
|
-
{name: 'Medium', abbreviation: 'M', weight: 1.0},
|
53
|
-
{name: 'High', abbreviation: 'H', weight: 1.5},
|
54
|
-
{name: 'Not Defined', abbreviation: 'X', weight: 1}]))
|
55
|
-
@properties.push(@integrity_requirement =
|
56
|
-
CvssProperty.new(name: 'Integrity Requirement', abbreviation: 'IR', position: [9, 12],
|
57
|
-
choices: [{name: 'Low', abbreviation: 'L', weight: 0.5},
|
58
|
-
{name: 'Medium', abbreviation: 'M', weight: 1.0},
|
59
|
-
{name: 'High', abbreviation: 'H', weight: 1.5},
|
60
|
-
{name: 'Not Defined', abbreviation: 'X', weight: 1}]))
|
61
|
-
|
62
|
-
@properties.push(@availability_requirement =
|
63
|
-
CvssProperty.new(name: 'Availability Requirement', abbreviation: 'AR', position: [10, 13],
|
64
|
-
choices: [{name: 'Low', abbreviation: 'L', weight: 0.5},
|
65
|
-
{name: 'Medium', abbreviation: 'M', weight: 1.0},
|
66
|
-
{name: 'High', abbreviation: 'H', weight: 1.5},
|
67
|
-
{name: 'Not Defined', abbreviation: 'X', weight: 1}]))
|
68
|
-
@properties.push(@modified_attack_vector =
|
69
|
-
CvssProperty.new(name: 'Modified Attack Vector', abbreviation: 'MAV', position: [11, 14],
|
70
|
-
choices: [{name: 'Network', abbreviation: 'N', weight: 0.85},
|
71
|
-
{name: 'Adjacent Network', abbreviation: 'A', weight: 0.62},
|
72
|
-
{name: 'Local', abbreviation: 'L', weight: 0.55},
|
73
|
-
{name: 'Physical', abbreviation: 'P', weight: 0.2},
|
74
|
-
{name: 'Not Defined', abbreviation: 'X', weight: 1}]))
|
75
|
-
@properties.push(@modified_attack_complexity =
|
76
|
-
CvssProperty.new(name: 'Modified Attack Complexity', abbreviation: 'MAC', position: [12, 15],
|
77
|
-
choices: [{name: 'Low', abbreviation: 'L', weight: 0.77},
|
78
|
-
{name: 'High', abbreviation: 'H', weight: 0.44},
|
79
|
-
{name: 'Not Defined', abbreviation: 'X', weight: 1}]))
|
80
|
-
@properties.push(@modified_privileges_required =
|
81
|
-
CvssProperty.new(name: 'Modified Privileges Required', abbreviation: 'MPR', position: [13, 16],
|
82
|
-
choices: [{name: 'None', abbreviation: 'N', weight: 0.85},
|
83
|
-
{name: 'Low', abbreviation: 'L', weight: 0.62},
|
84
|
-
{name: 'High', abbreviation: 'H', weight: 0.27},
|
85
|
-
{name: 'Not Defined', abbreviation: 'X', weight: 1}]))
|
86
|
-
@properties.push(@modified_user_interaction =
|
87
|
-
CvssProperty.new(name: 'Modified User Interaction', abbreviation: 'MUI', position: [14, 17],
|
88
|
-
choices: [{name: 'None', abbreviation: 'N', weight: 0.85},
|
89
|
-
{name: 'Required', abbreviation: 'R', weight: 0.62},
|
90
|
-
{name: 'Not Defined', abbreviation: 'X', weight: 1}]))
|
91
|
-
@properties.push(@modified_scope =
|
92
|
-
CvssProperty.new(name: 'Modified Scope', abbreviation: 'MS', position: [15, 18],
|
93
|
-
choices: [{name: 'Changed', abbreviation: 'C'},
|
94
|
-
{name: 'Unchanged', abbreviation: 'U'}]))
|
95
|
-
@properties.push(@modified_confidentiality =
|
96
|
-
CvssProperty.new(name: 'Modified Confidentiality', abbreviation: 'MC', position: [16, 19],
|
97
|
-
choices: [{name: 'None', abbreviation: 'N', weight: 0},
|
98
|
-
{name: 'Low', abbreviation: 'L', weight: 0.22},
|
99
|
-
{name: 'High', abbreviation: 'H', weight: 0.56},
|
100
|
-
{name: 'Not Defined', abbreviation: 'X', weight: 1}]))
|
101
|
-
@properties.push(@modified_integrity =
|
102
|
-
CvssProperty.new(name: 'Modified Integrity', abbreviation: 'MI', position: [17, 20],
|
103
|
-
choices: [{name: 'None', abbreviation: 'N', weight: 0},
|
104
|
-
{name: 'Low', abbreviation: 'L', weight: 0.22},
|
105
|
-
{name: 'High', abbreviation: 'H', weight: 0.56},
|
106
|
-
{name: 'Not Defined', abbreviation: 'X', weight: 1}]))
|
107
|
-
@properties.push(@modified_availability =
|
108
|
-
CvssProperty.new(name: 'Modified Availability', abbreviation: 'MA', position: [18, 21],
|
109
|
-
choices: [{name: 'None', abbreviation: 'N', weight: 0},
|
110
|
-
{name: 'Low', abbreviation: 'L', weight: 0.22},
|
111
|
-
{name: 'High', abbreviation: 'H', weight: 0.56},
|
112
|
-
{name: 'Not Defined', abbreviation: 'X', weight: 1}]))
|
113
|
-
end
|
41
|
+
calculate_score modified_impact_sub_score, modified_exploitability_sub_score, temporal_score
|
42
|
+
end
|
114
43
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
44
|
+
private
|
45
|
+
|
46
|
+
def init_properties
|
47
|
+
@properties.push(@confidentiality_requirement =
|
48
|
+
CvssProperty.new(name: 'Confidentiality Requirement', abbreviation: 'CR', position: [8, 11],
|
49
|
+
choices: [{ name: 'Low', abbreviation: 'L', weight: 0.5 },
|
50
|
+
{ name: 'Medium', abbreviation: 'M', weight: 1.0 },
|
51
|
+
{ name: 'High', abbreviation: 'H', weight: 1.5 },
|
52
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
53
|
+
@properties.push(@integrity_requirement =
|
54
|
+
CvssProperty.new(name: 'Integrity Requirement', abbreviation: 'IR', position: [9, 12],
|
55
|
+
choices: [{ name: 'Low', abbreviation: 'L', weight: 0.5 },
|
56
|
+
{ name: 'Medium', abbreviation: 'M', weight: 1.0 },
|
57
|
+
{ name: 'High', abbreviation: 'H', weight: 1.5 },
|
58
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
59
|
+
|
60
|
+
@properties.push(@availability_requirement =
|
61
|
+
CvssProperty.new(name: 'Availability Requirement', abbreviation: 'AR', position: [10, 13],
|
62
|
+
choices: [{ name: 'Low', abbreviation: 'L', weight: 0.5 },
|
63
|
+
{ name: 'Medium', abbreviation: 'M', weight: 1.0 },
|
64
|
+
{ name: 'High', abbreviation: 'H', weight: 1.5 },
|
65
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
66
|
+
@properties.push(@modified_attack_vector =
|
67
|
+
CvssProperty.new(name: 'Modified Attack Vector', abbreviation: 'MAV', position: [11, 14],
|
68
|
+
choices: [{ name: 'Network', abbreviation: 'N', weight: 0.85 },
|
69
|
+
{ name: 'Adjacent Network', abbreviation: 'A', weight: 0.62 },
|
70
|
+
{ name: 'Local', abbreviation: 'L', weight: 0.55 },
|
71
|
+
{ name: 'Physical', abbreviation: 'P', weight: 0.2 },
|
72
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
73
|
+
@properties.push(@modified_attack_complexity =
|
74
|
+
CvssProperty.new(name: 'Modified Attack Complexity', abbreviation: 'MAC', position: [12, 15],
|
75
|
+
choices: [{ name: 'Low', abbreviation: 'L', weight: 0.77 },
|
76
|
+
{ name: 'High', abbreviation: 'H', weight: 0.44 },
|
77
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
78
|
+
@properties.push(@modified_privileges_required =
|
79
|
+
CvssProperty.new(name: 'Modified Privileges Required', abbreviation: 'MPR', position: [13, 16],
|
80
|
+
choices: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
|
81
|
+
{ name: 'Low', abbreviation: 'L', weight: 0.62 },
|
82
|
+
{ name: 'High', abbreviation: 'H', weight: 0.27 },
|
83
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
84
|
+
@properties.push(@modified_user_interaction =
|
85
|
+
CvssProperty.new(name: 'Modified User Interaction', abbreviation: 'MUI', position: [14, 17],
|
86
|
+
choices: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
|
87
|
+
{ name: 'Required', abbreviation: 'R', weight: 0.62 },
|
88
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
89
|
+
@properties.push(@modified_scope =
|
90
|
+
CvssProperty.new(name: 'Modified Scope', abbreviation: 'MS', position: [15, 18],
|
91
|
+
choices: [{ name: 'Changed', abbreviation: 'C' },
|
92
|
+
{ name: 'Unchanged', abbreviation: 'U' }]))
|
93
|
+
@properties.push(@modified_confidentiality =
|
94
|
+
CvssProperty.new(name: 'Modified Confidentiality', abbreviation: 'MC', position: [16, 19],
|
95
|
+
choices: [{ name: 'None', abbreviation: 'N', weight: 0 },
|
96
|
+
{ name: 'Low', abbreviation: 'L', weight: 0.22 },
|
97
|
+
{ name: 'High', abbreviation: 'H', weight: 0.56 },
|
98
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
99
|
+
@properties.push(@modified_integrity =
|
100
|
+
CvssProperty.new(name: 'Modified Integrity', abbreviation: 'MI', position: [17, 20],
|
101
|
+
choices: [{ name: 'None', abbreviation: 'N', weight: 0 },
|
102
|
+
{ name: 'Low', abbreviation: 'L', weight: 0.22 },
|
103
|
+
{ name: 'High', abbreviation: 'H', weight: 0.56 },
|
104
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
105
|
+
@properties.push(@modified_availability =
|
106
|
+
CvssProperty.new(name: 'Modified Availability', abbreviation: 'MA', position: [18, 21],
|
107
|
+
choices: [{ name: 'None', abbreviation: 'N', weight: 0 },
|
108
|
+
{ name: 'Low', abbreviation: 'L', weight: 0.22 },
|
109
|
+
{ name: 'High', abbreviation: 'H', weight: 0.56 },
|
110
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
120
111
|
end
|
121
|
-
end
|
122
112
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
113
|
+
def modified_impact_sub(isc_modified)
|
114
|
+
if @modified_scope.selected_choice[:name] == 'Changed'
|
115
|
+
7.52 * (isc_modified - 0.029) - 3.25 * (isc_modified * 0.9731 - 0.02)**13
|
116
|
+
else
|
117
|
+
6.42 * isc_modified
|
118
|
+
end
|
119
|
+
end
|
127
120
|
|
128
|
-
|
129
|
-
|
121
|
+
def isc_modified
|
122
|
+
confidentiality_score = 1 - @modified_confidentiality.score * @confidentiality_requirement.score
|
123
|
+
integrity_score = 1 - @modified_integrity.score * @integrity_requirement.score
|
124
|
+
availability_score = 1 - @modified_availability.score * @availability_requirement.score
|
130
125
|
|
131
|
-
|
132
|
-
|
133
|
-
modified_exploitability_sub_score *= @modified_attack_complexity.score
|
134
|
-
modified_exploitability_sub_score *= privilege_score
|
135
|
-
modified_exploitability_sub_score *= @modified_user_interaction.score
|
136
|
-
end
|
126
|
+
[0.915, (1 - confidentiality_score * integrity_score * availability_score)].min
|
127
|
+
end
|
137
128
|
|
138
|
-
|
139
|
-
|
129
|
+
def modified_exploitability_sub(privilege_score)
|
130
|
+
8.22 * @modified_attack_vector.score * @modified_attack_complexity.score *
|
131
|
+
privilege_score * @modified_user_interaction.score
|
132
|
+
end
|
140
133
|
|
141
|
-
|
134
|
+
def calculate_score(modified_impact_sub_score, modified_exploitability_sub_score, temporal_score)
|
135
|
+
factor = @modified_scope.selected_choice[:name] == 'Changed' ? 1.08 : 1.0
|
142
136
|
|
137
|
+
Cvss31Helper.round_up(
|
138
|
+
[factor * (modified_impact_sub_score + modified_exploitability_sub_score), 10].min
|
139
|
+
) * temporal_score
|
140
|
+
end
|
143
141
|
end
|
144
|
-
end
|
142
|
+
end
|