Skip to content

Commit

Permalink
Audit: add severity to plain and table output (composer#11702)
Browse files Browse the repository at this point in the history
  • Loading branch information
glaubinix authored and theoboldalex committed Jan 10, 2024
1 parent a2e84f0 commit 3fe481f
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 5 deletions.
12 changes: 12 additions & 0 deletions src/Composer/Advisory/Auditor.php
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ private function outputAdvisoriesTable(ConsoleIO $io, array $advisories): void
foreach ($packageAdvisories as $advisory) {
$headers = [
'Package',
'Severity',
'CVE',
'Title',
'URL',
Expand All @@ -255,6 +256,7 @@ private function outputAdvisoriesTable(ConsoleIO $io, array $advisories): void
];
$row = [
$advisory->packageName,
$this->getSeverity($advisory),
$this->getCVE($advisory),
$advisory->title,
$this->getURL($advisory),
Expand Down Expand Up @@ -289,6 +291,7 @@ private function outputAdvisoriesPlain(IOInterface $io, array $advisories): void
$error[] = '--------';
}
$error[] = "Package: ".$advisory->packageName;
$error[] = "Severity: ".$this->getSeverity($advisory);
$error[] = "CVE: ".$this->getCVE($advisory);
$error[] = "Title: ".OutputFormatter::escape($advisory->title);
$error[] = "URL: ".$this->getURL($advisory);
Expand Down Expand Up @@ -350,6 +353,15 @@ private function getPackageNameWithLink(PackageInterface $package): string
return $packageUrl !== null ? '<href=' . OutputFormatter::escape($packageUrl) . '>' . $package->getPrettyName() . '</>' : $package->getPrettyName();
}

private function getSeverity(SecurityAdvisory $advisory): string
{
if ($advisory->severity === null) {
return '';
}

return $advisory->severity;
}

private function getCVE(SecurityAdvisory $advisory): string
{
if ($advisory->cve === null) {
Expand Down
4 changes: 2 additions & 2 deletions src/Composer/Advisory/IgnoredSecurityAdvisory.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ class IgnoredSecurityAdvisory extends SecurityAdvisory
/**
* @param non-empty-array<array{name: string, remoteId: string}> $sources
*/
public function __construct(string $packageName, string $advisoryId, ConstraintInterface $affectedVersions, string $title, array $sources, DateTimeImmutable $reportedAt, ?string $cve = null, ?string $link = null, ?string $ignoreReason = null)
public function __construct(string $packageName, string $advisoryId, ConstraintInterface $affectedVersions, string $title, array $sources, DateTimeImmutable $reportedAt, ?string $cve = null, ?string $link = null, ?string $ignoreReason = null, ?string $severity = null)
{
parent::__construct($packageName, $advisoryId, $affectedVersions, $title, $sources, $reportedAt, $cve, $link);
parent::__construct($packageName, $advisoryId, $affectedVersions, $title, $sources, $reportedAt, $cve, $link, $severity);

$this->ignoreReason = $ignoreReason;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Composer/Advisory/PartialSecurityAdvisory.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public static function create(string $packageName, array $data, VersionParser $p
{
$constraint = $parser->parseConstraints($data['affectedVersions']);
if (isset($data['title'], $data['sources'], $data['reportedAt'])) {
return new SecurityAdvisory($packageName, $data['advisoryId'], $constraint, $data['title'], $data['sources'], new \DateTimeImmutable($data['reportedAt'], new \DateTimeZone('UTC')), $data['cve'] ?? null, $data['link'] ?? null);
return new SecurityAdvisory($packageName, $data['advisoryId'], $constraint, $data['title'], $data['sources'], new \DateTimeImmutable($data['reportedAt'], new \DateTimeZone('UTC')), $data['cve'] ?? null, $data['link'] ?? null, $data['severity'] ?? null);
}

return new self($packageName, $data['advisoryId'], $constraint);
Expand Down
12 changes: 10 additions & 2 deletions src/Composer/Advisory/SecurityAdvisory.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,16 @@ class SecurityAdvisory extends PartialSecurityAdvisory
*/
public $sources;

/**
* @var string|null
* @readonly
*/
public $severity;

/**
* @param non-empty-array<array{name: string, remoteId: string}> $sources
*/
public function __construct(string $packageName, string $advisoryId, ConstraintInterface $affectedVersions, string $title, array $sources, DateTimeImmutable $reportedAt, ?string $cve = null, ?string $link = null)
public function __construct(string $packageName, string $advisoryId, ConstraintInterface $affectedVersions, string $title, array $sources, DateTimeImmutable $reportedAt, ?string $cve = null, ?string $link = null, ?string $severity = null)
{
parent::__construct($packageName, $advisoryId, $affectedVersions);

Expand All @@ -59,6 +65,7 @@ public function __construct(string $packageName, string $advisoryId, ConstraintI
$this->reportedAt = $reportedAt;
$this->cve = $cve;
$this->link = $link;
$this->severity = $severity;
}

/**
Expand All @@ -75,7 +82,8 @@ public function toIgnoredAdvisory(?string $ignoreReason): IgnoredSecurityAdvisor
$this->reportedAt,
$this->cve,
$this->link,
$ignoreReason
$ignoreReason,
$this->severity
);
}

Expand Down
20 changes: 20 additions & 0 deletions tests/Composer/Test/Advisory/AuditorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,15 @@ public static function auditProvider()
'expected' => 1,
'output' => '<warning>Found 2 security vulnerability advisories affecting 1 package:</warning>
Package: vendor1/package1
Severity: high
CVE: CVE3
Title: advisory4
URL: https://advisory.example.com/advisory4
Affected versions: >=8,<8.2.2|>=1,<2.5.6
Reported at: 2022-05-25T13:21:00+00:00
--------
Package: vendor1/package1
Severity: medium
CVE: '.'
Title: advisory5
URL: https://advisory.example.com/advisory5
Expand Down Expand Up @@ -169,6 +171,7 @@ public function ignoredIdsProvider(): \Generator {
[
['text' => 'Found 1 ignored security vulnerability advisory affecting 1 package:'],
['text' => 'Package: vendor1/package1'],
['text' => 'Severity: medium'],
['text' => 'CVE: CVE1'],
['text' => 'Title: advisory1'],
['text' => 'URL: https://advisory.example.com/advisory1'],
Expand All @@ -185,6 +188,7 @@ public function ignoredIdsProvider(): \Generator {
[
['text' => 'Found 1 ignored security vulnerability advisory affecting 1 package:'],
['text' => 'Package: vendor1/package1'],
['text' => 'Severity: medium'],
['text' => 'CVE: CVE1'],
['text' => 'Title: advisory1'],
['text' => 'URL: https://advisory.example.com/advisory1'],
Expand All @@ -202,6 +206,7 @@ public function ignoredIdsProvider(): \Generator {
[
['text' => 'Found 1 ignored security vulnerability advisory affecting 1 package:'],
['text' => 'Package: vendor1/package2'],
['text' => 'Severity: medium'],
['text' => 'CVE: '],
['text' => 'Title: advisory2'],
['text' => 'URL: https://advisory.example.com/advisory2'],
Expand All @@ -218,6 +223,7 @@ public function ignoredIdsProvider(): \Generator {
[
['text' => 'Found 1 ignored security vulnerability advisory affecting 1 package:'],
['text' => 'Package: vendorx/packagex'],
['text' => 'Severity: medium'],
['text' => 'CVE: CVE5'],
['text' => 'Title: advisory17'],
['text' => 'URL: https://advisory.example.com/advisory17'],
Expand All @@ -234,6 +240,7 @@ public function ignoredIdsProvider(): \Generator {
[
['text' => 'Found 1 security vulnerability advisory affecting 1 package:'],
['text' => 'Package: vendor1/package1'],
['text' => 'Severity: medium'],
['text' => 'CVE: CVE1'],
['text' => 'Title: advisory1'],
['text' => 'URL: https://advisory.example.com/advisory1'],
Expand All @@ -254,6 +261,7 @@ public function ignoredIdsProvider(): \Generator {
[
['text' => 'Found 3 ignored security vulnerability advisories affecting 2 packages:'],
['text' => 'Package: vendor2/package1'],
['text' => 'Severity: medium'],
['text' => 'CVE: CVE2'],
['text' => 'Title: advisory3'],
['text' => 'URL: https://advisory.example.com/advisory3'],
Expand All @@ -262,6 +270,7 @@ public function ignoredIdsProvider(): \Generator {
['text' => 'Ignore reason: None specified'],
['text' => '--------'],
['text' => 'Package: vendor2/package1'],
['text' => 'Severity: medium'],
['text' => 'CVE: CVE4'],
['text' => 'Title: advisory6'],
['text' => 'URL: https://advisory.example.com/advisory6'],
Expand All @@ -270,6 +279,7 @@ public function ignoredIdsProvider(): \Generator {
['text' => 'Ignore reason: None specified'],
['text' => '--------'],
['text' => 'Package: vendorx/packagex'],
['text' => 'Severity: medium'],
['text' => 'CVE: CVE5'],
['text' => 'Title: advisory17'],
['text' => 'URL: https://advisory.example.com/advisory17'],
Expand All @@ -278,6 +288,7 @@ public function ignoredIdsProvider(): \Generator {
['text' => 'Ignore reason: None specified'],
['text' => 'Found 1 security vulnerability advisory affecting 1 package:'],
['text' => 'Package: vendor3/package1'],
['text' => 'Severity: medium'],
['text' => 'CVE: CVE5'],
['text' => 'Title: advisory7'],
['text' => 'URL: https://advisory.example.com/advisory7'],
Expand Down Expand Up @@ -380,6 +391,7 @@ public static function getMockAdvisories(): array
],
'reportedAt' => '2022-05-25 13:21:00',
'composerRepository' => 'https://packagist.org',
'severity' => 'medium',
],
[
'advisoryId' => 'ID4',
Expand All @@ -396,6 +408,7 @@ public static function getMockAdvisories(): array
],
'reportedAt' => '2022-05-25 13:21:00',
'composerRepository' => 'https://packagist.org',
'severity' => 'high',
],
[
'advisoryId' => 'ID5',
Expand All @@ -412,6 +425,7 @@ public static function getMockAdvisories(): array
],
'reportedAt' => '2022-05-25 13:21:00',
'composerRepository' => 'https://packagist.org',
'severity' => 'medium',
],
],
'vendor1/package2' => [
Expand All @@ -430,6 +444,7 @@ public static function getMockAdvisories(): array
],
'reportedAt' => '2022-05-25 13:21:00',
'composerRepository' => 'https://packagist.org',
'severity' => 'medium',
],
],
'vendorx/packagex' => [
Expand All @@ -448,6 +463,7 @@ public static function getMockAdvisories(): array
],
'reportedAt' => '2015-05-25 13:21:00',
'composerRepository' => 'https://packagist.org',
'severity' => 'medium',
],
],
'vendor2/package1' => [
Expand All @@ -466,6 +482,7 @@ public static function getMockAdvisories(): array
],
'reportedAt' => '2022-05-25 13:21:00',
'composerRepository' => 'https://packagist.org',
'severity' => 'medium',
],
[
'advisoryId' => 'ID6',
Expand All @@ -482,6 +499,7 @@ public static function getMockAdvisories(): array
],
'reportedAt' => '2015-05-25 13:21:00',
'composerRepository' => 'https://packagist.org',
'severity' => 'medium',
],
],
'vendory/packagey' => [
Expand All @@ -500,6 +518,7 @@ public static function getMockAdvisories(): array
],
'reportedAt' => '2015-05-25 13:21:00',
'composerRepository' => 'https://packagist.org',
'severity' => 'medium',
],
],
'vendor3/package1' => [
Expand All @@ -518,6 +537,7 @@ public static function getMockAdvisories(): array
],
'reportedAt' => '2015-05-25 13:21:00',
'composerRepository' => 'https://packagist.org',
'severity' => 'medium',
],
],
];
Expand Down

0 comments on commit 3fe481f

Please sign in to comment.