0
Fork 0
mirror of https://github.com/project-zot/zot.git synced 2024-12-16 21:56:37 -05:00

Added image format validation to validate media type because squashfs image media type not supported for vulnerability scanning

This commit is contained in:
Shivam Mishra 2020-08-18 23:03:16 -07:00
parent 2cf2c16137
commit 72ae02ca4b
6 changed files with 134 additions and 0 deletions

View file

@ -34,4 +34,5 @@ var (
ErrConfigNotFound = errors.New("cli: config with the given name does not exist")
ErrNoURLProvided = errors.New("cli: no URL provided in argument or via config. see 'zot config -h'")
ErrIllegalConfigKey = errors.New("cli: given config key is not allowed")
ErrScanNotSupported = errors.New("search: scanning of image media type not supported")
)

1
go.mod
View file

@ -14,6 +14,7 @@ require (
github.com/go-chi/chi v4.0.2+incompatible // indirect
github.com/go-ldap/ldap/v3 v3.1.3
github.com/gofrs/uuid v3.2.0+incompatible
github.com/google/go-containerregistry v0.0.0-20200331213917-3d03ed9b1ca2
github.com/gorilla/handlers v1.4.2
github.com/gorilla/mux v1.7.4
github.com/json-iterator/go v1.1.9

View file

@ -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",

View file

@ -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",
],
)

View file

@ -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
}

View file

@ -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)