cvss-suite 1.2.1 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 792fd7bf771ac83da4c5a4ee81cfce2e5ce42edf32d3a8d84ecdccdb8df1f555
4
- data.tar.gz: 6bc9148983a577d0e26ed5b19407ba6a366070e46166aae1a0b440c2328a59e4
3
+ metadata.gz: eba339bafe4db99aa85aadd132b2e10faeddc2cc5abc37b9554e5e14caaf9dd4
4
+ data.tar.gz: fbe718029edb8a08b0da04944bfac0b29b8e813dbb621b51b914bb3d644d832a
5
5
  SHA512:
6
- metadata.gz: ce3abc3c7f0c6eeaa02b3739da79e61445936bc8ee2e0c066252c06477022ec1aaf752ca18400727aac8f81f3627f96cb89fd932df261168d156f000da860db6
7
- data.tar.gz: c0ef0261fec46ae6340bf52f04e1739ffd92915b76039027fb98cf06db9ecd5e99472d31b54068c49618607ebdef6fd98e1b8a70bd2a7a097799d2321c17fe21
6
+ metadata.gz: 7576066639774a2e6ab36d716c657ff4e794f93d9eeda6565287772a5c097478877ba56a9fcf891b5c247fb15698bace28e92f4c2ea86e802f5c4a08e1046da2
7
+ data.tar.gz: 4c6f90f5431563ef303f9804f12375eb64f2b423e1e078dec2b62184b4f609fbcc0140e6bbcd483945014e1d681c820863efcc824f6b56816acc63ba16f32c51
@@ -2,6 +2,39 @@ inherit_from: .rubocop_todo.yml
2
2
 
3
3
  Metrics/LineLength:
4
4
  Max: 120
5
+ Exclude:
6
+ - 'lib/cvss_suite/cvss3/cvss3_environmental.rb'
7
+ - 'lib/cvss_suite/cvss31/cvss31_environmental.rb'
8
+
9
+ Metrics/ClassLength:
10
+ Exclude:
11
+ - 'lib/cvss_suite/cvss3/cvss3_environmental.rb'
12
+ - 'lib/cvss_suite/cvss31/cvss31_environmental.rb'
13
+
14
+ Metrics/MethodLength:
15
+ Exclude:
16
+ - 'lib/cvss_suite/cvss3/cvss3_environmental.rb'
17
+ - 'lib/cvss_suite/cvss31/cvss31_environmental.rb'
18
+
19
+ Metrics/BlockLength:
20
+ Exclude:
21
+ - 'spec/cvss3/cvss3_spec.rb'
22
+ - 'spec/cvss31/cvss31_spec.rb'
23
+
24
+ Style/IfUnlessModifier:
25
+ Exclude:
26
+ - 'lib/cvss_suite/cvss3/cvss3_environmental.rb'
27
+ - 'lib/cvss_suite/cvss31/cvss31_environmental.rb'
28
+
29
+ Style/GuardClause:
30
+ Exclude:
31
+ - 'lib/cvss_suite/cvss3/cvss3_environmental.rb'
32
+ - 'lib/cvss_suite/cvss31/cvss31_environmental.rb'
33
+
34
+ Style/ConditionalAssignment:
35
+ Exclude:
36
+ - 'lib/cvss_suite/cvss3/cvss3_environmental.rb'
37
+ - 'lib/cvss_suite/cvss31/cvss31_environmental.rb'
5
38
 
6
39
  Style/FrozenStringLiteralComment:
7
40
  Enabled: false
data/CHANGES.md CHANGED
@@ -2,6 +2,11 @@
2
2
  All notable changes to this project will be documented in this file.
3
3
  This project adheres to [Semantic Versioning](http://semver.org/).
4
4
 
5
+ ## [1.2.2] - 2020-07-19
6
+
7
+ ### Fixes
8
+ Fixed an error that resulted in incorrect environmental score if modified attributes were not defined.
9
+
5
10
  ## [1.2.1] - 2020-05-10
6
11
 
7
12
  ### Improvements
data/README.md CHANGED
@@ -100,8 +100,6 @@ Properties (Access Vector, Remediation Level, etc) do have a position attribute,
100
100
 
101
101
  Currently it is not possible to leave an attribute blank instead of ND/X. If you don't have a value for an attribute, please use ND/X instead.
102
102
 
103
- Because the documentation isn't clear on how to calculate the score if Modified Scope (CVSS 3.0 Environmental) is not defined, Modified Scope has to have a valid value (S/U).
104
-
105
103
  There is a possibility of implementations generating different scores (+/- 0,1) due to small floating-point inaccuracies. This can happen due to differences in floating point arithmetic between different languages and hardware platforms.
106
104
 
107
105
  ## Changelog
@@ -46,7 +46,7 @@ module CvssSuite
46
46
  def environmental_score
47
47
  return temporal_score unless @environmental.valid?
48
48
 
49
- Cvss3Helper.round_up(@environmental.score(@temporal.score))
49
+ Cvss3Helper.round_up(@environmental.score(@base, @temporal))
50
50
  end
51
51
 
52
52
  private
@@ -28,8 +28,20 @@ module CvssSuite
28
28
  ##
29
29
  # Returns score of this metric
30
30
 
31
- def score(temporal_score)
32
- privilege_score = Cvss3Helper.privileges_required_score(@modified_privileges_required, @modified_scope)
31
+ def score(base, temporal)
32
+ @base = base
33
+
34
+ merged_modified_privileges_required = @modified_privileges_required
35
+ if @modified_privileges_required.selected_choice[:name] == 'Not Defined'
36
+ merged_modified_privileges_required = @base.privileges_required
37
+ end
38
+
39
+ merged_modified_scope = @modified_scope
40
+ if @modified_scope.selected_choice[:name] == 'Not Defined'
41
+ merged_modified_scope = @base.scope
42
+ end
43
+
44
+ privilege_score = Cvss3Helper.privileges_required_score(merged_modified_privileges_required, merged_modified_scope)
33
45
 
34
46
  modified_exploitability_sub_score = modified_exploitability_sub(privilege_score)
35
47
 
@@ -37,7 +49,7 @@ module CvssSuite
37
49
 
38
50
  return 0 if modified_impact_sub_score <= 0
39
51
 
40
- calculate_score(modified_impact_sub_score, modified_exploitability_sub_score, temporal_score)
52
+ calculate_score modified_impact_sub_score, modified_exploitability_sub_score, temporal.score
41
53
  end
42
54
 
43
55
  private
@@ -88,7 +100,8 @@ module CvssSuite
88
100
  @properties.push(@modified_scope =
89
101
  CvssProperty.new(name: 'Modified Scope', abbreviation: 'MS', position: [15, 18],
90
102
  choices: [{ name: 'Changed', abbreviation: 'C' },
91
- { name: 'Unchanged', abbreviation: 'U' }]))
103
+ { name: 'Unchanged', abbreviation: 'U' },
104
+ { name: 'Not Defined', abbreviation: 'X' }]))
92
105
  @properties.push(@modified_confidentiality =
93
106
  CvssProperty.new(name: 'Modified Confidentiality', abbreviation: 'MC', position: [16, 19],
94
107
  choices: [{ name: 'None', abbreviation: 'N', weight: 0 },
@@ -110,6 +123,14 @@ module CvssSuite
110
123
  end
111
124
 
112
125
  def modified_impact_sub(isc_modified)
126
+ if @modified_scope.selected_choice[:name] == 'Not Defined'
127
+ if @base.scope.selected_choice[:name] == 'Changed'
128
+ return 7.52 * (isc_modified - 0.029) - 3.25 * (isc_modified - 0.02)**15
129
+ else
130
+ return 6.42 * isc_modified
131
+ end
132
+ end
133
+
113
134
  if @modified_scope.selected_choice[:name] == 'Changed'
114
135
  7.52 * (isc_modified - 0.029) - 3.25 * (isc_modified - 0.02)**15
115
136
  else
@@ -118,20 +139,54 @@ module CvssSuite
118
139
  end
119
140
 
120
141
  def isc_modified
121
- confidentiality_score = 1 - @modified_confidentiality.score * @confidentiality_requirement.score
122
- integrity_score = 1 - @modified_integrity.score * @integrity_requirement.score
123
- availability_score = 1 - @modified_availability.score * @availability_requirement.score
142
+ merged_modified_confidentiality = @modified_confidentiality
143
+ if @modified_confidentiality.selected_choice[:name] == 'Not Defined'
144
+ merged_modified_confidentiality = @base.confidentiality
145
+ end
146
+
147
+ merged_modified_integrity = @modified_integrity
148
+ if @modified_integrity.selected_choice[:name] == 'Not Defined'
149
+ merged_modified_integrity = @base.integrity
150
+ end
151
+
152
+ merged_modified_availability = @modified_availability
153
+ if @modified_availability.selected_choice[:name] == 'Not Defined'
154
+ merged_modified_availability = @base.availability
155
+ end
156
+
157
+ confidentiality_score = 1 - merged_modified_confidentiality.score * @confidentiality_requirement.score
158
+ integrity_score = 1 - merged_modified_integrity.score * @integrity_requirement.score
159
+ availability_score = 1 - merged_modified_availability.score * @availability_requirement.score
124
160
 
125
161
  [0.915, (1 - confidentiality_score * integrity_score * availability_score)].min
126
162
  end
127
163
 
128
164
  def modified_exploitability_sub(privilege_score)
129
- 8.22 * @modified_attack_vector.score * @modified_attack_complexity.score *
130
- privilege_score * @modified_user_interaction.score
165
+ merged_modified_attack_vector = @modified_attack_vector
166
+ if @modified_attack_vector.selected_choice[:name] == 'Not Defined'
167
+ merged_modified_attack_vector = @base.attack_vector
168
+ end
169
+
170
+ merged_modified_attack_complexity = @modified_attack_complexity
171
+ if @modified_attack_complexity.selected_choice[:name] == 'Not Defined'
172
+ merged_modified_attack_complexity = @base.attack_complexity
173
+ end
174
+
175
+ merged_modified_user_interaction = @modified_user_interaction
176
+ if @modified_user_interaction.selected_choice[:name] == 'Not Defined'
177
+ merged_modified_user_interaction = @base.user_interaction
178
+ end
179
+
180
+ 8.22 * merged_modified_attack_vector.score * merged_modified_attack_complexity.score *
181
+ privilege_score * merged_modified_user_interaction.score
131
182
  end
132
183
 
133
184
  def calculate_score(modified_impact_sub_score, modified_exploitability_sub_score, temporal_score)
134
- factor = @modified_scope.selected_choice[:name] == 'Changed' ? 1.08 : 1.0
185
+ if @modified_scope.selected_choice[:name] == 'Not Defined'
186
+ factor = @base.scope.selected_choice[:name] == 'Changed' ? 1.08 : 1.0
187
+ else
188
+ factor = @modified_scope.selected_choice[:name] == 'Changed' ? 1.08 : 1.0
189
+ end
135
190
 
136
191
  Cvss3Helper.round_up(
137
192
  [factor * (modified_impact_sub_score + modified_exploitability_sub_score), 10].min
@@ -47,7 +47,7 @@ module CvssSuite
47
47
  def environmental_score
48
48
  return temporal_score unless @environmental.valid?
49
49
 
50
- Cvss31Helper.round_up(@environmental.score(@temporal.score))
50
+ Cvss31Helper.round_up(@environmental.score(@base, @temporal))
51
51
  end
52
52
 
53
53
  private
@@ -28,9 +28,20 @@ module CvssSuite
28
28
 
29
29
  ##
30
30
  # Returns score of this metric
31
+ def score(base, temporal)
32
+ @base = base
31
33
 
32
- def score(temporal_score)
33
- privilege_score = Cvss3Helper.privileges_required_score(@modified_privileges_required, @modified_scope)
34
+ merged_modified_privileges_required = @modified_privileges_required
35
+ if @modified_privileges_required.selected_choice[:name] == 'Not Defined'
36
+ merged_modified_privileges_required = @base.privileges_required
37
+ end
38
+
39
+ merged_modified_scope = @modified_scope
40
+ if @modified_scope.selected_choice[:name] == 'Not Defined'
41
+ merged_modified_scope = @base.scope
42
+ end
43
+
44
+ privilege_score = Cvss3Helper.privileges_required_score(merged_modified_privileges_required, merged_modified_scope)
34
45
 
35
46
  modified_exploitability_sub_score = modified_exploitability_sub(privilege_score)
36
47
 
@@ -38,7 +49,7 @@ module CvssSuite
38
49
 
39
50
  return 0 if modified_impact_sub_score <= 0
40
51
 
41
- calculate_score modified_impact_sub_score, modified_exploitability_sub_score, temporal_score
52
+ calculate_score modified_impact_sub_score, modified_exploitability_sub_score, temporal.score
42
53
  end
43
54
 
44
55
  private
@@ -89,7 +100,8 @@ module CvssSuite
89
100
  @properties.push(@modified_scope =
90
101
  CvssProperty.new(name: 'Modified Scope', abbreviation: 'MS', position: [15, 18],
91
102
  choices: [{ name: 'Changed', abbreviation: 'C' },
92
- { name: 'Unchanged', abbreviation: 'U' }]))
103
+ { name: 'Unchanged', abbreviation: 'U' },
104
+ { name: 'Not Defined', abbreviation: 'X' }]))
93
105
  @properties.push(@modified_confidentiality =
94
106
  CvssProperty.new(name: 'Modified Confidentiality', abbreviation: 'MC', position: [16, 19],
95
107
  choices: [{ name: 'None', abbreviation: 'N', weight: 0 },
@@ -111,6 +123,14 @@ module CvssSuite
111
123
  end
112
124
 
113
125
  def modified_impact_sub(isc_modified)
126
+ if @modified_scope.selected_choice[:name] == 'Not Defined'
127
+ if @base.scope.selected_choice[:name] == 'Changed'
128
+ return 7.52 * (isc_modified - 0.029) - 3.25 * (isc_modified * 0.9731 - 0.02)**13
129
+ else
130
+ return 6.42 * isc_modified
131
+ end
132
+ end
133
+
114
134
  if @modified_scope.selected_choice[:name] == 'Changed'
115
135
  7.52 * (isc_modified - 0.029) - 3.25 * (isc_modified * 0.9731 - 0.02)**13
116
136
  else
@@ -119,20 +139,54 @@ module CvssSuite
119
139
  end
120
140
 
121
141
  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
142
+ merged_modified_confidentiality = @modified_confidentiality
143
+ if @modified_confidentiality.selected_choice[:name] == 'Not Defined'
144
+ merged_modified_confidentiality = @base.confidentiality
145
+ end
146
+
147
+ merged_modified_integrity = @modified_integrity
148
+ if @modified_integrity.selected_choice[:name] == 'Not Defined'
149
+ merged_modified_integrity = @base.integrity
150
+ end
151
+
152
+ merged_modified_availability = @modified_availability
153
+ if @modified_availability.selected_choice[:name] == 'Not Defined'
154
+ merged_modified_availability = @base.availability
155
+ end
156
+
157
+ confidentiality_score = 1 - merged_modified_confidentiality.score * @confidentiality_requirement.score
158
+ integrity_score = 1 - merged_modified_integrity.score * @integrity_requirement.score
159
+ availability_score = 1 - merged_modified_availability.score * @availability_requirement.score
125
160
 
126
161
  [0.915, (1 - confidentiality_score * integrity_score * availability_score)].min
127
162
  end
128
163
 
129
164
  def modified_exploitability_sub(privilege_score)
130
- 8.22 * @modified_attack_vector.score * @modified_attack_complexity.score *
131
- privilege_score * @modified_user_interaction.score
165
+ merged_modified_attack_vector = @modified_attack_vector
166
+ if @modified_attack_vector.selected_choice[:name] == 'Not Defined'
167
+ merged_modified_attack_vector = @base.attack_vector
168
+ end
169
+
170
+ merged_modified_attack_complexity = @modified_attack_complexity
171
+ if @modified_attack_complexity.selected_choice[:name] == 'Not Defined'
172
+ merged_modified_attack_complexity = @base.attack_complexity
173
+ end
174
+
175
+ merged_modified_user_interaction = @modified_user_interaction
176
+ if @modified_user_interaction.selected_choice[:name] == 'Not Defined'
177
+ merged_modified_user_interaction = @base.user_interaction
178
+ end
179
+
180
+ 8.22 * merged_modified_attack_vector.score * merged_modified_attack_complexity.score *
181
+ privilege_score * merged_modified_user_interaction.score
132
182
  end
133
183
 
134
184
  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
185
+ if @modified_scope.selected_choice[:name] == 'Not Defined'
186
+ factor = @base.scope.selected_choice[:name] == 'Changed' ? 1.08 : 1.0
187
+ else
188
+ factor = @modified_scope.selected_choice[:name] == 'Changed' ? 1.08 : 1.0
189
+ end
136
190
 
137
191
  Cvss31Helper.round_up(
138
192
  [factor * (modified_impact_sub_score + modified_exploitability_sub_score), 10].min
@@ -9,5 +9,5 @@
9
9
  # See the LICENSE.md file in the top-level directory.
10
10
 
11
11
  module CvssSuite
12
- VERSION = '1.2.1'
12
+ VERSION = '1.2.2'
13
13
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cvss-suite
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oliver Hamboerger
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-05-10 00:00:00.000000000 Z
11
+ date: 2020-07-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler