cvss-suite 3.0.1 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +8 -0
- data/README.md +0 -6
- data/cvss_suite.gemspec +5 -5
- 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 +3 -3
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,14 @@
|
|
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
|
+
|
5
13
|
## [3.0.1] - 2022-03-13
|
6
14
|
|
7
15
|
### Notes
|
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
@@ -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'
|
30
|
-
'changelog_uri'
|
31
|
-
'documentation_uri' =>
|
32
|
-
'homepage_uri'
|
33
|
-
'source_code_uri'
|
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'
|
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.0
|
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
|
@@ -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
|
124
|
+
documentation_uri: https://www.rubydoc.info/gems/cvss-suite/3.1.0
|
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:
|