CVSS

 view release on metacpan or  search on metacpan

lib/CVSS/v3.pm  view on Meta::CPAN


    }


    # PR depends on the value of Scope (S).
    if ($metric eq 'PR') {

        DEBUG and say STDERR '-- PR depends on the value of Scope (S)';

        my $s_value  = $self->M('S');
        my $pr_value = $self->M('PR');
        my $weight   = $WEIGHTS->{PR}{$s_value}{$pr_value};

        DEBUG and say STDERR "-- Weight : $metric:$pr_value = $weight (S:$s_value)";

        return $weight;

    }

    my $value  = $self->M($metric);
    my $weight = $WEIGHTS->{$metric}{$value};

    DEBUG and say STDERR "-- Weight : $metric:$value = $weight";

    return $weight;

}

sub W { weight(@_) }

sub calculate_score {

    my ($self) = @_;

    if (%{$self->metrics}) {
        for (@{$self->METRIC_GROUPS->{base}}) {
            Carp::croak sprintf('Missing base metric (%s)', $_) unless ($self->metrics->{$_});
        }
    }

    # Set NOT_DEFINED
    $self->metrics->{E}  //= 'X';
    $self->metrics->{RL} //= 'X';
    $self->metrics->{RC} //= 'X';

    $self->metrics->{CR}  //= 'X';
    $self->metrics->{IR}  //= 'X';
    $self->metrics->{AR}  //= 'X';
    $self->metrics->{MAV} //= 'X';
    $self->metrics->{MAC} //= 'X';
    $self->metrics->{MPR} //= 'X';
    $self->metrics->{MUI} //= 'X';
    $self->metrics->{MS}  //= 'X';
    $self->metrics->{MC}  //= 'X';
    $self->metrics->{MI}  //= 'X';
    $self->metrics->{MA}  //= 'X';


    # Base Metrics Equations

    # The Base Score formula depends on sub-formulas for Impact Sub-Score (ISS),
    # Impact, and Exploitability, all of which are defined below:

    # ISS = 1 - [ (1 - Confidentiality) × (1 - Integrity) × (1 - Availability) ]

    # Impact =
    #   If Scope is Unchanged   6.42 × ISS
    #   If Scope is Changed     7.52 × (ISS - 0.029) - 3.25 × (ISS - 0.02) ** 15

    # Exploitability =  8.22 × AttackVector × AttackComplexity ×
    #                   PrivilegesRequired × UserInteraction

    # BaseScore =
    #   If Impact \<= 0         0, else
    #   If Scope is Unchanged   Roundup (Minimum [(Impact + Exploitability), 10])
    #   If Scope is Changed     Roundup (Minimum [1.08 × (Impact + Exploitability), 10])

    my $iss            = (1 - ((1 - $self->W('C')) * (1 - $self->W('I')) * (1 - $self->W('A'))));
    my $impact         = 0;
    my $exploitability = 8.22 * $self->W('AV') * $self->W('AC') * $self->W('PR') * $self->W('UI');
    my $base_score     = 0;

    if ($self->M('S') eq 'U') {
        $impact = $self->W('S') * $iss;
    }
    else {
        $impact = $self->W('S') * ($iss - 0.029) - 3.25 * ($iss - 0.02)**15;
    }

    if ($impact <= 0) {
        $base_score = 0;
    }
    elsif ($self->M('S') eq 'U') {
        $base_score = round_up(min(($impact + $exploitability), 10));
    }
    else {
        $base_score = round_up(min((1.08 * ($impact + $exploitability)), 10));
    }

    DEBUG and say STDERR "-- Impact Sub-Score (ISS): $iss";
    DEBUG and say STDERR "-- Impact: $impact";
    DEBUG and say STDERR "-- Exploitability: $exploitability";
    DEBUG and say STDERR "-- BaseScore: $base_score";

    $self->{scores}->{base}           = $base_score;
    $self->{scores}->{exploitability} = sprintf('%.1f', $exploitability);
    $self->{scores}->{impact}         = sprintf('%.1f', $impact);

    if ($self->metric_group_is_set('temporal')) {

        # Temporal Metrics Equations

        # TemporalScore =     Roundup (BaseScore × ExploitCodeMaturity × RemediationLevel × ReportConfidence)

        my $temporal_score = round_up($base_score * $self->W('E') * $self->W('RL') * $self->W('RC'));

        DEBUG and say STDERR "-- TemporalScore: $temporal_score";

        $self->{scores}->{temporal} = $temporal_score;

    }


    if ($self->metric_group_is_set('environmental')) {

        # Environmental Metrics Equations

        # The Environmental Score formula depends on sub-formulas for Modified Impact
        # Sub-Score (MISS), ModifiedImpact, and ModifiedExploitability, all of which
        # are defined below:

        # MISS =  Minimum ( 1 - [
        #   (1 - ConfidentialityRequirement × ModifiedConfidentiality) ×
        #   (1 - IntegrityRequirement × ModifiedIntegrity) ×
        #   (1 - AvailabilityRequirement × ModifiedAvailability)
        # ], 0.915)

        # ModifiedImpact =
        #   If ModifiedScope is Unchanged   6.42 × MISS
        #   If ModifiedScope is Changed     7.52 × (MISS - 0.029) - 3.25 × (MISS × 0.9731 - 0.02) ** 13
        #                   CVSS v3.0  -->  7.52 × (MISS - 0.029) - 3.25 × (MISS - 0.02) ** 15

        # ModifiedExploitability =    8.22 × ModifiedAttackVector ×
        #                                    ModifiedAttackComplexity ×
        #                                    ModifiedPrivilegesRequired ×
        #                                    ModifiedUserInteraction

        # EnvironmentalScore =
        #   If ModifiedImpact \<= 0         0, else
        #   If ModifiedScope is Unchanged   Roundup ( Roundup [Minimum (
        #                                       [ModifiedImpact + ModifiedExploitability], 10) ] ×
        #                                       ExploitCodeMaturity × RemediationLevel × ReportConfidence)

        #   If ModifiedScope is Changed     Roundup ( Roundup [Minimum (1.08 ×
        #                                       [ModifiedImpact + ModifiedExploitability], 10) ] ×
        #                                       ExploitCodeMaturity × RemediationLevel × ReportConfidence)

        my $modified_impact         = 0;
        my $environmental_score     = 0;
        my $modified_exploitability = 8.22 * $self->W('MAV') * $self->W('MAC') * $self->W('MPR') * $self->W('MUI');

        my $miss = min(
            (
                1 - (
                      (1 - $self->W('MC') * $self->W('CR'))
                    * (1 - $self->W('MI') * $self->W('IR'))
                        * (1 - $self->W('MA') * $self->W('AR'))
                )
            ),
            0.915
        );

        DEBUG and say STDERR "-- Modified Impact Sub-Score (MISS): $miss";

        if ($self->M('MS') eq 'U' || ($self->M('MS') eq 'X' && $self->M('S') eq 'U')) {
            $modified_impact = $self->W('MS') * $miss;
        }
        else {
            if ($self->version == 3.0) {
                $modified_impact = $self->W('MS') * ($miss - 0.029) - 3.25 * (($miss - 0.02)**15);
            }
            elsif ($self->version == 3.1) {
                $modified_impact = $self->W('MS') * ($miss - 0.029) - 3.25 * (($miss * 0.9731 - 0.02)**13);
            }
        }


        if ($modified_impact <= 0) {



( run in 1.742 second using v1.01-cache-2.11-cpan-df04353d9ac )