mirror of https://github.com/goharbor/harbor.git
Add status field to the API on secyurityHub (#22182)
This commit makes change to the API GET /api/v2.0/vul to make it include "status" of CVEs in the response. It also makes update in the UI to add the "Status" column to the data grids in security hub and artifact details page. Signed-off-by: Daniel Jiang <daniel.jiang@broadcom.com>
This commit is contained in:
parent
c83f2d114f
commit
440f53ebbc
|
@ -6144,6 +6144,7 @@ paths:
|
||||||
cve_id(exact match)
|
cve_id(exact match)
|
||||||
cvss_score_v3(range condition)
|
cvss_score_v3(range condition)
|
||||||
severity(exact match)
|
severity(exact match)
|
||||||
|
status(exact match)
|
||||||
repository_name(exact match)
|
repository_name(exact match)
|
||||||
project_id(exact match)
|
project_id(exact match)
|
||||||
package(exact match)
|
package(exact match)
|
||||||
|
@ -10072,6 +10073,9 @@ definitions:
|
||||||
severity:
|
severity:
|
||||||
type: string
|
type: string
|
||||||
description: the severity of the vulnerability
|
description: the severity of the vulnerability
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
description: the status of the vulnerability, example "fixed", "won't fix"
|
||||||
cvss_v3_score:
|
cvss_v3_score:
|
||||||
type: number
|
type: number
|
||||||
format: float
|
format: float
|
||||||
|
|
|
@ -83,7 +83,7 @@ ORDER BY vr.cvss_score_v3 DESC, severity_level DESC
|
||||||
LIMIT 5`
|
LIMIT 5`
|
||||||
|
|
||||||
// sql to query vulnerabilities
|
// sql to query vulnerabilities
|
||||||
vulnerabilitySQL = `select vr.cve_id, vr.cvss_score_v3, vr.package, a.repository_name, a.id artifact_id, a.digest, vr.package, vr.package_version, vr.severity, vr.fixed_version, vr.description, vr.urls, a.project_id
|
vulnerabilitySQL = `select vr.cve_id, vr.cvss_score_v3, vr.package, a.repository_name, a.id artifact_id, a.digest, vr.package, vr.package_version, vr.severity, vr.status, vr.fixed_version, vr.description, vr.urls, a.project_id
|
||||||
from artifact a,
|
from artifact a,
|
||||||
scan_report s,
|
scan_report s,
|
||||||
report_vulnerability_record rvr,
|
report_vulnerability_record rvr,
|
||||||
|
@ -112,6 +112,7 @@ type filterMetaData struct {
|
||||||
var filterMap = map[string]*filterMetaData{
|
var filterMap = map[string]*filterMetaData{
|
||||||
"cve_id": &filterMetaData{DataType: stringType},
|
"cve_id": &filterMetaData{DataType: stringType},
|
||||||
"severity": &filterMetaData{DataType: stringType},
|
"severity": &filterMetaData{DataType: stringType},
|
||||||
|
"status": &filterMetaData{DataType: stringType},
|
||||||
"cvss_score_v3": &filterMetaData{DataType: rangeType, FilterFunc: rangeFilter},
|
"cvss_score_v3": &filterMetaData{DataType: rangeType, FilterFunc: rangeFilter},
|
||||||
"project_id": &filterMetaData{DataType: stringType},
|
"project_id": &filterMetaData{DataType: stringType},
|
||||||
"repository_name": &filterMetaData{DataType: stringType},
|
"repository_name": &filterMetaData{DataType: stringType},
|
||||||
|
|
|
@ -28,6 +28,9 @@
|
||||||
<clr-dg-column>{{
|
<clr-dg-column>{{
|
||||||
'VULNERABILITY.GRID.COLUMN_SEVERITY' | translate
|
'VULNERABILITY.GRID.COLUMN_SEVERITY' | translate
|
||||||
}}</clr-dg-column>
|
}}</clr-dg-column>
|
||||||
|
<clr-dg-column>{{
|
||||||
|
'VULNERABILITY.GRID.COLUMN_STATUS' | translate
|
||||||
|
}}</clr-dg-column>
|
||||||
<clr-dg-column class="min-width">{{
|
<clr-dg-column class="min-width">{{
|
||||||
'VULNERABILITY.GRID.COLUMN_PACKAGE' | translate
|
'VULNERABILITY.GRID.COLUMN_PACKAGE' | translate
|
||||||
}}</clr-dg-column>
|
}}</clr-dg-column>
|
||||||
|
@ -117,6 +120,7 @@
|
||||||
severityText(c.severity) | translate
|
severityText(c.severity) | translate
|
||||||
}}</span>
|
}}</span>
|
||||||
</clr-dg-cell>
|
</clr-dg-cell>
|
||||||
|
<clr-dg-cell>{{ c.status }}</clr-dg-cell>
|
||||||
<clr-dg-cell class="ellipsis" title="{{ c.package }}">{{
|
<clr-dg-cell class="ellipsis" title="{{ c.package }}">{{
|
||||||
c.package
|
c.package
|
||||||
}}</clr-dg-cell>
|
}}</clr-dg-cell>
|
||||||
|
|
|
@ -30,6 +30,7 @@ export enum OptionType {
|
||||||
CVE_ID = 'cve_id',
|
CVE_ID = 'cve_id',
|
||||||
SEVERITY = 'severity',
|
SEVERITY = 'severity',
|
||||||
CVSS3 = 'cvss_score_v3',
|
CVSS3 = 'cvss_score_v3',
|
||||||
|
STATUS = 'status',
|
||||||
REPO = 'repository_name',
|
REPO = 'repository_name',
|
||||||
PACKAGE = 'package',
|
PACKAGE = 'package',
|
||||||
TAG = 'tag',
|
TAG = 'tag',
|
||||||
|
@ -42,6 +43,7 @@ export const OptionType_I18n_Map = {
|
||||||
[OptionType.CVE_ID]: 'SECURITY_HUB.CVE_ID',
|
[OptionType.CVE_ID]: 'SECURITY_HUB.CVE_ID',
|
||||||
[OptionType.SEVERITY]: 'VULNERABILITY.GRID.COLUMN_SEVERITY',
|
[OptionType.SEVERITY]: 'VULNERABILITY.GRID.COLUMN_SEVERITY',
|
||||||
[OptionType.CVSS3]: 'VULNERABILITY.GRID.CVSS3',
|
[OptionType.CVSS3]: 'VULNERABILITY.GRID.CVSS3',
|
||||||
|
[OptionType.STATUS]: 'VULNERABILITY.GRID.COLUMN_STATUS',
|
||||||
[OptionType.REPO]: 'SECURITY_HUB.REPO_NAME',
|
[OptionType.REPO]: 'SECURITY_HUB.REPO_NAME',
|
||||||
[OptionType.PACKAGE]: 'VULNERABILITY.GRID.COLUMN_PACKAGE',
|
[OptionType.PACKAGE]: 'VULNERABILITY.GRID.COLUMN_PACKAGE',
|
||||||
[OptionType.TAG]: 'REPLICATION.TAG',
|
[OptionType.TAG]: 'REPLICATION.TAG',
|
||||||
|
|
|
@ -33,6 +33,7 @@ export class VulnerabilityFilterComponent {
|
||||||
OptionType.CVE_ID,
|
OptionType.CVE_ID,
|
||||||
OptionType.SEVERITY,
|
OptionType.SEVERITY,
|
||||||
OptionType.CVSS3,
|
OptionType.CVSS3,
|
||||||
|
OptionType.STATUS,
|
||||||
OptionType.PROJECT_ID,
|
OptionType.PROJECT_ID,
|
||||||
OptionType.REPO,
|
OptionType.REPO,
|
||||||
OptionType.PACKAGE,
|
OptionType.PACKAGE,
|
||||||
|
@ -43,6 +44,7 @@ export class VulnerabilityFilterComponent {
|
||||||
OptionType.CVE_ID,
|
OptionType.CVE_ID,
|
||||||
OptionType.SEVERITY,
|
OptionType.SEVERITY,
|
||||||
OptionType.CVSS3,
|
OptionType.CVSS3,
|
||||||
|
OptionType.STATUS,
|
||||||
OptionType.PROJECT_ID,
|
OptionType.PROJECT_ID,
|
||||||
OptionType.REPO,
|
OptionType.REPO,
|
||||||
OptionType.PACKAGE,
|
OptionType.PACKAGE,
|
||||||
|
|
|
@ -64,6 +64,9 @@
|
||||||
<clr-dg-column [clrDgSortBy]="cvssSort">{{
|
<clr-dg-column [clrDgSortBy]="cvssSort">{{
|
||||||
'VULNERABILITY.GRID.CVSS3' | translate
|
'VULNERABILITY.GRID.CVSS3' | translate
|
||||||
}}</clr-dg-column>
|
}}</clr-dg-column>
|
||||||
|
<clr-dg-column>{{
|
||||||
|
'VULNERABILITY.GRID.COLUMN_STATUS' | translate
|
||||||
|
}}</clr-dg-column>
|
||||||
<clr-dg-column [clrDgField]="'package'">{{
|
<clr-dg-column [clrDgField]="'package'">{{
|
||||||
'VULNERABILITY.GRID.COLUMN_PACKAGE' | translate
|
'VULNERABILITY.GRID.COLUMN_PACKAGE' | translate
|
||||||
}}</clr-dg-column>
|
}}</clr-dg-column>
|
||||||
|
@ -154,6 +157,7 @@
|
||||||
<div class="clr-col">{{ item?.value?.V3Score }}</div>
|
<div class="clr-col">{{ item?.value?.V3Score }}</div>
|
||||||
</div>
|
</div>
|
||||||
</clr-dg-cell>
|
</clr-dg-cell>
|
||||||
|
<clr-dg-cell>{{ res.status }}</clr-dg-cell>
|
||||||
<clr-dg-cell>{{ res.package }}</clr-dg-cell>
|
<clr-dg-cell>{{ res.package }}</clr-dg-cell>
|
||||||
<clr-dg-cell>{{ res.version }}</clr-dg-cell>
|
<clr-dg-cell>{{ res.version }}</clr-dg-cell>
|
||||||
<clr-dg-cell>
|
<clr-dg-cell>
|
||||||
|
|
|
@ -43,6 +43,7 @@ describe('ArtifactVulnerabilitiesComponent', () => {
|
||||||
{
|
{
|
||||||
id: '123',
|
id: '123',
|
||||||
severity: 'low',
|
severity: 'low',
|
||||||
|
status: 'fixed',
|
||||||
package: 'test',
|
package: 'test',
|
||||||
version: '1.0',
|
version: '1.0',
|
||||||
links: ['testLink'],
|
links: ['testLink'],
|
||||||
|
@ -52,6 +53,7 @@ describe('ArtifactVulnerabilitiesComponent', () => {
|
||||||
{
|
{
|
||||||
id: '456',
|
id: '456',
|
||||||
severity: 'high',
|
severity: 'high',
|
||||||
|
status: 'fixed',
|
||||||
package: 'test',
|
package: 'test',
|
||||||
version: '1.0',
|
version: '1.0',
|
||||||
links: ['testLink'],
|
links: ['testLink'],
|
||||||
|
@ -163,7 +165,7 @@ describe('ArtifactVulnerabilitiesComponent', () => {
|
||||||
await fixture.whenStable();
|
await fixture.whenStable();
|
||||||
const cols = fixture.nativeElement.querySelectorAll('clr-dg-column');
|
const cols = fixture.nativeElement.querySelectorAll('clr-dg-column');
|
||||||
expect(cols).toBeTruthy();
|
expect(cols).toBeTruthy();
|
||||||
expect(cols.length).toEqual(7);
|
expect(cols.length).toEqual(8);
|
||||||
const firstRow = fixture.nativeElement.querySelector('clr-dg-row');
|
const firstRow = fixture.nativeElement.querySelector('clr-dg-row');
|
||||||
const cells = firstRow.querySelectorAll('clr-dg-cell');
|
const cells = firstRow.querySelectorAll('clr-dg-cell');
|
||||||
expect(cells[cells.length - 1].innerText).toEqual('TAG_RETENTION.YES');
|
expect(cells[cells.length - 1].innerText).toEqual('TAG_RETENTION.YES');
|
||||||
|
|
|
@ -197,6 +197,7 @@ export enum VulnerabilitySeverity {
|
||||||
export interface VulnerabilityBase {
|
export interface VulnerabilityBase {
|
||||||
id: string;
|
id: string;
|
||||||
severity: string;
|
severity: string;
|
||||||
|
status: string;
|
||||||
package: string;
|
package: string;
|
||||||
version: string;
|
version: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1106,6 +1106,7 @@
|
||||||
"PLACEHOLDER": "We couldn't find any scanning results!",
|
"PLACEHOLDER": "We couldn't find any scanning results!",
|
||||||
"COLUMN_ID": "Vulnerability",
|
"COLUMN_ID": "Vulnerability",
|
||||||
"COLUMN_SEVERITY": "Severity",
|
"COLUMN_SEVERITY": "Severity",
|
||||||
|
"COLUMN_STATUS": "Status",
|
||||||
"COLUMN_PACKAGE": "Package",
|
"COLUMN_PACKAGE": "Package",
|
||||||
"COLUMN_PACKAGES": "Packages",
|
"COLUMN_PACKAGES": "Packages",
|
||||||
"COLUMN_VERSION": "Current version",
|
"COLUMN_VERSION": "Current version",
|
||||||
|
|
|
@ -136,6 +136,7 @@ func toVulnerabilities(vuls []*secHubModel.VulnerabilityItem) []*models.Vulnerab
|
||||||
Digest: item.Digest,
|
Digest: item.Digest,
|
||||||
CVEID: item.CVEID,
|
CVEID: item.CVEID,
|
||||||
Severity: item.Severity,
|
Severity: item.Severity,
|
||||||
|
Status: item.Status,
|
||||||
Package: item.Package,
|
Package: item.Package,
|
||||||
Tags: item.Tags,
|
Tags: item.Tags,
|
||||||
Version: item.PackageVersion,
|
Version: item.PackageVersion,
|
||||||
|
|
Loading…
Reference in New Issue