cvss-suite 3.0.1 → 3.1.1

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: 4b5de123089a1d8250c5fdccbf1d859a0da8be387ed88875fb88a5613a786cbb
4
- data.tar.gz: cd9150e3086e5f3304f9b4c3de53f587d25b41033218c398aa1e925385e22cee
3
+ metadata.gz: 9474da7f6ca4ff4f9016d55b23714c1a5ca7e1a6a1fce6e4fb74fddbda9ea757
4
+ data.tar.gz: a581c242701b79f72ef2b97208ab9a0524942dcba8ddca75a0df7b5ef0b36c71
5
5
  SHA512:
6
- metadata.gz: 32ef998978e20dfb978dacccfda21b587f31a63ea5426e3e0fc9a1b1c448696d27c641375cb8d35c917c19779098ce2aceca88aaa035efcda6da8d5a5c8c8860
7
- data.tar.gz: 5347e86397270b74cb5b78b5a1fc5eb7e9d9a6de13d56de62a4170c84c459406fd2cfe614434af7a83fdc434ed64ffe17de4738bb418fd4b771c01807140e1fc
6
+ metadata.gz: 2e3d15e35b59915b919faa4b99d3ff8a43d9b9ab231a9993e6b1876cd8b0c55ead7c73d0078a011245ebf40e6fa88f0abc9936eeb7af48c4972df8252d97e037
7
+ data.tar.gz: e061ce21c13ad6759b3b54f01d3330b339322213cf103fbe1350185da8dbf621d6a22ba211fd882fc174daec62ea42695a79ae37511adbe863b6b48fc75b4af2
@@ -8,9 +8,9 @@ jobs:
8
8
  runs-on: ubuntu-latest
9
9
  strategy:
10
10
  matrix:
11
- ruby: [ '2.6', '2.7', '3.0', '3.1' ]
11
+ ruby: [ '2.6', '2.7', '3.0', '3.1', '3.2' ]
12
12
  steps:
13
- - uses: actions/checkout@v2
13
+ - uses: actions/checkout@v3
14
14
  - name: Set up ${{ matrix.ruby }}
15
15
  uses: ruby/setup-ruby@v1
16
16
  with:
data/CHANGES.md CHANGED
@@ -2,6 +2,19 @@
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
+ ## [3.1.1] - 2023-10-15
6
+
7
+ ### Fixes
8
+ * CVSS prefix is missing in v3.1.0. Fixes [#33](https://github.com/0llirocks/cvss-suite/issues/33)
9
+
10
+ ## [3.1.0] - 2022-09-27
11
+
12
+ ### Fixes
13
+ * Metrics are no longer order-dependent. Fixes [#30](https://github.com/0llirocks/cvss-suite/issues/30)
14
+
15
+ ### Improvements
16
+ * Temporal and Environmental metrics can now be partly omitted instead of setting them to X.
17
+
5
18
  ## [3.0.1] - 2022-03-13
6
19
 
7
20
  ### Notes
data/README.md CHANGED
@@ -18,6 +18,12 @@ Add this line to your application's Gemfile:
18
18
  gem 'cvss-suite'
19
19
  ```
20
20
 
21
+ Since the naming of this gem is not following the naming convention you can also add the following line to automatically require the gem:
22
+
23
+ ```ruby
24
+ gem 'cvss-suite', require: 'cvss_suite'
25
+ ```
26
+
21
27
  And then execute:
22
28
 
23
29
  $ bundle
@@ -100,14 +106,8 @@ valid = cvss.valid? # false
100
106
  cvss.base_score # will throw CvssSuite::Errors::InvalidVector: Vector is not valid!
101
107
  ```
102
108
 
103
- ## Notable Features
104
-
105
- Properties (Access Vector, Remediation Level, etc) do have a position attribute, with this they can be ordered the same way they appear in the vector.
106
-
107
109
  ## Known Issues
108
110
 
109
- 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.
110
-
111
111
  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.
112
112
 
113
113
  ## Changelog
data/cvss_suite.gemspec CHANGED
@@ -26,11 +26,11 @@ Gem::Specification.new do |spec|
26
26
  Besides calculating the Base, Temporal and Environmental Score, you are able to extract the selected option.'
27
27
 
28
28
  spec.metadata = {
29
- 'bug_tracker_uri' => 'https://github.com/0llirocks/cvss-suite/issues',
30
- 'changelog_uri' => 'https://github.com/0llirocks/cvss-suite/blob/master/CHANGES.md',
31
- 'documentation_uri' => 'https://www.rubydoc.info/gems/cvss-suite/' + CvssSuite::VERSION,
32
- 'homepage_uri' => 'https://cvss-suite.0lli.rocks',
33
- 'source_code_uri' => 'https://github.com/0llirocks/cvss-suite'
29
+ 'bug_tracker_uri' => 'https://github.com/0llirocks/cvss-suite/issues',
30
+ 'changelog_uri' => 'https://github.com/0llirocks/cvss-suite/blob/master/CHANGES.md',
31
+ 'documentation_uri' => "https://www.rubydoc.info/gems/cvss-suite/#{CvssSuite::VERSION}",
32
+ 'homepage_uri' => 'https://cvss-suite.0lli.rocks',
33
+ 'source_code_uri' => 'https://github.com/0llirocks/cvss-suite'
34
34
  }
35
35
 
36
36
  spec.required_ruby_version = '>= 2.6.0'
@@ -1,7 +1,7 @@
1
1
  # CVSS-Suite, a Ruby gem to manage the CVSS vector
2
2
  #
3
3
  # Copyright (c) 2016-2022 Siemens AG
4
- # Copyright (c) 2022 0llirocks
4
+ # Copyright (c) 2022-2023 0llirocks
5
5
  #
6
6
  # Authors:
7
7
  # 0llirocks <http://0lli.rocks>
@@ -17,10 +17,6 @@ module CvssSuite
17
17
  # Metric of a CVSS vector.
18
18
  attr_reader :base, :temporal, :environmental
19
19
 
20
- ##
21
- # Returns the vector itself.
22
- attr_reader :vector
23
-
24
20
  ##
25
21
  # Creates a new CVSS vector by a +vector+.
26
22
  #
@@ -37,7 +33,7 @@ module CvssSuite
37
33
  ##
38
34
  # Returns if CVSS vector is valid.
39
35
  def valid?
40
- if @amount_of_properties == required_amount_of_properties
36
+ if @amount_of_properties >= required_amount_of_properties
41
37
  base = @base.valid?
42
38
  temporal = @base.valid? && @temporal.valid?
43
39
  environmental = @base.valid? && @environmental.valid?
@@ -80,44 +76,30 @@ module CvssSuite
80
76
  base_score
81
77
  end
82
78
 
79
+ ##
80
+ # Returns the vector itself.
81
+ def vector
82
+ @vector.to_s
83
+ end
84
+
83
85
  private
84
86
 
85
87
  def extract_metrics
86
- properties = prepared_vector.split('/')
88
+ properties = @vector.split('/')
87
89
  @amount_of_properties = properties.size
88
90
  properties.each_with_index do |property, index|
89
91
  property = property.split(':')
90
92
  @properties.push({ name: property[0], selected: property[1], position: index })
91
93
  end
94
+ @properties = [] if @properties.group_by { |p| p[:name] }.select { |_k, v| v.size > 1 }.length.positive?
92
95
  end
93
96
 
94
97
  def check_validity
95
98
  raise CvssSuite::Errors::InvalidVector, 'Vector is not valid!' unless valid?
96
99
  end
97
100
 
98
- def prepared_vector
99
- start_of_vector = @vector.index('AV')
100
-
101
- if start_of_vector.nil?
102
- ''
103
- elsif start_of_vector == 1
104
- match_array = @vector.scan(/\((?>[^)(]+|\g<0>)*\)/)
105
- if match_array.length == 1 && match_array[0] == @vector
106
- @vector.slice!(0)
107
- @vector.slice!(@vector.length - 1)
108
- @vector
109
- else
110
- ''
111
- end
112
- else
113
- @vector[start_of_vector..]
114
- end
115
- end
116
-
117
101
  def required_amount_of_properties
118
- total = @base.count if @base.valid?
119
- total += @temporal.count if @temporal.valid?
120
- total += @environmental.count if @environmental.valid?
102
+ total = @base.count
121
103
  total || 0
122
104
  end
123
105
  end
@@ -1,7 +1,7 @@
1
1
  # CVSS-Suite, a Ruby gem to manage the CVSS vector
2
2
  #
3
3
  # Copyright (c) 2016-2022 Siemens AG
4
- # Copyright (c) 2022 0llirocks
4
+ # Copyright (c) 2022-2023 0llirocks
5
5
  #
6
6
  # Authors:
7
7
  # 0llirocks <http://0lli.rocks>
@@ -45,6 +45,12 @@ module CvssSuite
45
45
  Cvss3Helper.round_up(@environmental.score(@base, @temporal))
46
46
  end
47
47
 
48
+ ##
49
+ # Returns the vector itself.
50
+ def vector
51
+ "#{CvssSuite::CVSS_VECTOR_BEGINNINGS.find { |beginning| beginning[:version] == version }[:string]}#{@vector}"
52
+ end
53
+
48
54
  private
49
55
 
50
56
  def init_metrics
@@ -51,40 +51,40 @@ module CvssSuite
51
51
 
52
52
  def init_properties
53
53
  @properties.push(@attack_vector =
54
- CvssProperty.new(name: 'Attack Vector', abbreviation: 'AV', position: [0],
54
+ CvssProperty.new(name: 'Attack Vector', abbreviation: 'AV',
55
55
  values: [{ name: 'Network', abbreviation: 'N', weight: 0.85 },
56
56
  { name: 'Adjacent', abbreviation: 'A', weight: 0.62 },
57
57
  { name: 'Local', abbreviation: 'L', weight: 0.55 },
58
58
  { name: 'Physical', abbreviation: 'P', weight: 0.2 }]))
59
59
  @properties.push(@attack_complexity =
60
- CvssProperty.new(name: 'Attack Complexity', abbreviation: 'AC', position: [1],
60
+ CvssProperty.new(name: 'Attack Complexity', abbreviation: 'AC',
61
61
  values: [{ name: 'Low', abbreviation: 'L', weight: 0.77 },
62
62
  { name: 'High', abbreviation: 'H', weight: 0.44 }]))
63
63
  @properties.push(@privileges_required =
64
- CvssProperty.new(name: 'Privileges Required', abbreviation: 'PR', position: [2],
64
+ CvssProperty.new(name: 'Privileges Required', abbreviation: 'PR',
65
65
  values: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
66
66
  { name: 'Low', abbreviation: 'L', weight: 0.62 },
67
67
  { name: 'High', abbreviation: 'H', weight: 0.27 }]))
68
68
  @properties.push(@user_interaction =
69
- CvssProperty.new(name: 'User Interaction', abbreviation: 'UI', position: [3],
69
+ CvssProperty.new(name: 'User Interaction', abbreviation: 'UI',
70
70
  values: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
71
71
  { name: 'Required', abbreviation: 'R', weight: 0.62 }]))
72
72
  @properties.push(@scope =
73
- CvssProperty.new(name: 'Scope', abbreviation: 'S', position: [4],
73
+ CvssProperty.new(name: 'Scope', abbreviation: 'S',
74
74
  values: [{ name: 'Unchanged', abbreviation: 'U' },
75
75
  { name: 'Changed', abbreviation: 'C' }]))
76
76
  @properties.push(@confidentiality =
77
- CvssProperty.new(name: 'Confidentiality', abbreviation: 'C', position: [5],
77
+ CvssProperty.new(name: 'Confidentiality', abbreviation: 'C',
78
78
  values: [{ name: 'None', abbreviation: 'N', weight: 0.0 },
79
79
  { name: 'Low', abbreviation: 'L', weight: 0.22 },
80
80
  { name: 'High', abbreviation: 'H', weight: 0.56 }]))
81
81
  @properties.push(@integrity =
82
- CvssProperty.new(name: 'Integrity', abbreviation: 'I', position: [6],
82
+ CvssProperty.new(name: 'Integrity', abbreviation: 'I',
83
83
  values: [{ name: 'None', abbreviation: 'N', weight: 0.0 },
84
84
  { name: 'Low', abbreviation: 'L', weight: 0.22 },
85
85
  { name: 'High', abbreviation: 'H', weight: 0.56 }]))
86
86
  @properties.push(@availability =
87
- CvssProperty.new(name: 'Availability', abbreviation: 'A', position: [7],
87
+ CvssProperty.new(name: 'Availability', abbreviation: 'A',
88
88
  values: [{ name: 'None', abbreviation: 'N', weight: 0.0 },
89
89
  { name: 'Low', abbreviation: 'L', weight: 0.22 },
90
90
  { name: 'High', abbreviation: 'H', weight: 0.56 }]))
@@ -55,66 +55,66 @@ module CvssSuite
55
55
 
56
56
  def init_properties
57
57
  @properties.push(@confidentiality_requirement =
58
- CvssProperty.new(name: 'Confidentiality Requirement', abbreviation: 'CR', position: [8, 11],
58
+ CvssProperty.new(name: 'Confidentiality Requirement', abbreviation: 'CR',
59
59
  values: [{ name: 'Low', abbreviation: 'L', weight: 0.5 },
60
60
  { name: 'Medium', abbreviation: 'M', weight: 1.0 },
61
61
  { name: 'High', abbreviation: 'H', weight: 1.5 },
62
62
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
63
63
  @properties.push(@integrity_requirement =
64
- CvssProperty.new(name: 'Integrity Requirement', abbreviation: 'IR', position: [9, 12],
64
+ CvssProperty.new(name: 'Integrity Requirement', abbreviation: 'IR',
65
65
  values: [{ name: 'Low', abbreviation: 'L', weight: 0.5 },
66
66
  { name: 'Medium', abbreviation: 'M', weight: 1.0 },
67
67
  { name: 'High', abbreviation: 'H', weight: 1.5 },
68
68
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
69
69
 
70
70
  @properties.push(@availability_requirement =
71
- CvssProperty.new(name: 'Availability Requirement', abbreviation: 'AR', position: [10, 13],
71
+ CvssProperty.new(name: 'Availability Requirement', abbreviation: 'AR',
72
72
  values: [{ name: 'Low', abbreviation: 'L', weight: 0.5 },
73
73
  { name: 'Medium', abbreviation: 'M', weight: 1.0 },
74
74
  { name: 'High', abbreviation: 'H', weight: 1.5 },
75
75
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
76
76
  @properties.push(@modified_attack_vector =
77
- CvssProperty.new(name: 'Modified Attack Vector', abbreviation: 'MAV', position: [11, 14],
77
+ CvssProperty.new(name: 'Modified Attack Vector', abbreviation: 'MAV',
78
78
  values: [{ name: 'Network', abbreviation: 'N', weight: 0.85 },
79
79
  { name: 'Adjacent Network', abbreviation: 'A', weight: 0.62 },
80
80
  { name: 'Local', abbreviation: 'L', weight: 0.55 },
81
81
  { name: 'Physical', abbreviation: 'P', weight: 0.2 },
82
82
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
83
83
  @properties.push(@modified_attack_complexity =
84
- CvssProperty.new(name: 'Modified Attack Complexity', abbreviation: 'MAC', position: [12, 15],
84
+ CvssProperty.new(name: 'Modified Attack Complexity', abbreviation: 'MAC',
85
85
  values: [{ name: 'Low', abbreviation: 'L', weight: 0.77 },
86
86
  { name: 'High', abbreviation: 'H', weight: 0.44 },
87
87
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
88
88
  @properties.push(@modified_privileges_required =
89
- CvssProperty.new(name: 'Modified Privileges Required', abbreviation: 'MPR', position: [13, 16],
89
+ CvssProperty.new(name: 'Modified Privileges Required', abbreviation: 'MPR',
90
90
  values: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
91
91
  { name: 'Low', abbreviation: 'L', weight: 0.62 },
92
92
  { name: 'High', abbreviation: 'H', weight: 0.27 },
93
93
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
94
94
  @properties.push(@modified_user_interaction =
95
- CvssProperty.new(name: 'Modified User Interaction', abbreviation: 'MUI', position: [14, 17],
95
+ CvssProperty.new(name: 'Modified User Interaction', abbreviation: 'MUI',
96
96
  values: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
97
97
  { name: 'Required', abbreviation: 'R', weight: 0.62 },
98
98
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
99
99
  @properties.push(@modified_scope =
100
- CvssProperty.new(name: 'Modified Scope', abbreviation: 'MS', position: [15, 18],
100
+ CvssProperty.new(name: 'Modified Scope', abbreviation: 'MS',
101
101
  values: [{ name: 'Changed', abbreviation: 'C' },
102
102
  { name: 'Unchanged', abbreviation: 'U' },
103
103
  { name: 'Not Defined', abbreviation: 'X' }]))
104
104
  @properties.push(@modified_confidentiality =
105
- CvssProperty.new(name: 'Modified Confidentiality', abbreviation: 'MC', position: [16, 19],
105
+ CvssProperty.new(name: 'Modified Confidentiality', abbreviation: 'MC',
106
106
  values: [{ name: 'None', abbreviation: 'N', weight: 0 },
107
107
  { name: 'Low', abbreviation: 'L', weight: 0.22 },
108
108
  { name: 'High', abbreviation: 'H', weight: 0.56 },
109
109
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
110
110
  @properties.push(@modified_integrity =
111
- CvssProperty.new(name: 'Modified Integrity', abbreviation: 'MI', position: [17, 20],
111
+ CvssProperty.new(name: 'Modified Integrity', abbreviation: 'MI',
112
112
  values: [{ name: 'None', abbreviation: 'N', weight: 0 },
113
113
  { name: 'Low', abbreviation: 'L', weight: 0.22 },
114
114
  { name: 'High', abbreviation: 'H', weight: 0.56 },
115
115
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
116
116
  @properties.push(@modified_availability =
117
- CvssProperty.new(name: 'Modified Availability', abbreviation: 'MA', position: [18, 21],
117
+ CvssProperty.new(name: 'Modified Availability', abbreviation: 'MA',
118
118
  values: [{ name: 'None', abbreviation: 'N', weight: 0 },
119
119
  { name: 'Low', abbreviation: 'L', weight: 0.22 },
120
120
  { name: 'High', abbreviation: 'H', weight: 0.56 },
@@ -32,14 +32,14 @@ module CvssSuite
32
32
 
33
33
  def init_properties
34
34
  @properties.push(@exploit_code_maturity =
35
- CvssProperty.new(name: 'Exploit Code Maturity', abbreviation: 'E', position: [8],
35
+ CvssProperty.new(name: 'Exploit Code Maturity', abbreviation: 'E',
36
36
  values: [{ name: 'Not Defined', abbreviation: 'X', weight: 1.0 },
37
37
  { name: 'Unproven', abbreviation: 'U', weight: 0.91 },
38
38
  { name: 'Proof-of-Concept', abbreviation: 'P', weight: 0.94 },
39
39
  { name: 'Functional', abbreviation: 'F', weight: 0.97 },
40
40
  { name: 'High', abbreviation: 'H', weight: 1.0 }]))
41
41
  @properties.push(@remediation_level =
42
- CvssProperty.new(name: 'Remediation Level', abbreviation: 'RL', position: [9],
42
+ CvssProperty.new(name: 'Remediation Level', abbreviation: 'RL',
43
43
  values: [{ name: 'Not Defined', abbreviation: 'X', weight: 1.0 },
44
44
  { name: 'Official Fix', abbreviation: 'O', weight: 0.95 },
45
45
  { name: 'Temporary Fix', abbreviation: 'T', weight: 0.96 },
@@ -47,7 +47,7 @@ module CvssSuite
47
47
  { name: 'Unavailable', abbreviation: 'U', weight: 1.0 }]))
48
48
 
49
49
  @properties.push(@report_confidence =
50
- CvssProperty.new(name: 'Report Confidence', abbreviation: 'RC', position: [10],
50
+ CvssProperty.new(name: 'Report Confidence', abbreviation: 'RC',
51
51
  values: [{ name: 'Not Defined', abbreviation: 'X', weight: 1.0 },
52
52
  { name: 'Unknown', abbreviation: 'U', weight: 0.92 },
53
53
  { name: 'Reasonable', abbreviation: 'R', weight: 0.96 },
@@ -1,7 +1,7 @@
1
1
  # CVSS-Suite, a Ruby gem to manage the CVSS vector
2
2
  #
3
3
  # Copyright (c) 2019-2022 Siemens AG
4
- # Copyright (c) 2022 0llirocks
4
+ # Copyright (c) 2022-2023 0llirocks
5
5
  #
6
6
  # Authors:
7
7
  # 0llirocks <http://0lli.rocks>
@@ -50,6 +50,12 @@ module CvssSuite
50
50
  Cvss31Helper.round_up(@environmental.score(@base, @temporal))
51
51
  end
52
52
 
53
+ ##
54
+ # Returns the vector itself.
55
+ def vector
56
+ "#{CvssSuite::CVSS_VECTOR_BEGINNINGS.find { |beginning| beginning[:version] == version }[:string]}#{@vector}"
57
+ end
58
+
53
59
  private
54
60
 
55
61
  def init_metrics
@@ -52,40 +52,40 @@ module CvssSuite
52
52
 
53
53
  def init_properties
54
54
  @properties.push(@attack_vector =
55
- CvssProperty.new(name: 'Attack Vector', abbreviation: 'AV', position: [0],
55
+ CvssProperty.new(name: 'Attack Vector', abbreviation: 'AV',
56
56
  values: [{ name: 'Network', abbreviation: 'N', weight: 0.85 },
57
57
  { name: 'Adjacent', abbreviation: 'A', weight: 0.62 },
58
58
  { name: 'Local', abbreviation: 'L', weight: 0.55 },
59
59
  { name: 'Physical', abbreviation: 'P', weight: 0.2 }]))
60
60
  @properties.push(@attack_complexity =
61
- CvssProperty.new(name: 'Attack Complexity', abbreviation: 'AC', position: [1],
61
+ CvssProperty.new(name: 'Attack Complexity', abbreviation: 'AC',
62
62
  values: [{ name: 'Low', abbreviation: 'L', weight: 0.77 },
63
63
  { name: 'High', abbreviation: 'H', weight: 0.44 }]))
64
64
  @properties.push(@privileges_required =
65
- CvssProperty.new(name: 'Privileges Required', abbreviation: 'PR', position: [2],
65
+ CvssProperty.new(name: 'Privileges Required', abbreviation: 'PR',
66
66
  values: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
67
67
  { name: 'Low', abbreviation: 'L', weight: 0.62 },
68
68
  { name: 'High', abbreviation: 'H', weight: 0.27 }]))
69
69
  @properties.push(@user_interaction =
70
- CvssProperty.new(name: 'User Interaction', abbreviation: 'UI', position: [3],
70
+ CvssProperty.new(name: 'User Interaction', abbreviation: 'UI',
71
71
  values: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
72
72
  { name: 'Required', abbreviation: 'R', weight: 0.62 }]))
73
73
  @properties.push(@scope =
74
- CvssProperty.new(name: 'Scope', abbreviation: 'S', position: [4],
74
+ CvssProperty.new(name: 'Scope', abbreviation: 'S',
75
75
  values: [{ name: 'Unchanged', abbreviation: 'U' },
76
76
  { name: 'Changed', abbreviation: 'C' }]))
77
77
  @properties.push(@confidentiality =
78
- CvssProperty.new(name: 'Confidentiality', abbreviation: 'C', position: [5],
78
+ CvssProperty.new(name: 'Confidentiality', abbreviation: 'C',
79
79
  values: [{ name: 'None', abbreviation: 'N', weight: 0.0 },
80
80
  { name: 'Low', abbreviation: 'L', weight: 0.22 },
81
81
  { name: 'High', abbreviation: 'H', weight: 0.56 }]))
82
82
  @properties.push(@integrity =
83
- CvssProperty.new(name: 'Integrity', abbreviation: 'I', position: [6],
83
+ CvssProperty.new(name: 'Integrity', abbreviation: 'I',
84
84
  values: [{ name: 'None', abbreviation: 'N', weight: 0.0 },
85
85
  { name: 'Low', abbreviation: 'L', weight: 0.22 },
86
86
  { name: 'High', abbreviation: 'H', weight: 0.56 }]))
87
87
  @properties.push(@availability =
88
- CvssProperty.new(name: 'Availability', abbreviation: 'A', position: [7],
88
+ CvssProperty.new(name: 'Availability', abbreviation: 'A',
89
89
  values: [{ name: 'None', abbreviation: 'N', weight: 0.0 },
90
90
  { name: 'Low', abbreviation: 'L', weight: 0.22 },
91
91
  { name: 'High', abbreviation: 'H', weight: 0.56 }]))
@@ -55,66 +55,66 @@ module CvssSuite
55
55
 
56
56
  def init_properties
57
57
  @properties.push(@confidentiality_requirement =
58
- CvssProperty.new(name: 'Confidentiality Requirement', abbreviation: 'CR', position: [8, 11],
58
+ CvssProperty.new(name: 'Confidentiality Requirement', abbreviation: 'CR',
59
59
  values: [{ name: 'Low', abbreviation: 'L', weight: 0.5 },
60
60
  { name: 'Medium', abbreviation: 'M', weight: 1.0 },
61
61
  { name: 'High', abbreviation: 'H', weight: 1.5 },
62
62
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
63
63
  @properties.push(@integrity_requirement =
64
- CvssProperty.new(name: 'Integrity Requirement', abbreviation: 'IR', position: [9, 12],
64
+ CvssProperty.new(name: 'Integrity Requirement', abbreviation: 'IR',
65
65
  values: [{ name: 'Low', abbreviation: 'L', weight: 0.5 },
66
66
  { name: 'Medium', abbreviation: 'M', weight: 1.0 },
67
67
  { name: 'High', abbreviation: 'H', weight: 1.5 },
68
68
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
69
69
 
70
70
  @properties.push(@availability_requirement =
71
- CvssProperty.new(name: 'Availability Requirement', abbreviation: 'AR', position: [10, 13],
71
+ CvssProperty.new(name: 'Availability Requirement', abbreviation: 'AR',
72
72
  values: [{ name: 'Low', abbreviation: 'L', weight: 0.5 },
73
73
  { name: 'Medium', abbreviation: 'M', weight: 1.0 },
74
74
  { name: 'High', abbreviation: 'H', weight: 1.5 },
75
75
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
76
76
  @properties.push(@modified_attack_vector =
77
- CvssProperty.new(name: 'Modified Attack Vector', abbreviation: 'MAV', position: [11, 14],
77
+ CvssProperty.new(name: 'Modified Attack Vector', abbreviation: 'MAV',
78
78
  values: [{ name: 'Network', abbreviation: 'N', weight: 0.85 },
79
79
  { name: 'Adjacent Network', abbreviation: 'A', weight: 0.62 },
80
80
  { name: 'Local', abbreviation: 'L', weight: 0.55 },
81
81
  { name: 'Physical', abbreviation: 'P', weight: 0.2 },
82
82
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
83
83
  @properties.push(@modified_attack_complexity =
84
- CvssProperty.new(name: 'Modified Attack Complexity', abbreviation: 'MAC', position: [12, 15],
84
+ CvssProperty.new(name: 'Modified Attack Complexity', abbreviation: 'MAC',
85
85
  values: [{ name: 'Low', abbreviation: 'L', weight: 0.77 },
86
86
  { name: 'High', abbreviation: 'H', weight: 0.44 },
87
87
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
88
88
  @properties.push(@modified_privileges_required =
89
- CvssProperty.new(name: 'Modified Privileges Required', abbreviation: 'MPR', position: [13, 16],
89
+ CvssProperty.new(name: 'Modified Privileges Required', abbreviation: 'MPR',
90
90
  values: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
91
91
  { name: 'Low', abbreviation: 'L', weight: 0.62 },
92
92
  { name: 'High', abbreviation: 'H', weight: 0.27 },
93
93
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
94
94
  @properties.push(@modified_user_interaction =
95
- CvssProperty.new(name: 'Modified User Interaction', abbreviation: 'MUI', position: [14, 17],
95
+ CvssProperty.new(name: 'Modified User Interaction', abbreviation: 'MUI',
96
96
  values: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
97
97
  { name: 'Required', abbreviation: 'R', weight: 0.62 },
98
98
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
99
99
  @properties.push(@modified_scope =
100
- CvssProperty.new(name: 'Modified Scope', abbreviation: 'MS', position: [15, 18],
100
+ CvssProperty.new(name: 'Modified Scope', abbreviation: 'MS',
101
101
  values: [{ name: 'Changed', abbreviation: 'C' },
102
102
  { name: 'Unchanged', abbreviation: 'U' },
103
103
  { name: 'Not Defined', abbreviation: 'X' }]))
104
104
  @properties.push(@modified_confidentiality =
105
- CvssProperty.new(name: 'Modified Confidentiality', abbreviation: 'MC', position: [16, 19],
105
+ CvssProperty.new(name: 'Modified Confidentiality', abbreviation: 'MC',
106
106
  values: [{ name: 'None', abbreviation: 'N', weight: 0 },
107
107
  { name: 'Low', abbreviation: 'L', weight: 0.22 },
108
108
  { name: 'High', abbreviation: 'H', weight: 0.56 },
109
109
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
110
110
  @properties.push(@modified_integrity =
111
- CvssProperty.new(name: 'Modified Integrity', abbreviation: 'MI', position: [17, 20],
111
+ CvssProperty.new(name: 'Modified Integrity', abbreviation: 'MI',
112
112
  values: [{ name: 'None', abbreviation: 'N', weight: 0 },
113
113
  { name: 'Low', abbreviation: 'L', weight: 0.22 },
114
114
  { name: 'High', abbreviation: 'H', weight: 0.56 },
115
115
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
116
116
  @properties.push(@modified_availability =
117
- CvssProperty.new(name: 'Modified Availability', abbreviation: 'MA', position: [18, 21],
117
+ CvssProperty.new(name: 'Modified Availability', abbreviation: 'MA',
118
118
  values: [{ name: 'None', abbreviation: 'N', weight: 0 },
119
119
  { name: 'Low', abbreviation: 'L', weight: 0.22 },
120
120
  { name: 'High', abbreviation: 'H', weight: 0.56 },
@@ -32,14 +32,14 @@ module CvssSuite
32
32
 
33
33
  def init_properties
34
34
  @properties.push(@exploit_code_maturity =
35
- CvssProperty.new(name: 'Exploit Code Maturity', abbreviation: 'E', position: [8],
35
+ CvssProperty.new(name: 'Exploit Code Maturity', abbreviation: 'E',
36
36
  values: [{ name: 'Not Defined', abbreviation: 'X', weight: 1.0 },
37
37
  { name: 'Unproven', abbreviation: 'U', weight: 0.91 },
38
38
  { name: 'Proof-of-Concept', abbreviation: 'P', weight: 0.94 },
39
39
  { name: 'Functional', abbreviation: 'F', weight: 0.97 },
40
40
  { name: 'High', abbreviation: 'H', weight: 1.0 }]))
41
41
  @properties.push(@remediation_level =
42
- CvssProperty.new(name: 'Remediation Level', abbreviation: 'RL', position: [9],
42
+ CvssProperty.new(name: 'Remediation Level', abbreviation: 'RL',
43
43
  values: [{ name: 'Not Defined', abbreviation: 'X', weight: 1.0 },
44
44
  { name: 'Official Fix', abbreviation: 'O', weight: 0.95 },
45
45
  { name: 'Temporary Fix', abbreviation: 'T', weight: 0.96 },
@@ -47,7 +47,7 @@ module CvssSuite
47
47
  { name: 'Unavailable', abbreviation: 'U', weight: 1.0 }]))
48
48
 
49
49
  @properties.push(@report_confidence =
50
- CvssProperty.new(name: 'Report Confidence', abbreviation: 'RC', position: [10],
50
+ CvssProperty.new(name: 'Report Confidence', abbreviation: 'RC',
51
51
  values: [{ name: 'Not Defined', abbreviation: 'X', weight: 1.0 },
52
52
  { name: 'Unknown', abbreviation: 'U', weight: 0.92 },
53
53
  { name: 'Reasonable', abbreviation: 'R', weight: 0.96 },
@@ -41,10 +41,12 @@ module CvssSuite
41
41
  def extract_selected_values_from(selected_properties)
42
42
  selected_properties.each do |selected_property|
43
43
  property = @properties.detect do |p|
44
- p.abbreviation == selected_property[:name] && p.position.include?(selected_property[:position])
44
+ p.abbreviation == selected_property[:name] &&
45
+ (p.position&.include?(selected_property[:position]) || p.position.nil?)
45
46
  end
46
47
  property&.set_selected_value selected_property[:selected]
47
48
  end
49
+ @properties.reject(&:valid?).each(&:set_default_value)
48
50
  end
49
51
  end
50
52
  end
@@ -22,7 +22,7 @@ module CvssSuite
22
22
 
23
23
  def initialize(property)
24
24
  @property = property
25
- @property[:default_value] ||= 'Not Available'
25
+ @property[:default_value] ||= 'Not Defined'
26
26
  end
27
27
 
28
28
  ##
@@ -83,5 +83,15 @@ module CvssSuite
83
83
  end
84
84
  @selected_value = values.detect { |value| value[:selected] }
85
85
  end
86
+
87
+ ##
88
+ # Sets the default value.
89
+
90
+ def set_default_value
91
+ values.each do |value|
92
+ value[:selected] = value[:abbreviation].eql?('X')
93
+ end
94
+ @selected_value = values.detect { |value| value[:selected] }
95
+ end
86
96
  end
87
97
  end
@@ -1,7 +1,7 @@
1
1
  # CVSS-Suite, a Ruby gem to manage the CVSS vector
2
2
  #
3
3
  # Copyright (c) 2016-2022 Siemens AG
4
- # Copyright (c) 2022 0llirocks
4
+ # Copyright (c) 2022-2023 0llirocks
5
5
  #
6
6
  # Authors:
7
7
  # 0llirocks <http://0lli.rocks>
@@ -10,5 +10,5 @@
10
10
  # See the LICENSE.md file in the top-level directory.
11
11
 
12
12
  module CvssSuite
13
- VERSION = '3.0.1'.freeze
13
+ VERSION = '3.1.1'.freeze
14
14
  end
data/lib/cvss_suite.rb CHANGED
@@ -34,11 +34,11 @@ module CvssSuite
34
34
  @vector_string = vector
35
35
  case version
36
36
  when 2
37
- Cvss2.new(@vector_string)
37
+ Cvss2.new(prepare_vector(@vector_string))
38
38
  when 3.0
39
- Cvss3.new(@vector_string)
39
+ Cvss3.new(prepare_vector(@vector_string))
40
40
  when 3.1
41
- Cvss31.new(@vector_string)
41
+ Cvss31.new(prepare_vector(@vector_string))
42
42
  else
43
43
  InvalidCvss.new
44
44
  end
@@ -51,4 +51,38 @@ module CvssSuite
51
51
  return beginning[:version] if @vector_string.start_with? beginning[:string]
52
52
  end
53
53
  end
54
+
55
+ def self.prepare_vector(vector)
56
+ vector = vector.clone
57
+
58
+ return prepare_cvss2_vector(vector) if version == 2
59
+
60
+ version_string = CVSS_VECTOR_BEGINNINGS.detect { |v| v[:version] == version } [:string]
61
+ start_of_vector = vector.index(version_string)
62
+
63
+ if start_of_vector.nil?
64
+ ''
65
+ else
66
+ vector[version_string.length..]
67
+ end
68
+ end
69
+
70
+ def self.prepare_cvss2_vector(vector)
71
+ start_of_vector = vector.index('AV')
72
+
73
+ if start_of_vector.nil?
74
+ ''
75
+ elsif start_of_vector == 1
76
+ match_array = vector.scan(/\((?>[^)(]+|\g<0>)*\)/)
77
+ if match_array.length == 1 && match_array[0] == vector
78
+ vector.slice!(0)
79
+ vector.slice!(vector.length - 1)
80
+ vector
81
+ else
82
+ ''
83
+ end
84
+ else
85
+ vector[start_of_vector..]
86
+ end
87
+ end
54
88
  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: 3.0.1
4
+ version: 3.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - 0llirocks
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-03-13 00:00:00.000000000 Z
11
+ date: 2023-10-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -121,7 +121,7 @@ licenses:
121
121
  metadata:
122
122
  bug_tracker_uri: https://github.com/0llirocks/cvss-suite/issues
123
123
  changelog_uri: https://github.com/0llirocks/cvss-suite/blob/master/CHANGES.md
124
- documentation_uri: https://www.rubydoc.info/gems/cvss-suite/3.0.1
124
+ documentation_uri: https://www.rubydoc.info/gems/cvss-suite/3.1.1
125
125
  homepage_uri: https://cvss-suite.0lli.rocks
126
126
  source_code_uri: https://github.com/0llirocks/cvss-suite
127
127
  post_install_message: