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