mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-19 23:28:20 +01:00
feat(vuln-severity): map negligible to none to match CVSS v3 ratings (#9885)
BREAKING CHANGE: the value negligible of severity in project metadata will change to none in the responses of project APIs Signed-off-by: He Weiwei <hweiwei@vmware.com>
This commit is contained in:
parent
8b740ace8a
commit
0c068d81f5
@ -4905,7 +4905,7 @@ definitions:
|
|||||||
description: 'Whether prevent the vulnerable images from running. The valid values are "true", "false".'
|
description: 'Whether prevent the vulnerable images from running. The valid values are "true", "false".'
|
||||||
severity:
|
severity:
|
||||||
type: string
|
type: string
|
||||||
description: 'If the vulnerability is high than severity defined here, the images can''t be pulled. The valid values are "negligible", "low", "medium", "high", "critical".'
|
description: 'If the vulnerability is high than severity defined here, the images can''t be pulled. The valid values are "none", "low", "medium", "high", "critical".'
|
||||||
auto_scan:
|
auto_scan:
|
||||||
type: string
|
type: string
|
||||||
description: 'Whether scan images automatically when pushing. The valid values are "true", "false".'
|
description: 'Whether scan images automatically when pushing. The valid values are "true", "false".'
|
||||||
|
@ -26,11 +26,6 @@ const (
|
|||||||
ProMetaSeverity = "severity"
|
ProMetaSeverity = "severity"
|
||||||
ProMetaAutoScan = "auto_scan"
|
ProMetaAutoScan = "auto_scan"
|
||||||
ProMetaReuseSysCVEWhitelist = "reuse_sys_cve_whitelist"
|
ProMetaReuseSysCVEWhitelist = "reuse_sys_cve_whitelist"
|
||||||
SeverityNegligible = "negligible"
|
|
||||||
SeverityLow = "low"
|
|
||||||
SeverityMedium = "medium"
|
|
||||||
SeverityHigh = "high"
|
|
||||||
SeverityCritical = "critical"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ProjectMetadata holds the metadata of a project.
|
// ProjectMetadata holds the metadata of a project.
|
||||||
|
@ -15,18 +15,18 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"github.com/goharbor/harbor/src/common/models"
|
"github.com/goharbor/harbor/src/common/models"
|
||||||
"github.com/goharbor/harbor/src/common/rbac"
|
"github.com/goharbor/harbor/src/common/rbac"
|
||||||
"github.com/goharbor/harbor/src/common/utils/log"
|
"github.com/goharbor/harbor/src/common/utils/log"
|
||||||
"github.com/goharbor/harbor/src/core/promgr/metamgr"
|
"github.com/goharbor/harbor/src/core/promgr/metamgr"
|
||||||
|
"github.com/goharbor/harbor/src/pkg/scan/vuln"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MetadataAPI ...
|
// MetadataAPI ...
|
||||||
@ -230,12 +230,12 @@ func validateProjectMetadata(metas map[string]string) (map[string]string, error)
|
|||||||
|
|
||||||
value, exist := metas[models.ProMetaSeverity]
|
value, exist := metas[models.ProMetaSeverity]
|
||||||
if exist {
|
if exist {
|
||||||
switch strings.ToLower(value) {
|
severity := vuln.ParseSeverityVersion3(strings.ToLower(value))
|
||||||
case models.SeverityHigh, models.SeverityMedium, models.SeverityLow, models.SeverityNegligible:
|
if severity == vuln.Unknown {
|
||||||
metas[models.ProMetaSeverity] = strings.ToLower(value)
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("invalid severity %s", value)
|
return nil, fmt.Errorf("invalid severity %s", value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
metas[models.ProMetaSeverity] = strings.ToLower(severity.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
return metas, nil
|
return metas, nil
|
||||||
|
@ -19,6 +19,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -32,6 +33,7 @@ import (
|
|||||||
errutil "github.com/goharbor/harbor/src/common/utils/error"
|
errutil "github.com/goharbor/harbor/src/common/utils/error"
|
||||||
"github.com/goharbor/harbor/src/common/utils/log"
|
"github.com/goharbor/harbor/src/common/utils/log"
|
||||||
"github.com/goharbor/harbor/src/core/config"
|
"github.com/goharbor/harbor/src/core/config"
|
||||||
|
"github.com/goharbor/harbor/src/pkg/scan/vuln"
|
||||||
"github.com/goharbor/harbor/src/pkg/types"
|
"github.com/goharbor/harbor/src/pkg/types"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
@ -458,6 +460,11 @@ func (p *ProjectAPI) List() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *ProjectAPI) populateProperties(project *models.Project) error {
|
func (p *ProjectAPI) populateProperties(project *models.Project) error {
|
||||||
|
// Transform the severity to severity of CVSS v3.0 Ratings
|
||||||
|
if severity, ok := project.GetMetadata(models.ProMetaSeverity); ok {
|
||||||
|
project.SetMetadata(models.ProMetaSeverity, strings.ToLower(vuln.ParseSeverityVersion3(severity).String()))
|
||||||
|
}
|
||||||
|
|
||||||
if p.SecurityCtx.IsAuthenticated() {
|
if p.SecurityCtx.IsAuthenticated() {
|
||||||
roles := p.SecurityCtx.GetProjectRoles(project.ProjectID)
|
roles := p.SecurityCtx.GetProjectRoles(project.ProjectID)
|
||||||
project.RoleList = roles
|
project.RoleList = roles
|
||||||
|
@ -389,7 +389,7 @@ func (pc PmsPolicyChecker) VulnerablePolicy(name string) (bool, vuln.Severity, m
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return project.VulPrevented(), getProjectVulnSeverity(project), wl
|
return project.VulPrevented(), vuln.ParseSeverityVersion3(project.Severity()), wl
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPMSPolicyChecker returns an instance of an pmsPolicyChecker
|
// NewPMSPolicyChecker returns an instance of an pmsPolicyChecker
|
||||||
@ -607,20 +607,3 @@ func FireQuotaEvent(req *http.Request, level int, msg string) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func getProjectVulnSeverity(project *models.Project) vuln.Severity {
|
|
||||||
mp := map[string]vuln.Severity{
|
|
||||||
models.SeverityNegligible: vuln.Negligible,
|
|
||||||
models.SeverityLow: vuln.Low,
|
|
||||||
models.SeverityMedium: vuln.Medium,
|
|
||||||
models.SeverityHigh: vuln.High,
|
|
||||||
models.SeverityCritical: vuln.Critical,
|
|
||||||
}
|
|
||||||
|
|
||||||
severity, ok := mp[project.Severity()]
|
|
||||||
if !ok {
|
|
||||||
return vuln.Unknown
|
|
||||||
}
|
|
||||||
|
|
||||||
return severity
|
|
||||||
}
|
|
||||||
|
@ -14,6 +14,10 @@
|
|||||||
|
|
||||||
package vuln
|
package vuln
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// None - only used to mark the overall severity of the scanned artifacts,
|
// None - only used to mark the overall severity of the scanned artifacts,
|
||||||
// means no vulnerabilities attached with the artifacts,
|
// means no vulnerabilities attached with the artifacts,
|
||||||
@ -62,3 +66,23 @@ func (s Severity) Code() int {
|
|||||||
return 99
|
return 99
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s Severity) String() string {
|
||||||
|
return string(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseSeverityVersion3 returns severity of CVSS v3.0 Ratings
|
||||||
|
func ParseSeverityVersion3(str string) Severity {
|
||||||
|
severity := Severity(strings.Title(str))
|
||||||
|
|
||||||
|
// There are `None`, `Low`, `Medium`, `High` and `Critical` severity rankings in CVSS v3.0 Ratings,
|
||||||
|
// so map `negligible` severity to `none`
|
||||||
|
switch severity {
|
||||||
|
case None, Low, Medium, High, Critical:
|
||||||
|
return severity
|
||||||
|
case Negligible:
|
||||||
|
return None
|
||||||
|
default:
|
||||||
|
return Unknown
|
||||||
|
}
|
||||||
|
}
|
||||||
|
52
src/pkg/scan/vuln/severity_test.go
Normal file
52
src/pkg/scan/vuln/severity_test.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// Copyright Project Harbor Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package vuln
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseSeverityVersion3(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
str string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want Severity
|
||||||
|
}{
|
||||||
|
{"none", args{"none"}, None},
|
||||||
|
{"None", args{"None"}, None},
|
||||||
|
{"negligible", args{"negligible"}, None},
|
||||||
|
{"Negligible", args{"Negligible"}, None},
|
||||||
|
{"low", args{"low"}, Low},
|
||||||
|
{"Low", args{"Low"}, Low},
|
||||||
|
{"medium", args{"medium"}, Medium},
|
||||||
|
{"Medium", args{"Medium"}, Medium},
|
||||||
|
{"high", args{"high"}, High},
|
||||||
|
{"High", args{"High"}, High},
|
||||||
|
{"critical", args{"critical"}, Critical},
|
||||||
|
{"Critical", args{"Critical"}, Critical},
|
||||||
|
{"invalid", args{"invalid"}, Unknown},
|
||||||
|
{"Invalid", args{"Invalid"}, Unknown},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := ParseSeverityVersion3(tt.args.str); got != tt.want {
|
||||||
|
t.Errorf("ParseSeverityVersion3() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -74,7 +74,7 @@ export class ProjectPolicyConfigComponent implements OnInit {
|
|||||||
{severity: 'high', severityLevel: 'VULNERABILITY.SEVERITY.HIGH'},
|
{severity: 'high', severityLevel: 'VULNERABILITY.SEVERITY.HIGH'},
|
||||||
{severity: 'medium', severityLevel: 'VULNERABILITY.SEVERITY.MEDIUM'},
|
{severity: 'medium', severityLevel: 'VULNERABILITY.SEVERITY.MEDIUM'},
|
||||||
{severity: 'low', severityLevel: 'VULNERABILITY.SEVERITY.LOW'},
|
{severity: 'low', severityLevel: 'VULNERABILITY.SEVERITY.LOW'},
|
||||||
{severity: 'negligible', severityLevel: 'VULNERABILITY.SEVERITY.NEGLIGIBLE'},
|
{severity: 'none', severityLevel: 'VULNERABILITY.SEVERITY.NONE'},
|
||||||
];
|
];
|
||||||
userSystemWhitelist: boolean = true;
|
userSystemWhitelist: boolean = true;
|
||||||
showAddModal: boolean = false;
|
showAddModal: boolean = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user