mirror of
https://github.com/project-zot/zot.git
synced 2026-06-16 04:17:55 +08:00
Added image format validation to validate media type because squashfs image media type not supported for vulnerability scanning
This commit is contained in:
@@ -10,6 +10,7 @@ go_library(
|
||||
importpath = "github.com/anuvu/zot/pkg/extensions/search",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//errors:go_default_library",
|
||||
"//pkg/extensions/search/cve:go_default_library",
|
||||
"//pkg/log:go_default_library",
|
||||
"//pkg/storage:go_default_library",
|
||||
|
||||
@@ -9,10 +9,15 @@ go_library(
|
||||
importpath = "github.com/anuvu/zot/pkg/extensions/search/cve",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//errors:go_default_library",
|
||||
"//pkg/log:go_default_library",
|
||||
"@com_github_aquasecurity_trivy//integration:go_default_library",
|
||||
"@com_github_aquasecurity_trivy//integration/config:go_default_library",
|
||||
"@com_github_aquasecurity_trivy//pkg/report:go_default_library",
|
||||
"@com_github_google_go_containerregistry//pkg/v1:go_default_library",
|
||||
"@com_github_google_go_containerregistry//pkg/v1/types:go_default_library",
|
||||
"@com_github_opencontainers_go_digest//:go_default_library",
|
||||
"@com_github_opencontainers_image_spec//specs-go/v1:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -1,10 +1,21 @@
|
||||
package cveinfo
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/anuvu/zot/errors"
|
||||
"github.com/anuvu/zot/pkg/log"
|
||||
integration "github.com/aquasecurity/trivy/integration"
|
||||
config "github.com/aquasecurity/trivy/integration/config"
|
||||
"github.com/aquasecurity/trivy/pkg/report"
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
"github.com/google/go-containerregistry/pkg/v1/types"
|
||||
godigest "github.com/opencontainers/go-digest"
|
||||
ispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
// UpdateCVEDb ...
|
||||
@@ -31,3 +42,91 @@ func NewTrivyConfig(dir string) (*config.Config, error) {
|
||||
func ScanImage(config *config.Config) (report.Results, error) {
|
||||
return integration.ScanTrivyImage(config.TrivyConfig)
|
||||
}
|
||||
|
||||
func (cveinfo CveInfo) IsValidImageFormat(imagePath string) (bool, error) {
|
||||
imageDir := getImageDir(imagePath)
|
||||
|
||||
if !dirExists(imageDir) {
|
||||
cveinfo.Log.Error().Msg("Image Directory not exists")
|
||||
|
||||
return false, errors.ErrRepoNotFound
|
||||
}
|
||||
|
||||
buf, err := ioutil.ReadFile(path.Join(imageDir, "index.json"))
|
||||
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
cveinfo.Log.Error().Err(err).Msg("Index.json does not exist")
|
||||
|
||||
return false, errors.ErrRepoNotFound
|
||||
}
|
||||
|
||||
cveinfo.Log.Error().Err(err).Msg("Unable to open index.json")
|
||||
|
||||
return false, errors.ErrRepoNotFound
|
||||
}
|
||||
|
||||
var index ispec.Index
|
||||
|
||||
var blobManifest v1.Manifest
|
||||
|
||||
var digest godigest.Digest
|
||||
|
||||
if err := json.Unmarshal(buf, &index); err != nil {
|
||||
cveinfo.Log.Error().Err(err).Msg("Unable to marshal index.json file")
|
||||
|
||||
return false, err
|
||||
}
|
||||
|
||||
for _, m := range index.Manifests {
|
||||
digest = m.Digest
|
||||
|
||||
blobBuf, err := ioutil.ReadFile(path.Join(imageDir, "blobs", digest.Algorithm().String(), digest.Encoded()))
|
||||
if err != nil {
|
||||
cveinfo.Log.Error().Err(err).Msg("Failed to read manifest file")
|
||||
|
||||
return false, err
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(blobBuf, &blobManifest); err != nil {
|
||||
cveinfo.Log.Error().Err(err).Msg("Invalid manifest json")
|
||||
|
||||
return false, err
|
||||
}
|
||||
|
||||
imageLayers := blobManifest.Layers
|
||||
|
||||
for _, imageLayer := range imageLayers {
|
||||
switch imageLayer.MediaType {
|
||||
case types.OCILayer, types.DockerLayer:
|
||||
return true, nil
|
||||
|
||||
default:
|
||||
cveinfo.Log.Debug().Msg("Image media type not supported for scanning")
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func dirExists(d string) bool {
|
||||
fi, err := os.Stat(d)
|
||||
if err != nil && os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
|
||||
return fi.IsDir()
|
||||
}
|
||||
|
||||
func getImageDir(imageName string) string {
|
||||
var imageDir string
|
||||
if strings.Contains(imageName, ":") {
|
||||
imageDir = strings.Split(imageName, ":")[0]
|
||||
} else {
|
||||
imageDir = imageName
|
||||
}
|
||||
|
||||
return imageDir
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/anuvu/zot/errors"
|
||||
"github.com/anuvu/zot/pkg/log"
|
||||
|
||||
cveinfo "github.com/anuvu/zot/pkg/extensions/search/cve"
|
||||
@@ -54,6 +55,19 @@ func (r *queryResolver) CVEListForImage(ctx context.Context, image string) (*CVE
|
||||
|
||||
r.cveInfo.Log.Info().Str("Scanning Image", image).Msg("")
|
||||
|
||||
isValidImage, err := r.cveInfo.IsValidImageFormat(r.cveInfo.CveTrivyConfig.TrivyConfig.Input)
|
||||
if !isValidImage {
|
||||
r.cveInfo.Log.Debug().Msg("Image media type not supported for scanning")
|
||||
|
||||
return &CVEResultForImage{}, errors.ErrScanNotSupported
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
r.cveInfo.Log.Error().Err(err).Msg("Error scanning image repository")
|
||||
|
||||
return &CVEResultForImage{}, err
|
||||
}
|
||||
|
||||
cveResults, err := cveinfo.ScanImage(r.cveInfo.CveTrivyConfig)
|
||||
if err != nil {
|
||||
r.cveInfo.Log.Error().Err(err).Msg("Error scanning image repository")
|
||||
@@ -143,6 +157,19 @@ func (r *queryResolver) ImageListForCve(ctx context.Context, id string) ([]*ImgR
|
||||
for _, repo := range repoList {
|
||||
r.cveInfo.Log.Info().Str("Extracting list of tags available in image", repo).Msg("")
|
||||
|
||||
isValidImage, err := r.cveInfo.IsValidImageFormat(path.Join(r.dir, repo))
|
||||
if !isValidImage {
|
||||
r.cveInfo.Log.Debug().Str("Image media type not supported for scanning", repo)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
r.cveInfo.Log.Error().Err(err).Str("Error reading image media type", repo)
|
||||
|
||||
return cveResult, err
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
r.cveInfo.Log.Error().Err(err).Str("Error reading image media type", repo)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user