cvss-suite 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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 '../../../lib/cvss_suite/cvss'
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
- class Cvss31 < Cvss
20
+ module CvssSuite
21
+ class Cvss31 < Cvss
22
+ ##
23
+ # Returns the Version of the CVSS vector.
20
24
 
21
- ##
22
- # Returns the Base Score of the CVSS vector.
25
+ def version
26
+ 3.1
27
+ end
23
28
 
24
- def base_score
25
- check_validity
26
- @base.score.roundup
27
- end
29
+ ##
30
+ # Returns the Base Score of the CVSS vector.
28
31
 
29
- ##
30
- # Returns the Temporal Score of the CVSS vector.
32
+ def base_score
33
+ check_validity
34
+ Cvss31Helper.round_up(@base.score)
35
+ end
31
36
 
32
- def temporal_score
33
- (@base.score.roundup * @temporal.score).roundup
34
- end
37
+ ##
38
+ # Returns the Temporal Score of the CVSS vector.
35
39
 
36
- ##
37
- # Returns the Environmental Score of the CVSS vector.
40
+ def temporal_score
41
+ Cvss31Helper.round_up(Cvss31Helper.round_up(@base.score) * @temporal.score)
42
+ end
38
43
 
39
- def environmental_score
40
- return temporal_score unless @environmental.valid?
41
- (@environmental.score @temporal.score).roundup
42
- end
44
+ ##
45
+ # Returns the Environmental Score of the CVSS vector.
43
46
 
44
- private
47
+ def environmental_score
48
+ return temporal_score unless @environmental.valid?
45
49
 
46
- def init_metrics
47
- @base = Cvss31Base.new(@properties)
48
- @temporal = Cvss31Temporal.new(@properties)
49
- @environmental = Cvss31Environmental.new(@properties)
50
- end
50
+ Cvss31Helper.round_up(@environmental.score(@temporal.score))
51
+ end
52
+
53
+ private
51
54
 
52
- end
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
- class Cvss31Base < CvssMetric
18
+ module CvssSuite
19
+ class Cvss31Base < CvssMetric
20
+ ##
21
+ # Property of this metric
19
22
 
20
- ##
21
- # Property of this metric
23
+ attr_reader :attack_vector, :attack_complexity, :privileges_required, :user_interaction,
24
+ :scope, :confidentiality, :integrity, :availability
22
25
 
23
- attr_reader :attack_vector, :attack_complexity, :privileges_required, :user_interaction,
24
- :scope, :confidentiality, :integrity, :availability
26
+ ##
27
+ # Returns score of this metric
25
28
 
26
- ##
27
- # Returns score of this metric
29
+ def score
30
+ privilege_score = Cvss3Helper.privileges_required_score(@privileges_required, @scope)
28
31
 
29
- def score
32
+ exploitability = 8.22 * @attack_vector.score * @attack_complexity.score * privilege_score * @user_interaction.score
30
33
 
31
- privilege_score = Cvss3Helper.privileges_required_score @privileges_required, @scope
34
+ isc_base = 1 - ((1 - @confidentiality.score) * (1 - @integrity.score) * (1 - @availability.score))
32
35
 
33
- exploitability = 8.22 * @attack_vector.score * @attack_complexity.score * privilege_score * @user_interaction.score
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
- isc_base = 1 - ((1 - @confidentiality.score) * (1 - @integrity.score) * (1 - @availability.score))
42
+ return 0 if impact_sub_score <= 0
36
43
 
37
- if @scope.selected_choice[:name] == 'Changed'
38
- impact_sub_score = 7.52 * (isc_base - 0.029) - 3.25 * (isc_base - 0.02)**15
39
- else
40
- impact_sub_score = 6.42 * isc_base
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
- return 0 if impact_sub_score <= 0
44
-
45
- if @scope.selected_choice[:name] == 'Changed'
46
- [10, 1.08 * (impact_sub_score + exploitability)].min
47
- else
48
- [10, impact_sub_score + exploitability].min
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
- class Cvss31Environmental < CvssMetric
19
+ module CvssSuite
20
+ class Cvss31Environmental < CvssMetric
21
+ ##
22
+ # Property of this metric
19
23
 
20
- ##
21
- # Property of this metric
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
- attr_reader :confidentiality_requirement, :integrity_requirement, :availability_requirement,
24
- :modified_attack_vector, :modified_attack_complexity, :modified_privileges_required,
25
- :modified_user_interaction, :modified_scope, :modified_confidentiality,
26
- :modified_integrity, :modified_availability
29
+ ##
30
+ # Returns score of this metric
27
31
 
28
- ##
29
- # Returns score of this metric
32
+ def score(temporal_score)
33
+ privilege_score = Cvss3Helper.privileges_required_score(@modified_privileges_required, @modified_scope)
30
34
 
31
- def score(temporal_score)
35
+ modified_exploitability_sub_score = modified_exploitability_sub(privilege_score)
32
36
 
33
- privilege_score = Cvss3Helper.privileges_required_score @modified_privileges_required, @modified_scope
37
+ modified_impact_sub_score = modified_impact_sub(isc_modified)
34
38
 
35
- modified_exploitability_sub_score = modified_exploitability_sub privilege_score
39
+ return 0 if modified_impact_sub_score <= 0
36
40
 
37
- isc_modified_score = isc_modified
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
- def modified_impact_sub(isc_modified)
116
- if @modified_scope.selected_choice[:name] == 'Changed'
117
- 7.52 * (isc_modified - 0.029) - 3.25 * (isc_modified * 0.9731 - 0.02)**13
118
- else
119
- 6.42 * isc_modified
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
- def isc_modified
124
- confidentiality_score = 1 - @modified_confidentiality.score * @confidentiality_requirement.score
125
- integrity_score = 1 - @modified_integrity.score * @integrity_requirement.score
126
- availability_score = 1 - @modified_availability.score * @availability_requirement.score
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
- [0.915, (1 - confidentiality_score * integrity_score * availability_score)].min
129
- end
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
- def modified_exploitability_sub(privilege_score)
132
- modified_exploitability_sub_score = 8.22 * @modified_attack_vector.score
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
- def calculate_score(modified_impact_sub_score, modified_exploitability_sub_score, temporal_score)
139
- factor = @modified_scope.selected_choice[:name] == 'Changed' ? 1.08 : 1.0
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
- ([factor * (modified_impact_sub_score + modified_exploitability_sub_score), 10].min.round_up(1) * temporal_score)
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