cvss-suite 3.0.0 → 3.1.0
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/CHANGES.md +13 -0
- data/README.md +0 -6
- data/cvss_suite.gemspec +8 -1
- data/lib/cvss_suite/cvss.rb +4 -24
- data/lib/cvss_suite/cvss3/cvss3_base.rb +8 -8
- data/lib/cvss_suite/cvss3/cvss3_environmental.rb +11 -11
- data/lib/cvss_suite/cvss3/cvss3_temporal.rb +3 -3
- data/lib/cvss_suite/cvss31/cvss31_base.rb +8 -8
- data/lib/cvss_suite/cvss31/cvss31_environmental.rb +11 -11
- data/lib/cvss_suite/cvss31/cvss31_temporal.rb +3 -3
- data/lib/cvss_suite/cvss_metric.rb +3 -1
- data/lib/cvss_suite/cvss_property.rb +11 -1
- data/lib/cvss_suite/version.rb +1 -1
- data/lib/cvss_suite.rb +37 -3
- metadata +9 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8d6c9f7e41ba7184e8140cf17c6fc0a1b2dced70a3a0e80a603700c2517f413c
|
4
|
+
data.tar.gz: 8277aaf7c847feb0d83adcf96f33e85dbbaa4916bb84fb3b1fad5fc1eb99ef57
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3640b87d41a2b7533b756b416e115e8cde0bb4459a8aefe325d0db82816b48dc0b3f32bd2d6c9dde4ab48ec0bec94efc8572e0c94412618070a45ab04012dd04
|
7
|
+
data.tar.gz: fe15648aa4362009d44ef9159e38f40494b09911582845b29732cb6c6512694c6bdf4d3b57ec412a6e9e76c783c197746dd76a2cce79ce298facad8f4a8ac334
|
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.0] - 2022-09-27
|
6
|
+
|
7
|
+
### Fixes
|
8
|
+
* Metrics are no longer order-dependent. Fixes [#30](https://github.com/0llirocks/cvss-suite/issues/30)
|
9
|
+
|
10
|
+
### Improvements
|
11
|
+
* Temporal and Environmental metrics can now be partly omitted instead of setting them to X.
|
12
|
+
|
13
|
+
## [3.0.1] - 2022-03-13
|
14
|
+
|
15
|
+
### Notes
|
16
|
+
* Updated specification reference due to [Removing the edit linkset form](https://blog.rubygems.org/2019/03/08/and-then-there-was-one-metadata-links.html) and [Unable to edit gem online](https://github.com/rubygems/rubygems.org/issues/1899)
|
17
|
+
|
5
18
|
## [3.0.0] - 2022-03-13
|
6
19
|
|
7
20
|
### Breaking Changes
|
data/README.md
CHANGED
@@ -100,14 +100,8 @@ valid = cvss.valid? # false
|
|
100
100
|
cvss.base_score # will throw CvssSuite::Errors::InvalidVector: Vector is not valid!
|
101
101
|
```
|
102
102
|
|
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
103
|
## Known Issues
|
108
104
|
|
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
105
|
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
106
|
|
113
107
|
## Changelog
|
data/cvss_suite.gemspec
CHANGED
@@ -24,7 +24,14 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.summary = 'Ruby gem for processing cvss vectors.'
|
25
25
|
spec.description = 'This Ruby gem helps you to process the vector of the Common Vulnerability Scoring System (https://www.first.org/cvss/specification-document).
|
26
26
|
Besides calculating the Base, Temporal and Environmental Score, you are able to extract the selected option.'
|
27
|
-
|
27
|
+
|
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'
|
34
|
+
}
|
28
35
|
|
29
36
|
spec.required_ruby_version = '>= 2.6.0'
|
30
37
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
data/lib/cvss_suite/cvss.rb
CHANGED
@@ -37,7 +37,7 @@ module CvssSuite
|
|
37
37
|
##
|
38
38
|
# Returns if CVSS vector is valid.
|
39
39
|
def valid?
|
40
|
-
if @amount_of_properties
|
40
|
+
if @amount_of_properties >= required_amount_of_properties
|
41
41
|
base = @base.valid?
|
42
42
|
temporal = @base.valid? && @temporal.valid?
|
43
43
|
environmental = @base.valid? && @environmental.valid?
|
@@ -83,41 +83,21 @@ module CvssSuite
|
|
83
83
|
private
|
84
84
|
|
85
85
|
def extract_metrics
|
86
|
-
properties =
|
86
|
+
properties = @vector.split('/')
|
87
87
|
@amount_of_properties = properties.size
|
88
88
|
properties.each_with_index do |property, index|
|
89
89
|
property = property.split(':')
|
90
90
|
@properties.push({ name: property[0], selected: property[1], position: index })
|
91
91
|
end
|
92
|
+
@properties = [] if @properties.group_by { |p| p[:name] }.select { |_k, v| v.size > 1 }.length.positive?
|
92
93
|
end
|
93
94
|
|
94
95
|
def check_validity
|
95
96
|
raise CvssSuite::Errors::InvalidVector, 'Vector is not valid!' unless valid?
|
96
97
|
end
|
97
98
|
|
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
99
|
def required_amount_of_properties
|
118
|
-
total = @base.count
|
119
|
-
total += @temporal.count if @temporal.valid?
|
120
|
-
total += @environmental.count if @environmental.valid?
|
100
|
+
total = @base.count
|
121
101
|
total || 0
|
122
102
|
end
|
123
103
|
end
|
@@ -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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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 },
|
@@ -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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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] &&
|
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
|
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
|
data/lib/cvss_suite/version.rb
CHANGED
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.
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- 0llirocks
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-09-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -115,10 +115,15 @@ files:
|
|
115
115
|
- lib/cvss_suite/helpers/cvss3_helper.rb
|
116
116
|
- lib/cvss_suite/invalid_cvss.rb
|
117
117
|
- lib/cvss_suite/version.rb
|
118
|
-
homepage:
|
118
|
+
homepage:
|
119
119
|
licenses:
|
120
120
|
- MIT
|
121
|
-
metadata:
|
121
|
+
metadata:
|
122
|
+
bug_tracker_uri: https://github.com/0llirocks/cvss-suite/issues
|
123
|
+
changelog_uri: https://github.com/0llirocks/cvss-suite/blob/master/CHANGES.md
|
124
|
+
documentation_uri: https://www.rubydoc.info/gems/cvss-suite/3.1.0
|
125
|
+
homepage_uri: https://cvss-suite.0lli.rocks
|
126
|
+
source_code_uri: https://github.com/0llirocks/cvss-suite
|
122
127
|
post_install_message:
|
123
128
|
rdoc_options: []
|
124
129
|
require_paths:
|