CVSS
view release on metacpan or search on metacpan
lib/CVSS/v4.pm view on Meta::CPAN
$severity_distance_VC
= $VC_levels->{$self->M("VC")} - $VC_levels->{$self->extract_value_metric("VC", $max_vector)};
$severity_distance_VI
= $VI_levels->{$self->M("VI")} - $VI_levels->{$self->extract_value_metric("VI", $max_vector)};
$severity_distance_VA
= $VA_levels->{$self->M("VA")} - $VA_levels->{$self->extract_value_metric("VA", $max_vector)};
$severity_distance_SC
= $SC_levels->{$self->M("SC")} - $SC_levels->{$self->extract_value_metric("SC", $max_vector)};
$severity_distance_SI
= $SI_levels->{$self->M("SI")} - $SI_levels->{$self->extract_value_metric("SI", $max_vector)};
$severity_distance_SA
= $SA_levels->{$self->M("SA")} - $SA_levels->{$self->extract_value_metric("SA", $max_vector)};
$severity_distance_CR
= $CR_levels->{$self->M("CR")} - $CR_levels->{$self->extract_value_metric("CR", $max_vector)};
$severity_distance_IR
= $IR_levels->{$self->M("IR")} - $IR_levels->{$self->extract_value_metric("IR", $max_vector)};
$severity_distance_AR
= $AR_levels->{$self->M("AR")} - $AR_levels->{$self->extract_value_metric("AR", $max_vector)};
my @check = (
$severity_distance_AV, $severity_distance_PR, $severity_distance_UI, $severity_distance_AC,
$severity_distance_AT, $severity_distance_VC, $severity_distance_VI, $severity_distance_VA,
$severity_distance_SC, $severity_distance_SI, $severity_distance_SA, $severity_distance_CR,
$severity_distance_IR, $severity_distance_AR
);
# if any is less than zero this is not the right max
foreach (@check) {
next DISTANCE if ($_ < 0);
}
# if multiple maxes exist to reach it it is enough the first one
last;
}
my $step = 0.1;
my $current_severity_distance_eq1 = ($severity_distance_AV + $severity_distance_PR + $severity_distance_UI);
my $current_severity_distance_eq2 = ($severity_distance_AC + $severity_distance_AT);
my $current_severity_distance_eq3eq6
= ( $severity_distance_VC
+ $severity_distance_VI
+ $severity_distance_VA
+ $severity_distance_CR
+ $severity_distance_IR
+ $severity_distance_AR);
my $current_severity_distance_eq4 = ($severity_distance_SC + $severity_distance_SI + $severity_distance_SA);
my $current_severity_distance_eq5 = 0;
# if the next lower macro score do not exist the result is Nan
# Rename to maximal scoring difference (aka MSD)
my $available_distance_eq1 = $value - $score_eq1_next_lower_macro;
my $available_distance_eq2 = $value - $score_eq2_next_lower_macro;
my $available_distance_eq3eq6 = $value - $score_eq3eq6_next_lower_macro;
my $available_distance_eq4 = $value - $score_eq4_next_lower_macro;
my $available_distance_eq5 = $value - $score_eq5_next_lower_macro;
my $percent_to_next_eq1_severity = 0;
my $percent_to_next_eq2_severity = 0;
my $percent_to_next_eq3eq6_severity = 0;
my $percent_to_next_eq4_severity = 0;
my $percent_to_next_eq5_severity = 0;
my $normalized_severity_eq1 = 0;
my $normalized_severity_eq2 = 0;
my $normalized_severity_eq3eq6 = 0;
my $normalized_severity_eq4 = 0;
my $normalized_severity_eq5 = 0;
# multiply by step because distance is pure
my $max_severity_eq1 = $MAX_SEVERITY->{eq1}->{$eq1} * $step;
my $max_severity_eq2 = $MAX_SEVERITY->{eq2}->{$eq2} * $step;
my $max_severity_eq3eq6 = $MAX_SEVERITY->{eq3eq6}->{$eq3}->{$eq6} * $step;
my $max_severity_eq4 = $MAX_SEVERITY->{eq4}->{$eq4} * $step;
# c. The proportion of the distance is determined by dividing
# the severity distance of the to-be-scored vector by the depth
# of the MacroVector.
# d. The maximal scoring difference is multiplied by the proportion of
# distance.
my $n_existing_lower = 0;
if (!isNaN($available_distance_eq1) && $available_distance_eq1 >= 0) {
$n_existing_lower += 1;
$percent_to_next_eq1_severity = ($current_severity_distance_eq1) / $max_severity_eq1;
$normalized_severity_eq1 = $available_distance_eq1 * $percent_to_next_eq1_severity;
}
if (!isNaN($available_distance_eq2) && $available_distance_eq2 >= 0) {
$n_existing_lower += 1;
$percent_to_next_eq2_severity = ($current_severity_distance_eq2) / $max_severity_eq2;
$normalized_severity_eq2 = $available_distance_eq2 * $percent_to_next_eq2_severity;
}
if (!isNaN($available_distance_eq3eq6) && $available_distance_eq3eq6 >= 0) {
$n_existing_lower += 1;
$percent_to_next_eq3eq6_severity = ($current_severity_distance_eq3eq6) / $max_severity_eq3eq6;
$normalized_severity_eq3eq6 = $available_distance_eq3eq6 * $percent_to_next_eq3eq6_severity;
}
if (!isNaN($available_distance_eq4) && $available_distance_eq4 >= 0) {
$n_existing_lower += 1;
$percent_to_next_eq4_severity = ($current_severity_distance_eq4) / $max_severity_eq4;
$normalized_severity_eq4 = $available_distance_eq4 * $percent_to_next_eq4_severity;
}
if (!isNaN($available_distance_eq5) && $available_distance_eq5 >= 0) {
$n_existing_lower += 1;
$percent_to_next_eq5_severity = 0;
$normalized_severity_eq5 = $available_distance_eq5 * $percent_to_next_eq5_severity;
}
my $mean_distance = undef;
# 2. The mean of the above computed proportional distances is computed.
if ($n_existing_lower == 0) {
$mean_distance = 0;
}
else {
# sometimes we need to go up but there is nothing there, or down but there is nothing there so it's a change of 0.
$mean_distance
= ( $normalized_severity_eq1
+ $normalized_severity_eq2
+ $normalized_severity_eq3eq6
+ $normalized_severity_eq4
+ $normalized_severity_eq5)
/ $n_existing_lower;
}
# /
DEBUG and say STDERR "-- Value: $value - MeanDistance: $mean_distance";
# 3. The score of the vector is the score of the MacroVector
# (i.e. the score of the highest severity vector) minus the mean
# distance so computed. This score is rounded to one decimal place.
$value -= $mean_distance;
DEBUG and say STDERR "-- Value $value";
$value = max(0.0, $value);
$value = min(10.0, $value);
my $base_score = sprintf('%.1f', $value);
DEBUG and say STDERR "-- BaseScore: $base_score ($value)";
$self->{scores}->{base} = $base_score;
return 1;
}
sub extract_value_metric {
my ($self, $metric, $vector_string) = @_;
my %metrics = split /[\/:]/, $vector_string;
return $metrics{$metric};
}
sub isNaN { !defined($_[0] <=> 9**9**9) }
sub to_xml {
my ($self) = @_;
my $metric_value_names = $self->METRIC_NAMES;
$self->calculate_score unless ($self->base_score);
my $version = $self->version;
( run in 0.481 second using v1.01-cache-2.11-cpan-99c4e6809bf )