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.
@@ -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