Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:

- name: Cache Composer packages
id: composer-cache
uses: actions/cache@v2
uses: actions/cache@v4
with:
path: vendor
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
Expand Down
68 changes: 67 additions & 1 deletion psalm-baseline.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="6.0.0@b8e96bb617bf59382113b1b56cef751f648a7dc9">
<files psalm-version="6.12.0@cf420941d061a57050b6c468ef2c778faf40aee2">
<file src="src/Calculators/AbstractCvss3Calculator.php">
<InvalidOperand>
<code><![CDATA[($cvssObject->impactSubScore - 0.02) ** 15]]></code>
<code><![CDATA[1 - $cvssObject->availability]]></code>
<code><![CDATA[1 - $cvssObject->confidentiality]]></code>
<code><![CDATA[1 - $cvssObject->integrity]]></code>
<code><![CDATA[1 - ((1 - $cvssObject->confidentiality) * (1 - $cvssObject->integrity) * (1 - $cvssObject->availability))]]></code>
</InvalidOperand>
</file>
<file src="src/Calculators/Cvss2Calculator.php">
<InvalidOperand>
<code><![CDATA[1 - $cvssObject->availability]]></code>
<code><![CDATA[1 - $cvssObject->availability * $cvssObject->availabilityRequirement]]></code>
<code><![CDATA[1 - $cvssObject->confidentiality]]></code>
<code><![CDATA[1 - $cvssObject->confidentiality * $cvssObject->confidentialityRequirement]]></code>
<code><![CDATA[1 - $cvssObject->integrity]]></code>
<code><![CDATA[1 - $cvssObject->integrity * $cvssObject->integrityRequirement]]></code>
<code><![CDATA[1 - (1 - $cvssObject->confidentiality * $cvssObject->confidentialityRequirement) * (1 - $cvssObject->integrity * $cvssObject->integrityRequirement) * (1 - $cvssObject->availability * $cvssObject->availabilityRequirement)]]></code>
<code><![CDATA[1 - (1 - $cvssObject->confidentiality) * (1 - $cvssObject->integrity) * (1 - $cvssObject->availability)]]></code>
<code><![CDATA[10 - $adjustedTemporal]]></code>
<code><![CDATA[20 * $cvssObject->accessVector]]></code>
</InvalidOperand>
</file>
<file src="src/Calculators/Cvss30Calculator.php">
<InvalidOperand>
<code><![CDATA[$number * 10]]></code>
<code><![CDATA[($cvssObject->modifiedImpactSubScore - 0.02) ** 15]]></code>
<code><![CDATA[1 - $cvssObject->availabilityRequirement * $cvssObject->modifiedAvailability]]></code>
<code><![CDATA[1 - $cvssObject->confidentialityRequirement * $cvssObject->modifiedConfidentiality]]></code>
<code><![CDATA[1 - $cvssObject->integrityRequirement * $cvssObject->modifiedIntegrity]]></code>
<code><![CDATA[1 - ((1 - $cvssObject->confidentialityRequirement * $cvssObject->modifiedConfidentiality) *
(1 - $cvssObject->integrityRequirement * $cvssObject->modifiedIntegrity) *
(1 - $cvssObject->availabilityRequirement * $cvssObject->modifiedAvailability))]]></code>
<code><![CDATA[ceil($number * 10) / 10]]></code>
</InvalidOperand>
</file>
<file src="src/Calculators/Cvss31Calculator.php">
<InvalidOperand>
<code><![CDATA[$intInput % 10000]]></code>
<code><![CDATA[$intInput / 10000]]></code>
<code><![CDATA[$number * 100000]]></code>
<code><![CDATA[($cvssObject->modifiedImpactSubScore * 0.9731 - 0.02) ** 13]]></code>
<code><![CDATA[1 - $cvssObject->availabilityRequirement * $cvssObject->modifiedAvailability]]></code>
<code><![CDATA[1 - $cvssObject->confidentialityRequirement * $cvssObject->modifiedConfidentiality]]></code>
<code><![CDATA[1 - $cvssObject->integrityRequirement * $cvssObject->modifiedIntegrity]]></code>
<code><![CDATA[1 - ((1 - $cvssObject->confidentialityRequirement * $cvssObject->modifiedConfidentiality) *
(1 - $cvssObject->integrityRequirement * $cvssObject->modifiedIntegrity) *
(1 - $cvssObject->availabilityRequirement * $cvssObject->modifiedAvailability))]]></code>
<code><![CDATA[floor($intInput / 10000) + 1]]></code>
</InvalidOperand>
</file>
<file src="src/Calculators/Cvss40Calculator.php">
<InvalidOperand>
<code><![CDATA[$this->maxSeverity[1][$cvssObject->eq1] * 0.1]]></code>
<code><![CDATA[$this->maxSeverity[2][$cvssObject->eq2] * 0.1]]></code>
<code><![CDATA[$this->maxSeverity[3][$cvssObject->eq3][$cvssObject->eq6] * 0.1]]></code>
<code><![CDATA[$this->maxSeverity[4][$cvssObject->eq4] * 0.1]]></code>
<code><![CDATA[(
$normalisedSeverity->eqOne +
$normalisedSeverity->eqTwo +
$normalisedSeverity->eqThree +
$normalisedSeverity->eqFour +
$normalisedSeverity->eqFive
) / $existingLower]]></code>
</InvalidOperand>
</file>
<file src="src/Cvss.php">
<UnusedClass>
<code><![CDATA[Cvss]]></code>
Expand Down
3 changes: 3 additions & 0 deletions src/Calculators/AbstractCvss3Calculator.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ abstract public function calculateModifiedImpactSubScore(CvssObject $cvssObject)
abstract public function calculateModifiedImpact(CvssObject $cvssObject): float;
abstract public function roundUp(float $number): float;

#[\Override]
public function calculateBaseScore(CvssObject $cvssObject): float
{
if (!$cvssObject instanceof Cvss23Object) {
Expand Down Expand Up @@ -54,6 +55,7 @@ private function calculateExploitability(Cvss23Object $cvssObject): float
return 8.22 * $cvssObject->attackVector * $cvssObject->attackComplexity * $cvssObject->privilegesRequired * $cvssObject->userInteraction;
}

#[\Override]
public function calculateTemporalScore(CvssObject $cvssObject): float
{
if (!$cvssObject instanceof Cvss23Object) {
Expand All @@ -68,6 +70,7 @@ private function calculateModifiedExploitability(Cvss23Object $cvssObject): floa
return 8.22 * $cvssObject->modifiedAttackVector * $cvssObject->modifiedAttackComplexity * $cvssObject->modifiedPrivilegesRequired * $cvssObject->modifiedUserInteraction;
}

#[\Override]
public function calculateEnvironmentalScore(CvssObject $cvssObject): float
{
if (!$cvssObject instanceof Cvss23Object) {
Expand Down
5 changes: 4 additions & 1 deletion src/Calculators/Cvss2Calculator.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
use Rootshell\Cvss\ValueObjects\Cvss23Object;
use Rootshell\Cvss\ValueObjects\CvssObject;

class Cvss2Calculator implements CvssCalculator
final class Cvss2Calculator implements CvssCalculator
{
#[\Override]
public function calculateBaseScore(CvssObject $cvssObject): float
{
if (!$cvssObject instanceof Cvss23Object) {
Expand All @@ -33,6 +34,7 @@ private function calculateFImpact(Cvss23Object $cvssObject): float
return $cvssObject->impact === 0.0 ? 0.0 : 1.176;
}

#[\Override]
public function calculateTemporalScore(CvssObject $cvssObject): float
{
if (!$cvssObject instanceof Cvss23Object) {
Expand All @@ -42,6 +44,7 @@ public function calculateTemporalScore(CvssObject $cvssObject): float
return round($cvssObject->baseScore * $cvssObject->exploitability * $cvssObject->remediationLevel * $cvssObject->reportConfidence, 1);
}

#[\Override]
public function calculateEnvironmentalScore(CvssObject $cvssObject): float
{
if (!$cvssObject instanceof Cvss23Object) {
Expand Down
5 changes: 4 additions & 1 deletion src/Calculators/Cvss30Calculator.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
use Rootshell\Cvss\ValueObjects\Cvss23Object;
use Rootshell\Cvss\ValueObjects\CvssObject;

class Cvss30Calculator extends AbstractCvss3Calculator
final class Cvss30Calculator extends AbstractCvss3Calculator
{
#[\Override]
public function calculateModifiedImpactSubScore(CvssObject $cvssObject): float
{
if (!$cvssObject instanceof Cvss23Object) {
Expand All @@ -24,6 +25,7 @@ public function calculateModifiedImpactSubScore(CvssObject $cvssObject): float
);
}

#[\Override]
public function calculateModifiedImpact(CvssObject $cvssObject): float
{
if (!$cvssObject instanceof Cvss23Object) {
Expand All @@ -37,6 +39,7 @@ public function calculateModifiedImpact(CvssObject $cvssObject): float
return 7.52 * ($cvssObject->modifiedImpactSubScore - 0.029) - 3.25 * (($cvssObject->modifiedImpactSubScore - 0.02) ** 15);
}

#[\Override]
public function roundUp(float $number): float
{
return round(ceil($number * 10) / 10, 1);
Expand Down
5 changes: 4 additions & 1 deletion src/Calculators/Cvss31Calculator.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
use Rootshell\Cvss\ValueObjects\Cvss23Object;
use Rootshell\Cvss\ValueObjects\CvssObject;

class Cvss31Calculator extends AbstractCvss3Calculator
final class Cvss31Calculator extends AbstractCvss3Calculator
{
#[\Override]
public function calculateModifiedImpactSubScore(CvssObject $cvssObject): float
{
if (!$cvssObject instanceof Cvss23Object) {
Expand All @@ -24,6 +25,7 @@ public function calculateModifiedImpactSubScore(CvssObject $cvssObject): float
);
}

#[\Override]
public function calculateModifiedImpact(CvssObject $cvssObject): float
{
if (!$cvssObject instanceof Cvss23Object) {
Expand All @@ -37,6 +39,7 @@ public function calculateModifiedImpact(CvssObject $cvssObject): float
return 7.52 * ($cvssObject->modifiedImpactSubScore - 0.029) - 3.25 * (($cvssObject->modifiedImpactSubScore * 0.9731 - 0.02) ** 13);
}

#[\Override]
public function roundUp(float $number): float
{
$intInput = round($number * 100000);
Expand Down
5 changes: 4 additions & 1 deletion src/Calculators/Cvss40Calculator.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use Rootshell\Cvss\ValueObjects\Cvss4Object;
use Rootshell\Cvss\ValueObjects\CvssObject;

class Cvss40Calculator implements CvssCalculator
final class Cvss40Calculator implements CvssCalculator
{
private array $vectorLookup = [
'000000' => 10.0,
Expand Down Expand Up @@ -338,6 +338,7 @@ class Cvss40Calculator implements CvssCalculator
],
];

#[\Override]
public function calculateBaseScore(CvssObject $cvssObject): float
{
if (!$cvssObject instanceof Cvss4Object) {
Expand Down Expand Up @@ -395,11 +396,13 @@ public function calculateBaseScore(CvssObject $cvssObject): float
return round($finalValue, 1);
}

#[\Override]
public function calculateTemporalScore(CvssObject $cvssObject): float
{
return $this->calculateBaseScore($cvssObject);
}

#[\Override]
public function calculateEnvironmentalScore(CvssObject $cvssObject): float
{
return $this->calculateBaseScore($cvssObject);
Expand Down
10 changes: 5 additions & 5 deletions src/Cvss.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
use Rootshell\Cvss\ValueObjects\CvssObject;
use Rootshell\Cvss\ValueObjects\CvssResults;

class Cvss
final class Cvss
{
private const V4_VALIDATION_REGEX = '/^CVSS:4.0\/AV:[NALP]\/AC:[LH]\/AT:[NP]\/PR:[NLH]\/UI:[NPA]\/VC:[NLH]\/VI:[NLH]\/VA:[NLH]\/SC:[NLH]\/SI:[NLH]\/SA:[NLH]/';
private const V4_VALIDATION_REGEX_OPTIONALS = '/\/S:[^NP{1}|\s]|\/AU:[^YN{1}\s]|\/R:[^AIU{1}|\s]|\/V:[^CD|\s]|\/RE:[^LMH{1}|\s]|\/U:[^CGAR{1}|\s]|'
. '\/MAV:[^NALP{1}|\s]|\/MAC:[^LH{1}|\s]|\/MAT:[^NP{1}|\s]|\/MPR:[^NLH{1}|\s]|\/MUI:[^NPA{1}|\s]|'
. '\/MVC:[^HLN{1}|\s]|\/MVI:[^HLN{1}|\s]|\/MVA:[^HLN{1}|\s]|\/MSC:[^HLN{1}|\s]|\/MSI:[^SHLN{1}|\s]|\/MSA:[^SHLN{1}|\s]|'
. '\/CR:[^HML{1}|\s]|\/IR:[^HML{1}|\s]|\/AR:[^HML{1}|\s]|\/E:[^APU{1}|\s]/';
private const V4_VALIDATION_REGEX_OPTIONALS = '/\/S:[^NPX{1}|\s]|\/AU:[^YNX{1}\s]|\/R:[^AIUX{1}|\s]|\/V:[^CDX|\s]|\/RE:[^LMHX{1}|\s]|\/U:[^CGARX{1}|\s]|'
. '\/MAV:[^NALPX{1}|\s]|\/MAC:[^LHX{1}|\s]|\/MAT:[^NPX{1}|\s]|\/MPR:[^NLHX{1}|\s]|\/MUI:[^NPAX{1}|\s]|'
. '\/MVC:[^HLNX{1}|\s]|\/MVI:[^HLNX{1}|\s]|\/MVA:[^HLNX{1}|\s]|\/MSC:[^HLNX{1}|\s]|\/MSI:[^SHLNX{1}|\s]|\/MSA:[^SHLNX{1}|\s]|'
. '\/CR:[^HMLX{1}|\s]|\/IR:[^HMLX{1}|\s]|\/AR:[^HMLX{1}|\s]|\/E:[^APUX{1}|\s]/';
private const V3_VALIDATION_REGEX = '/^CVSS:(3.1|3.0)\/AV:[NALP]\/AC:[LH]\/PR:[NLH]\/UI:[NR]\/S:[UC]\/C:[NLH]\/I:[NLH]\/A:[NLH]/';
private const V2_VALIDATION_REGEX = '/AV:[LAN]\/AC:[HML]\/Au:[MSN]\/C:[NCP]\/I:[NCP]\/A:[NCP]/';

Expand Down
2 changes: 1 addition & 1 deletion src/Exceptions/CvssException.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use Exception;

class CvssException extends Exception
final class CvssException extends Exception
{
public static function invalidValue(): self
{
Expand Down
2 changes: 1 addition & 1 deletion src/Parsers/Cvss2Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use Rootshell\Cvss\Exceptions\CvssException;
use Rootshell\Cvss\ValueObjects\Cvss23Object;

class Cvss2Parser
final class Cvss2Parser
{
private const NETWORK = 'N';
private const ADJACENT = 'A';
Expand Down
2 changes: 1 addition & 1 deletion src/Parsers/Cvss31Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use Rootshell\Cvss\Exceptions\CvssException;
use Rootshell\Cvss\ValueObjects\Cvss23Object;

class Cvss31Parser
final class Cvss31Parser
{
private const NETWORK = 'N';
private const ADJACENT = 'A';
Expand Down
6 changes: 3 additions & 3 deletions src/Parsers/Cvss40Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use Rootshell\Cvss\ValueObjects\Cvss23Object;
use Rootshell\Cvss\ValueObjects\Cvss4Object;

class Cvss40Parser
final class Cvss40Parser
{
private const NETWORK = 'N';
private const ADJACENT = 'A';
Expand Down Expand Up @@ -326,15 +326,15 @@ private function findValueInVector(string $vector, string $section): string

private function findOptionalValueInVector(string $vector, string $section): ?string
{
$modifiedRegex = '/(?<=\/M' . $section . ':)(.*?)(?=\/|$)/';
$modifiedRegex = '/(?<=\/M' . $section . ':)([^X\/]*)(?=\/|$)/';

preg_match($modifiedRegex, '/' . $vector, $modifiedMatches);

if (isset($modifiedMatches[0])) {
return $modifiedMatches[0];
}

$regex = '/(?<=\/' . $section . ':)(.*?)(?=\/|$)/';
$regex = '/(?<=\/' . $section . ':)([^X\/]*)(?=\/|$)/';
preg_match($regex, '/' . $vector, $matches);

return $matches[0] ?? null;
Expand Down
2 changes: 1 addition & 1 deletion src/ValueObjects/Cvss23Object.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Rootshell\Cvss\ValueObjects;

class Cvss23Object extends CvssObject
final class Cvss23Object extends CvssObject
{
public const SCOPE_UNCHANGED = 'U';
public const SCOPE_CHANGED = 'C';
Expand Down
2 changes: 1 addition & 1 deletion src/ValueObjects/Cvss4Distance.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Rootshell\Cvss\ValueObjects;

class Cvss4Distance
final class Cvss4Distance
{
public function __construct(
public float $eqOne = 0.0,
Expand Down
2 changes: 1 addition & 1 deletion src/ValueObjects/Cvss4Object.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Rootshell\Cvss\ValueObjects;

class Cvss4Object extends CvssObject
final class Cvss4Object extends CvssObject
{
public function __construct(
public string $eq1,
Expand Down
2 changes: 1 addition & 1 deletion src/ValueObjects/CvssResults.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Rootshell\Cvss\ValueObjects;

class CvssResults
final class CvssResults
{
public function __construct(
public float $baseScore,
Expand Down
Loading