File Coverage

blib/lib/CVSS/Constants.pm
Criterion Covered Total %
statement 127 208 61.0
branch n/a
condition n/a
subroutine 28 30 93.3
pod 0 3 0.0
total 155 241 64.3


line stmt bran cond sub pod time code
1             package CVSS::Constants;
2              
3 6     6   36 use feature ':5.10';
  6         8  
  6         815  
4 6     6   31 use strict;
  6         9  
  6         110  
5 6     6   20 use utf8;
  6         9  
  6         34  
6 6     6   134 use warnings;
  6         8  
  6         665  
7              
8             our $VERSION = '1.14';
9             $VERSION =~ tr/_//d; ## no critic
10              
11              
12             # CVSS v2.0 constants
13              
14 6         445 use constant CVSS2_SCORE_SEVERITY => {
15             NONE => {min => 0.0, max => 0.0},
16             LOW => {min => 0.1, max => 3.9},
17             MEDIUM => {min => 4.0, max => 6.9},
18             HIGH => {min => 7.0, max => 10.0},
19 6     6   28 };
  6         8  
20              
21 6     6   28 use constant CVSS2_NOT_DEFINED_VALUE => 'ND';
  6         6  
  6         2291  
22              
23 6         518 use constant CVSS2_VECTOR_STRING_REGEX =>
24 6     6   33 qr{^((AV:[NAL]|AC:[LMH]|Au:[MSN]|[CIA]:[NPC]|E:(U|POC|F|H|ND)|RL:(OF|TF|W|U|ND)|RC:(UC|UR|C|ND)|CDP:(N|L|LM|MH|H|ND)|TD:(N|L|M|H|ND)|[CIA]R:(L|M|H|ND))/)*(AV:[NAL]|AC:[LMH]|Au:[MSN]|[CIA]:[NPC]|E:(U|POC|F|H|ND)|RL:(OF|TF|W|U|ND)|RC:(UC|UR|C|ND)|CDP:(N|L|LM|MH|H|ND)|TD:(N|L|M|H|ND)|[CIA]R:(L|M|H|ND))$};
  6         9  
25              
26              
27 6         1451 use constant CVSS2_METRIC_GROUPS =>
28 6     6   30 {base => [qw(AV AC Au C I A)], temporal => [qw(E RL RC)], environmental => [qw(CDP TD CR IR AR)]};
  6         9  
29              
30 6         734 use constant CVSS2_WEIGHTS => {
31              
32             AV => {N => 1.0, A => 0.646, L => 0.395},
33             AC => {H => 0.35, M => 0.61, L => 0.71},
34             Au => {M => 0.45, S => 0.56, N => 0.704},
35             C => {N => 0.0, P => 0.275, C => 0.660},
36             I => {N => 0.0, P => 0.275, C => 0.660},
37             A => {N => 0.0, P => 0.275, C => 0.660},
38              
39             E => {U => 0.85, POC => 0.9, F => 0.95, H => 1.00, ND => 1.00},
40             RL => {OF => 0.87, TF => 0.90, W => 0.95, U => 1.00, ND => 1.00},
41             RC => {UC => 0.90, UR => 0.95, C => 1.00, ND => 1.00},
42              
43             CDP => {N => 0, L => 0.1, LM => 0.3, MH => 0.4, H => 0.5, ND => 0},
44             TD => {N => 0, L => 0.25, M => 0.75, H => 1.0, ND => 1.0},
45             CR => {L => 0.5, M => 1.0, H => 1.51, ND => 1.0},
46             IR => {L => 0.5, M => 1.0, H => 1.51, ND => 1.0},
47             AR => {L => 0.5, M => 1.0, H => 1.51, ND => 1.0},
48              
49 6     6   28 };
  6         16  
50              
51 6         745 use constant CVSS2_ATTRIBUTES => {
52              
53             # Base metrics
54             accessVector => 'AV',
55             accessComplexity => 'AC',
56             authentication => 'Au',
57             confidentialityImpact => 'C',
58             integrityImpact => 'I',
59             availabilityImpact => 'A',
60              
61             # Temporal
62             exploitability => 'E',
63             remediationLevel => 'RL',
64             reportConfidence => 'RC',
65              
66             # Environmental
67             collateralDamagePotential => 'CDP',
68             targetDistribution => 'TD',
69             confidentialityRequirement => 'CR',
70             integrityRequirement => 'IR',
71             availabilityRequirement => 'AR',
72              
73 6     6   41 };
  6         29  
74              
75 6         2587 use constant CVSS2_METRIC_VALUES => {
76              
77             AV => [qw(N A L)],
78             AC => [qw(H M L)],
79             Au => [qw(M S N)],
80             C => [qw(N P C)],
81             I => [qw(N P C)],
82             A => [qw(N P C)],
83              
84             E => [qw(U POC F H ND)],
85             RL => [qw(OF TF W U ND)],
86             RC => [qw(UC UR C ND)],
87              
88             CDP => [qw(N L LM MH H ND)],
89             TD => [qw(N L M H ND)],
90             CR => [qw(L M H ND)],
91             IR => [qw(L M H ND)],
92             AR => [qw(L M H ND)],
93              
94 6     6   28 };
  6         44  
95              
96             sub CVSS2_METRIC_NAMES {
97              
98 0     0 0 0 my $ND = 'NOT_DEFINED';
99              
100 0         0 my $AV = {N => 'NETWORK', A => 'ADJACENT_NETWORK', L => 'LOCAL'};
101 0         0 my $AC = {H => 'HIGH', M => 'MEDIUM', L => 'LOW'};
102 0         0 my $Au = {M => 'MULTIPLE', S => 'SINGLE', N => 'NONE'};
103 0         0 my $C = {N => 'NONE', P => 'PARTIAL', C => 'COMPLETE'};
104 0         0 my $I = {N => 'NONE', P => 'PARTIAL', C => 'COMPLETE'};
105 0         0 my $A = {N => 'NONE', P => 'PARTIAL', C => 'COMPLETE'};
106              
107 0         0 my $E = {U => 'UNPROVEN', POC => 'PROOF_OF_CONCEPT', F => 'FUNCTIONAL', H => 'HIGH', ND => $ND};
108 0         0 my $RL = {OF => 'OFFICIAL_FIX', TF => 'TEMPORARY_FIX', W => 'WORKAROUND', U => 'UNAVAILABLE', ND => $ND};
109 0         0 my $RC = {UC => 'UNCONFIRMED', UR => 'UNCORROBORATED', C => 'CONFIRMED', ND => $ND};
110              
111 0         0 my $CDP = {N => 'NONE', L => 'LOW', LM => 'LOW_MEDIUM', MH => 'MEDIUM_HIGH', H => 'HIGH', ND => $ND};
112 0         0 my $TD = {N => 'NONE', L => 'LOW', M => 'MEDIUM', H => 'HIGH', ND => $ND};
113 0         0 my $CR = {L => 'LOW', M => 'MEDIUM', H => 'HIGH', ND => $ND};
114 0         0 my $IR = {L => 'LOW', M => 'MEDIUM', H => 'HIGH', ND => $ND};
115 0         0 my $AR = {L => 'LOW', M => 'MEDIUM', H => 'HIGH', ND => $ND};
116              
117             return {
118              
119             # Base
120 0         0 AV => {json => 'accessVector', values => $AV},
121             AC => {json => 'accessComplexity', values => $AC},
122             Au => {json => 'authentication', values => $Au},
123             C => {json => 'confidentialityImpact', values => $C},
124             I => {json => 'integrityImpact', values => $I},
125             A => {json => 'availabilityImpact', values => $A},
126              
127             # Temporal
128             E => {json => 'exploitability', values => $E},
129             RL => {json => 'remediationLevel', values => $RL},
130             RC => {json => 'reportConfidence', values => $RC},
131              
132             # Environmental
133             CDP => {json => 'collateralDamagePotential', values => $CDP},
134             TD => {json => 'targetDistribution', values => $TD},
135             CR => {json => 'confidentialityRequirement', values => $CR},
136             IR => {json => 'integrityRequirement', values => $IR},
137             AR => {json => 'availabilityRequirement', values => $AR},
138              
139             };
140             }
141              
142              
143             # CVSS v3.x constans
144              
145 6         382 use constant CVSS3_SCORE_SEVERITY => {
146             NONE => {min => 0.0, max => 0.0},
147             LOW => {min => 0.1, max => 3.9},
148             MEDIUM => {min => 4.0, max => 6.9},
149             HIGH => {min => 7.0, max => 8.9},
150             CRITICAL => {min => 9.0, max => 10.0}
151 6     6   50 };
  6         7  
152              
153              
154 6     6   25 use constant CVSS3_NOT_DEFINED_VALUE => 'X';
  6         9  
  6         384  
155              
156 6         2683 use constant CVSS3_METRIC_GROUPS => {
157             base => [qw(AV AC PR UI S C I A)],
158             temporal => [qw(E RL RC)],
159             environmental => [qw(CR IR AR MAV MAC MPR MUI MS MC MI MA)],
160 6     6   25 };
  6         8  
161              
162 6         1223 use constant CVSS3_VECTOR_STRING_REGEX =>
163 6     6   34 qr{^CVSS:3\.[0-1]\/((AV:[NALP]|AC:[LH]|PR:[UNLH]|UI:[NR]|S:[UC]|[CIA]:[NLH]|E:[XUPFH]|RL:[XOTWU]|RC:[XURC]|[CIA]R:[XLMH]|MAV:[XNALP]|MAC:[XLH]|MPR:[XUNLH]|MUI:[XNR]|MS:[XUC]|M[CIA]:[XNLH])\/)*(AV:[NALP]|AC:[LH]|PR:[UNLH]|UI:[NR]|S:[UC]|[CIA]:[NLH]|E:[XUPFH]|RL:[XOTWU]|RC:[XURC]|[CIA]R:[XLMH]|MAV:[XNALP]|MAC:[XLH]|MPR:[XUNLH]|MUI:[XNR]|MS:[XUC]|M[CIA]:[XNLH])$};
  6         8  
164              
165 6         992 use constant CVSS3_WEIGHTS => {
166              
167             # Base
168              
169             AV => {N => 0.85, A => 0.62, L => 0.55, P => 0.2},
170             AC => {H => 0.44, L => 0.77},
171              
172             # These values are used if Scope is Changed
173             PR => {U => {N => 0.85, L => 0.62, H => 0.27}, C => {N => 0.85, L => 0.68, H => 0.5}},
174              
175             UI => {N => 0.85, R => 0.62},
176             S => {U => 6.42, C => 7.52}, # Note: not defined as constants in specification
177              
178             # C, I and A have the same weights
179             C => {N => 0, L => 0.22, H => 0.56},
180             I => {N => 0, L => 0.22, H => 0.56},
181             A => {N => 0, L => 0.22, H => 0.56},
182              
183             # Temporal
184              
185             E => {X => 1, U => 0.91, P => 0.94, F => 0.97, H => 1},
186             RL => {X => 1, O => 0.95, T => 0.96, W => 0.97, U => 1},
187             RC => {X => 1, U => 0.92, R => 0.96, C => 1},
188              
189             # Environmental
190              
191             # CR, IR and AR have the same weights
192             CR => {X => 1, L => 0.5, M => 1, H => 1.5},
193             IR => {X => 1, L => 0.5, M => 1, H => 1.5},
194             AR => {X => 1, L => 0.5, M => 1, H => 1.5},
195              
196             # (modified Base)
197              
198             MAV => {N => 0.85, A => 0.62, L => 0.55, P => 0.2},
199             MAC => {H => 0.44, L => 0.77},
200              
201             # These values are used if Scope is Changed
202             MPR => {U => {N => 0.85, L => 0.62, H => 0.27}, C => {N => 0.85, L => 0.68, H => 0.5}},
203              
204             MUI => {N => 0.85, R => 0.62},
205             MS => {U => 6.42, C => 7.52}, # Note: not defined as constants in specification
206              
207             # C, I and A have the same weights
208             MC => {N => 0, L => 0.22, H => 0.56},
209             MI => {N => 0, L => 0.22, H => 0.56},
210             MA => {N => 0, L => 0.22, H => 0.56},
211              
212 6     6   48 };
  6         8  
213              
214 6         5878 use constant CVSS3_ATTRIBUTES => {
215              
216             # Base metrics
217             attackVector => 'AV',
218             attackComplexity => 'AC',
219             privilegesRequired => 'PR',
220             userInteraction => 'UI',
221             scope => 'S',
222             confidentialityImpact => 'C',
223             integrityImpact => 'I',
224             availabilityImpact => 'A',
225              
226             # Temporal metrics
227             exploitCodeMaturity => 'E',
228             remediationLevel => 'RL',
229             reportConfidence => 'RC',
230              
231             # Enviromental metrics
232             confidentialityRequirement => 'CR',
233             integrityRequirement => 'IR',
234             availabilityRequirement => 'AR',
235             modifiedAttackVector => 'MAV',
236             modifiedAttackComplexity => 'MAC',
237             modifiedPrivilegesRequired => 'MPR',
238             modifiedUserInteraction => 'MUI',
239             modifiedScope => 'MS',
240             modifiedConfidentialityImpact => 'MC',
241             modifiedIntegrityImpact => 'MI',
242             modifiedAvailabilityImpact => 'MA',
243              
244 6     6   40 };
  6         9  
245              
246 6         4657 use constant CVSS3_METRIC_VALUES => {
247              
248             AV => [qw(N A L P)],
249             AC => [qw(L H)],
250             PR => [qw(N L H)],
251             UI => [qw(N R)],
252             S => [qw(U C)],
253             C => [qw(N L H)],
254             I => [qw(N L H)],
255             A => [qw(N L H)],
256              
257             E => [qw(X U P F H)],
258             RL => [qw(X O T W U)],
259             RC => [qw(X U R C)],
260              
261             MAV => [qw(X N A L P)],
262             MAC => [qw(X L H)],
263             MPR => [qw(X N L H)],
264             MUI => [qw(X N R)],
265             MS => [qw(X U C)],
266             MC => [qw(X N L H)],
267             MI => [qw(X N L H)],
268             MA => [qw(X N L H)],
269             CR => [qw(X L M H)],
270             IR => [qw(X L M H)],
271             AR => [qw(X L M H)],
272              
273 6     6   33 };
  6         9  
274              
275             sub CVSS3_METRIC_NAMES {
276              
277 25     25 0 93 my $AV = {N => 'NETWORK', A => 'ADJACENT_NETWORK', L => 'LOCAL', P => 'PHYSICAL'};
278 25         61 my $AC = {H => 'HIGH', L => 'LOW'};
279 25         64 my $PR = {N => 'NONE', L => 'LOW', H => 'HIGH'};
280 25         57 my $UI = {N => 'NONE', R => 'REQUIRED'};
281 25         66 my $S = {U => 'UNCHANGED', C => 'CHANGED'};
282 25         85 my $C = {N => 'NONE', L => 'LOW', H => 'HIGH'};
283 25         67 my $I = {N => 'NONE', L => 'LOW', H => 'HIGH'};
284 25         64 my $A = {N => 'NONE', L => 'LOW', H => 'HIGH'};
285              
286 25         80 my $E = {X => 'NOT_DEFINED', U => 'UNPROVEN', P => 'PROOF_OF_CONCEPT', F => 'FUNCTIONAL', H => 'HIGH'};
287 25         86 my $RL = {X => 'NOT_DEFINED', O => 'OFFICIAL_FIX', T => 'TEMPORARY_FIX', W => 'WORKAROUND', U => 'UNAVAILABLE'};
288 25         72 my $RC = {X => 'NOT_DEFINED', U => 'UNKNOWN', R => 'REASONABLE', C => 'CONFIRMED'};
289              
290 25         91 my $CR = {X => 'NOT_DEFINED', L => 'LOW', M => 'MEDIUM', H => 'HIGH'};
291 25         64 my $IR = {X => 'NOT_DEFINED', L => 'LOW', M => 'MEDIUM', H => 'HIGH'};
292 25         68 my $AR = {X => 'NOT_DEFINED', L => 'LOW', M => 'MEDIUM', H => 'HIGH'};
293 25         77 my $MAV = {N => 'NETWORK', A => 'ADJACENT_NETWORK', L => 'LOCAL', P => 'PHYSICAL', X => 'NOT_DEFINED'};
294 25         58 my $MAC = {H => 'HIGH', L => 'LOW', X => 'NOT_DEFINED'};
295 25         65 my $MPR = {N => 'NONE', L => 'LOW', H => 'HIGH', X => 'NOT_DEFINED'};
296 25         79 my $MUI = {N => 'NONE', R => 'REQUIRED', X => 'NOT_DEFINED'};
297 25         86 my $MS = {U => 'UNCHANGED', C => 'CHANGED', X => 'NOT_DEFINED'};
298 25         75 my $MC = {N => 'NONE', L => 'LOW', H => 'HIGH', X => 'NOT_DEFINED'};
299 25         66 my $MI = {N => 'NONE', L => 'LOW', H => 'HIGH', X => 'NOT_DEFINED'};
300 25         69 my $MA = {N => 'NONE', L => 'LOW', H => 'HIGH', X => 'NOT_DEFINED'};
301              
302 25         73 my @AV = (qw[N A L P]);
303              
304             return {
305             # Base
306 25         180 AV => {json => 'attackVector', values => $AV, names => {reverse(%{$AV})}},
307 25         99 AC => {json => 'attackComplexity', values => $AC, names => {reverse(%{$AC})}},
308 25         110 PR => {json => 'privilegesRequired', values => $PR, names => {reverse(%{$PR})}},
309 25         90 UI => {json => 'userInteraction', values => $UI, names => {reverse(%{$UI})}},
310 25         99 S => {json => 'scope', values => $S, names => {reverse(%{$S})}},
311 25         99 C => {json => 'confidentialityImpact', values => $C, names => {reverse(%{$C})}},
312 25         98 I => {json => 'integrityImpact', values => $I, names => {reverse(%{$I})}},
313 25         109 A => {json => 'availabilityImpact', values => $A, names => {reverse(%{$A})}},
314              
315             # Temporal
316 25         149 E => {json => 'exploitCodeMaturity', values => $E, names => {reverse(%{$E})}},
317 25         137 RL => {json => 'remediationLevel', values => $RL, names => {reverse(%{$RL})}},
318 25         126 RC => {json => 'reportConfidence', values => $RC, names => {reverse(%{$RC})}},
319              
320             # Environmental
321 25         103 CR => {json => 'confidentialityRequirement', values => $CR, names => {reverse(%{$CR})}},
322 25         112 IR => {json => 'integrityRequirement', values => $IR, names => {reverse(%{$IR})}},
323 25         105 AR => {json => 'availabilityRequirement', values => $AR, names => {reverse(%{$AR})}},
324 25         125 MAV => {json => 'modifiedAttackVector', values => $MAV, names => {reverse(%{$MAV})}},
325 25         101 MAC => {json => 'modifiedAttackComplexity', values => $MAC, names => {reverse(%{$MAC})}},
326 25         100 MPR => {json => 'modifiedPrivilegesRequired', values => $MPR, names => {reverse(%{$MPR})}},
327 25         104 MUI => {json => 'modifiedUserInteraction', values => $MUI, names => {reverse(%{$MUI})}},
328 25         128 MS => {json => 'modifiedScope', values => $MS, names => {reverse(%{$MS})}},
329 25         110 MC => {json => 'modifiedConfidentialityImpact', values => $MC, names => {reverse(%{$MC})}},
330 25         122 MI => {json => 'modifiedIntegrityImpact', values => $MI, names => {reverse(%{$MI})}},
331 25         46 MA => {json => 'modifiedAvailabilityImpact', values => $MA, names => {reverse(%{$MA})}},
  25         828  
332              
333             };
334             }
335              
336              
337             # CVSS v4.0 constants
338              
339 6     6   42 use constant CVSS4_SCORE_SEVERITY => CVSS3_SCORE_SEVERITY();
  6         7  
  6         362  
340              
341 6     6   29 use constant CVSS4_NOT_DEFINED_VALUE => 'X';
  6         9  
  6         2670  
342              
343 6         871 use constant CVSS4_VECTOR_STRING_REGEX =>
344 6     6   36 qr{^CVSS:4[.]0/AV:[NALP]/AC:[LH]/AT:[NP]/PR:[NLH]/UI:[NPA]/VC:[HLN]/VI:[HLN]/VA:[HLN]/SC:[HLN]/SI:[HLN]/SA:[HLN](/E:[XAPU])?(/CR:[XHML])?(/IR:[XHML])?(/AR:[XHML])?(/MAV:[XNALP])?(/MAC:[XLH])?(/MAT:[XNP])?(/MPR:[XNLH])?(/MUI:[XNPA])?(/MVC:[XNLH])?(/MVI:[XNLH])?(/MVA:[XNLH])?(/MSC:[XNLH])?(/MSI:[XNLHS])?(/MSA:[XNLHS])?(/S:[XNP])?(/AU:[XNY])?(/R:[XAUI])?(/V:[XDC])?(/RE:[XLMH])?(/U:(X|Clear|Green|Amber|Red))?$};
  6         10  
345              
346 6         3993 use constant CVSS4_MAX_COMPOSED => {
347             eq1 => {
348             0 => ['AV:N/PR:N/UI:N/'],
349             1 => ['AV:A/PR:N/UI:N/', 'AV:N/PR:L/UI:N/', 'AV:N/PR:N/UI:P/'],
350             2 => ['AV:P/PR:N/UI:N/', 'AV:A/PR:L/UI:P/']
351             },
352             eq2 => {0 => ['AC:L/AT:N/'], 1 => ['AC:H/AT:N/', 'AC:L/AT:P/']},
353             eq3 => {
354             0 => {
355             0 => ['VC:H/VI:H/VA:H/CR:H/IR:H/AR:H/'],
356             1 => ['VC:H/VI:H/VA:L/CR:M/IR:M/AR:H/', 'VC:H/VI:H/VA:H/CR:M/IR:M/AR:M/']
357             },
358             1 => {
359             0 => ['VC:L/VI:H/VA:H/CR:H/IR:H/AR:H/', 'VC:H/VI:L/VA:H/CR:H/IR:H/AR:H/'],
360             1 => [
361             'VC:L/VI:H/VA:L/CR:H/IR:M/AR:H/', 'VC:L/VI:H/VA:H/CR:H/IR:M/AR:M/',
362             'VC:H/VI:L/VA:H/CR:M/IR:H/AR:M/', 'VC:H/VI:L/VA:L/CR:M/IR:H/AR:H/',
363             'VC:L/VI:L/VA:H/CR:H/IR:H/AR:M/'
364             ]
365             },
366             2 => {1 => ['VC:L/VI:L/VA:L/CR:H/IR:H/AR:H/']},
367             },
368             eq4 => {
369             0 => ['SC:H/SI:S/SA:S/'],
370             1 => ['SC:H/SI:H/SA:H/'],
371             2 => ['SC:L/SI:L/SA:L/']
372              
373             },
374             eq5 => {0 => ['E:A/'], 1 => ['E:P/'], 2 => ['E:U/']},
375 6     6   30 };
  6         9  
376              
377 6         1241 use constant CVSS4_LOOKUP_GLOBAL => {
378             '000000' => 10.0,
379             '000001' => 9.9,
380             '000010' => 9.8,
381             '000011' => 9.5,
382             '000020' => 9.5,
383             '000021' => 9.2,
384             '000100' => 10.0,
385             '000101' => 9.6,
386             '000110' => 9.3,
387             '000111' => 8.7,
388             '000120' => 9.1,
389             '000121' => 8.1,
390             '000200' => 9.3,
391             '000201' => 9.0,
392             '000210' => 8.9,
393             '000211' => 8.0,
394             '000220' => 8.1,
395             '000221' => 6.8,
396             '001000' => 9.8,
397             '001001' => 9.5,
398             '001010' => 9.5,
399             '001011' => 9.2,
400             '001020' => 9.0,
401             '001021' => 8.4,
402             '001100' => 9.3,
403             '001101' => 9.2,
404             '001110' => 8.9,
405             '001111' => 8.1,
406             '001120' => 8.1,
407             '001121' => 6.5,
408             '001200' => 8.8,
409             '001201' => 8.0,
410             '001210' => 7.8,
411             '001211' => 7.0,
412             '001220' => 6.9,
413             '001221' => 4.8,
414             '002001' => 9.2,
415             '002011' => 8.2,
416             '002021' => 7.2,
417             '002101' => 7.9,
418             '002111' => 6.9,
419             '002121' => 5.0,
420             '002201' => 6.9,
421             '002211' => 5.5,
422             '002221' => 2.7,
423             '010000' => 9.9,
424             '010001' => 9.7,
425             '010010' => 9.5,
426             '010011' => 9.2,
427             '010020' => 9.2,
428             '010021' => 8.5,
429             '010100' => 9.5,
430             '010101' => 9.1,
431             '010110' => 9.0,
432             '010111' => 8.3,
433             '010120' => 8.4,
434             '010121' => 7.1,
435             '010200' => 9.2,
436             '010201' => 8.1,
437             '010210' => 8.2,
438             '010211' => 7.1,
439             '010220' => 7.2,
440             '010221' => 5.3,
441             '011000' => 9.5,
442             '011001' => 9.3,
443             '011010' => 9.2,
444             '011011' => 8.5,
445             '011020' => 8.5,
446             '011021' => 7.3,
447             '011100' => 9.2,
448             '011101' => 8.2,
449             '011110' => 8.0,
450             '011111' => 7.2,
451             '011120' => 7.0,
452             '011121' => 5.9,
453             '011200' => 8.4,
454             '011201' => 7.0,
455             '011210' => 7.1,
456             '011211' => 5.2,
457             '011220' => 5.0,
458             '011221' => 3.0,
459             '012001' => 8.6,
460             '012011' => 7.5,
461             '012021' => 5.2,
462             '012101' => 7.1,
463             '012111' => 5.2,
464             '012121' => 2.9,
465             '012201' => 6.3,
466             '012211' => 2.9,
467             '012221' => 1.7,
468             '100000' => 9.8,
469             '100001' => 9.5,
470             '100010' => 9.4,
471             '100011' => 8.7,
472             '100020' => 9.1,
473             '100021' => 8.1,
474             '100100' => 9.4,
475             '100101' => 8.9,
476             '100110' => 8.6,
477             '100111' => 7.4,
478             '100120' => 7.7,
479             '100121' => 6.4,
480             '100200' => 8.7,
481             '100201' => 7.5,
482             '100210' => 7.4,
483             '100211' => 6.3,
484             '100220' => 6.3,
485             '100221' => 4.9,
486             '101000' => 9.4,
487             '101001' => 8.9,
488             '101010' => 8.8,
489             '101011' => 7.7,
490             '101020' => 7.6,
491             '101021' => 6.7,
492             '101100' => 8.6,
493             '101101' => 7.6,
494             '101110' => 7.4,
495             '101111' => 5.8,
496             '101120' => 5.9,
497             '101121' => 5.0,
498             '101200' => 7.2,
499             '101201' => 5.7,
500             '101210' => 5.7,
501             '101211' => 5.2,
502             '101220' => 5.2,
503             '101221' => 2.5,
504             '102001' => 8.3,
505             '102011' => 7.0,
506             '102021' => 5.4,
507             '102101' => 6.5,
508             '102111' => 5.8,
509             '102121' => 2.6,
510             '102201' => 5.3,
511             '102211' => 2.1,
512             '102221' => 1.3,
513             '110000' => 9.5,
514             '110001' => 9.0,
515             '110010' => 8.8,
516             '110011' => 7.6,
517             '110020' => 7.6,
518             '110021' => 7.0,
519             '110100' => 9.0,
520             '110101' => 7.7,
521             '110110' => 7.5,
522             '110111' => 6.2,
523             '110120' => 6.1,
524             '110121' => 5.3,
525             '110200' => 7.7,
526             '110201' => 6.6,
527             '110210' => 6.8,
528             '110211' => 5.9,
529             '110220' => 5.2,
530             '110221' => 3.0,
531             '111000' => 8.9,
532             '111001' => 7.8,
533             '111010' => 7.6,
534             '111011' => 6.7,
535             '111020' => 6.2,
536             '111021' => 5.8,
537             '111100' => 7.4,
538             '111101' => 5.9,
539             '111110' => 5.7,
540             '111111' => 5.7,
541             '111120' => 4.7,
542             '111121' => 2.3,
543             '111200' => 6.1,
544             '111201' => 5.2,
545             '111210' => 5.7,
546             '111211' => 2.9,
547             '111220' => 2.4,
548             '111221' => 1.6,
549             '112001' => 7.1,
550             '112011' => 5.9,
551             '112021' => 3.0,
552             '112101' => 5.8,
553             '112111' => 2.6,
554             '112121' => 1.5,
555             '112201' => 2.3,
556             '112211' => 1.3,
557             '112221' => 0.6,
558             '200000' => 9.3,
559             '200001' => 8.7,
560             '200010' => 8.6,
561             '200011' => 7.2,
562             '200020' => 7.5,
563             '200021' => 5.8,
564             '200100' => 8.6,
565             '200101' => 7.4,
566             '200110' => 7.4,
567             '200111' => 6.1,
568             '200120' => 5.6,
569             '200121' => 3.4,
570             '200200' => 7.0,
571             '200201' => 5.4,
572             '200210' => 5.2,
573             '200211' => 4.0,
574             '200220' => 4.0,
575             '200221' => 2.2,
576             '201000' => 8.5,
577             '201001' => 7.5,
578             '201010' => 7.4,
579             '201011' => 5.5,
580             '201020' => 6.2,
581             '201021' => 5.1,
582             '201100' => 7.2,
583             '201101' => 5.7,
584             '201110' => 5.5,
585             '201111' => 4.1,
586             '201120' => 4.6,
587             '201121' => 1.9,
588             '201200' => 5.3,
589             '201201' => 3.6,
590             '201210' => 3.4,
591             '201211' => 1.9,
592             '201220' => 1.9,
593             '201221' => 0.8,
594             '202001' => 6.4,
595             '202011' => 5.1,
596             '202021' => 2.0,
597             '202101' => 4.7,
598             '202111' => 2.1,
599             '202121' => 1.1,
600             '202201' => 2.4,
601             '202211' => 0.9,
602             '202221' => 0.4,
603             '210000' => 8.8,
604             '210001' => 7.5,
605             '210010' => 7.3,
606             '210011' => 5.3,
607             '210020' => 6.0,
608             '210021' => 5.0,
609             '210100' => 7.3,
610             '210101' => 5.5,
611             '210110' => 5.9,
612             '210111' => 4.0,
613             '210120' => 4.1,
614             '210121' => 2.0,
615             '210200' => 5.4,
616             '210201' => 4.3,
617             '210210' => 4.5,
618             '210211' => 2.2,
619             '210220' => 2.0,
620             '210221' => 1.1,
621             '211000' => 7.5,
622             '211001' => 5.5,
623             '211010' => 5.8,
624             '211011' => 4.5,
625             '211020' => 4.0,
626             '211021' => 2.1,
627             '211100' => 6.1,
628             '211101' => 5.1,
629             '211110' => 4.8,
630             '211111' => 1.8,
631             '211120' => 2.0,
632             '211121' => 0.9,
633             '211200' => 4.6,
634             '211201' => 1.8,
635             '211210' => 1.7,
636             '211211' => 0.7,
637             '211220' => 0.8,
638             '211221' => 0.2,
639             '212001' => 5.3,
640             '212011' => 2.4,
641             '212021' => 1.4,
642             '212101' => 2.4,
643             '212111' => 1.2,
644             '212121' => 0.5,
645             '212201' => 1.0,
646             '212211' => 0.3,
647             '212221' => 0.1,
648 6     6   67 };
  6         10  
649              
650 6         582 use constant CVSS4_MAX_SEVERITY => {
651             eq1 => {0 => 1, 1 => 4, 2 => 5},
652             eq2 => {0 => 1, 1 => 2},
653             eq3eq6 => {0 => {0 => 7, 1 => 6}, 1 => {0 => 8, 1 => 8}, 2 => {1 => 10}},
654             eq4 => {0 => 6, 1 => 5, 2 => 4},
655             eq5 => {0 => 1, 1 => 1, 2 => 1},
656 6     6   57 };
  6         13  
657              
658 6         844 use constant CVSS4_METRIC_GROUPS => {
659             base => [qw(AV AC AT PR UI VC VI VA SC SI SA)],
660             threat => [qw(E)],
661             environmental => [qw(CR IR AR MAV MAC MAT MPR MUI MVC MVI MVA MSC MSI MSA)],
662             supplemental => [qw(S AU R V RE U)],
663 6     6   31 };
  6         7  
664              
665 6         1252 use constant CVSS4_ATTRIBUTES => {
666              
667             # Base
668             attackVector => 'AV',
669             attackComplexity => 'AC',
670             attackRequirements => 'AT',
671             privilegesRequired => 'PR',
672             userInteraction => 'UI',
673             vulnConfidentialityImpact => 'VC',
674             vulnIntegrityImpact => 'VI',
675             vulnAvailabilityImpact => 'VA',
676             subConfidentialityImpact => 'SC',
677             subIntegrityImpact => 'SI',
678             subAvailabilityImpact => 'SA',
679              
680             # Threat
681             exploitMaturity => 'E',
682              
683             # Environmental
684             confidentialityRequirement => 'CR',
685             integrityRequirement => 'IR',
686             availabilityRequirement => 'AR',
687             modifiedAttackVector => 'MAV',
688             modifiedAttackComplexity => 'MAC',
689             modifiedAttackRequirements => 'MAT',
690             modifiedPrivilegesRequired => 'MPR',
691             modifiedUserInteraction => 'MUI',
692             modifiedVulnConfidentialityImpact => 'MVC',
693             modifiedVulnIntegrityImpact => 'MVI',
694             modifiedVulnAvailabilityImpact => 'MVA',
695             modifiedSubConfidentialityImpact => 'MSC',
696             modifiedSubIntegrityImpact => 'MSI',
697             modifiedSubAvailabilityImpact => 'MSA',
698              
699             # Supplemental
700             Safety => 'S',
701             Automatable => 'AU',
702             Recovery => 'R',
703             valueDensity => 'V',
704             vulnerabilityResponseEffort => 'RE',
705             providerUrgency => 'U',
706              
707 6     6   32 };
  6         7  
708              
709 6         6602 use constant CVSS4_METRIC_VALUES => {
710              
711             AV => [qw(N A L P)],
712             AC => [qw(L H)],
713             AT => [qw(N P)],
714             PR => [qw(N L H)],
715             UI => [qw(N P A)],
716             VC => [qw(H L N)],
717             VI => [qw(H L N)],
718             VA => [qw(H L N)],
719             SC => [qw(H L N)],
720             SI => [qw(H L N)],
721             SA => [qw(H L N)],
722              
723             E => [qw(X A P U)],
724              
725             CR => [qw(X H M L)],
726             IR => [qw(X H M L)],
727             AR => [qw(X H M L)],
728             MAV => [qw(X N A L P)],
729             MAC => [qw(X L H)],
730             MAT => [qw(X N P)],
731             MPR => [qw(X N L H)],
732             MUI => [qw(X N P A)],
733             MVC => [qw(X H L N)],
734             MVI => [qw(X H L N)],
735             MVA => [qw(X H L N)],
736             MSC => [qw(X H L N)],
737             MSI => [qw(X S H L N)],
738             MSA => [qw(X S H L N)],
739              
740             S => [qw(X N P)],
741             AU => [qw(X N Y)],
742             R => [qw(X A U I)],
743             V => [qw(X D C)],
744             RE => [qw(X L M H)],
745             U => [qw(X Clear Green Amber Red)],
746              
747 6     6   29 };
  6         8  
748              
749             sub CVSS4_METRIC_NAMES {
750              
751             # Base
752 0     0 0   my $AV = {N => 'NETWORK', A => 'ADJACENT', L => 'LOCAL', P => 'PHYSICAL'};
753 0           my $AC = {L => 'LOW', H => 'HIGH'};
754 0           my $AT = {N => 'NONE', P => 'PRESENT'};
755 0           my $PR = {N => 'NONE', L => 'LOW', H => 'HIGH'};
756 0           my $UI = {N => 'NONE', P => 'PASSIVE', A => 'ACTIVE'};
757 0           my $VC = {H => 'HIGH', L => 'LOW', N => 'NONE'};
758 0           my $VI = {H => 'HIGH', L => 'LOW', N => 'NONE'};
759 0           my $VA = {H => 'HIGH', L => 'LOW', N => 'NONE'};
760 0           my $SC = {H => 'HIGH', L => 'LOW', N => 'NONE'};
761 0           my $SI = {H => 'HIGH', L => 'LOW', N => 'NONE'};
762 0           my $SA = {H => 'HIGH', L => 'LOW', N => 'NONE'};
763              
764             # Threat
765 0           my $E = {X => 'NOT_DEFINED', A => 'ATTACKED', P => 'PROOF_OF_CONCEPT', U => 'UNREPORTED'};
766              
767             # Environmental
768 0           my $CR = {X => 'NOT_DEFINED', H => 'HIGH', M => 'MEDIUM', L => 'LOW'};
769 0           my $IR = {X => 'NOT_DEFINED', H => 'HIGH', M => 'MEDIUM', L => 'LOW'};
770 0           my $AR = {X => 'NOT_DEFINED', H => 'HIGH', M => 'MEDIUM', L => 'LOW'};
771 0           my $MAV = {X => 'NOT_DEFINED', N => 'NETWORK', A => 'ADJACENT', L => 'LOCAL', P => 'PHYSICAL'};
772 0           my $MAC = {X => 'NOT_DEFINED', L => 'LOW', H => 'HIGH'};
773 0           my $MAT = {X => 'NOT_DEFINED', N => 'NONE', P => 'PRESENT'};
774 0           my $MPR = {X => 'NOT_DEFINED', N => 'NONE', L => 'LOW', H => 'HIGH'};
775 0           my $MUI = {X => 'NOT_DEFINED', N => 'NONE', P => 'PASSIVE', A => 'ACTIVE'};
776 0           my $MVC = {X => 'NOT_DEFINED', H => 'HIGH', L => 'LOW', N => 'NONE'};
777 0           my $MVI = {X => 'NOT_DEFINED', H => 'HIGH', L => 'LOW', N => 'NONE'};
778 0           my $MVA = {X => 'NOT_DEFINED', H => 'HIGH', L => 'LOW', N => 'NONE'};
779 0           my $MSC = {X => 'NOT_DEFINED', H => 'HIGH', L => 'LOW', N => 'NONE'};
780 0           my $MSI = {X => 'NOT_DEFINED', S => 'SAFETY', H => 'HIGH', L => 'LOW', N => 'NEGLIGIBLE'};
781 0           my $MSA = {X => 'NOT_DEFINED', S => 'SAFETY', H => 'HIGH', L => 'LOW', N => 'NEGLIGIBLE'};
782              
783             # Supplemental
784 0           my $S = {X => 'NOT_DEFINED', N => 'NEGLIGIBLE', P => 'PRESENT'};
785 0           my $AU = {X => 'NOT_DEFINED', N => 'NO', Y => 'YES'};
786 0           my $R = {X => 'NOT_DEFINED', A => 'AUTOMATIC', U => 'USER', I => 'IRRECOVERABLE'};
787 0           my $V = {X => 'NOT_DEFINED', D => 'DIFFUSE', C => 'CONCENTRATED'};
788 0           my $RE = {X => 'NOT_DEFINED', L => 'LOW', M => 'MODERATE', H => 'HIGH'};
789 0           my $U = {X => 'NOT_DEFINED', Clear => 'CLEAR', Green => 'GREEN', Amber => 'AMBER', Red => 'RED'};
790              
791             return {
792 0           AV => {json => 'attackVector', values => $AV, names => {reverse(%{$AV})}},
793 0           AC => {json => 'attackComplexity', values => $AC, names => {reverse(%{$AC})}},
794 0           AT => {json => 'attackRequirements', values => $AT, names => {reverse(%{$AT})}},
795 0           PR => {json => 'privilegesRequired', values => $PR, names => {reverse(%{$PR})}},
796 0           UI => {json => 'userInteraction', values => $UI, names => {reverse(%{$UI})}},
797 0           VC => {json => 'vulnConfidentialityImpact', values => $VC, names => {reverse(%{$VC})}},
798 0           VI => {json => 'vulnIntegrityImpact', values => $VI, names => {reverse(%{$VI})}},
799 0           VA => {json => 'vulnAvailabilityImpact', values => $VA, names => {reverse(%{$VA})}},
800 0           SC => {json => 'subConfidentialityImpact', values => $SC, names => {reverse(%{$SC})}},
801 0           SI => {json => 'subIntegrityImpact', values => $SI, names => {reverse(%{$SI})}},
802 0           SA => {json => 'subAvailabilityImpact', values => $SA, names => {reverse(%{$SA})}},
803              
804 0           E => {json => 'exploitMaturity', values => $SA, names => {reverse(%{$E})}},
805              
806 0           CR => {json => 'confidentialityRequirement', values => $CR, names => {reverse(%{$CR})}},
807 0           IR => {json => 'integrityRequirement', values => $IR, names => {reverse(%{$IR})}},
808 0           AR => {json => 'availabilityRequirement', values => $AR, names => {reverse(%{$AR})}},
809 0           MAV => {json => 'modifiedAttackVector', values => $MAV, names => {reverse(%{$MAV})}},
810 0           MAC => {json => 'modifiedAttackComplexity', values => $MAC, names => {reverse(%{$MAC})}},
811 0           MAT => {json => 'modifiedAttackRequirements', values => $MAT, names => {reverse(%{$MAT})}},
812 0           MPR => {json => 'modifiedPrivilegesRequired', values => $MPR, names => {reverse(%{$MPR})}},
813 0           MUI => {json => 'modifiedUserInteraction', values => $MUI, names => {reverse(%{$MUI})}},
814 0           MVC => {json => 'modifiedVulnConfidentialityImpact', values => $MVC, names => {reverse(%{$MVC})}},
815 0           MVI => {json => 'modifiedVulnIntegrityImpact', values => $MVI, names => {reverse(%{$MVI})}},
816 0           MVA => {json => 'modifiedVulnAvailabilityImpact', values => $MVA, names => {reverse(%{$MVA})}},
817 0           MSC => {json => 'modifiedSubConfidentialityImpact', values => $MSC, names => {reverse(%{$MSC})}},
818 0           MSI => {json => 'modifiedSubIntegrityImpact', values => $MSI, names => {reverse(%{$MSI})}},
819 0           MSA => {json => 'modifiedSubAvailabilityImpact', values => $MSA, names => {reverse(%{$MSA})}},
820              
821 0           S => {json => 'Safety', values => $S, names => {reverse(%{$S})}},
822 0           AU => {json => 'Automatable', values => $AU, names => {reverse(%{$AU})}},
823 0           R => {json => 'Recovery', values => $R, names => {reverse(%{$R})}},
824 0           V => {json => 'valueDensity', values => $V, names => {reverse(%{$V})}},
825 0           RE => {json => 'vulnerabilityResponseEffort', values => $RE, names => {reverse(%{$RE})}},
826 0           U => {json => 'providerUrgency', values => $U, names => {reverse(%{$U})}},
  0            
827             };
828              
829             }
830              
831             1;
832             __END__