Skip to content
This repository was archived by the owner on Jul 23, 2023. It is now read-only.

Commit 9833678

Browse files
author
dwertent
committed
first commit
1 parent 7cf51a2 commit 9833678

12 files changed

+2185
-0
lines changed

.github/workflows/release.yaml

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Release-Tag
2+
on:
3+
push:
4+
branches: [ master ]
5+
jobs:
6+
build:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/checkout@v2
10+
11+
- name: Set up Go
12+
uses: actions/setup-go@v2
13+
with:
14+
go-version: 1.17
15+
16+
- name: Build
17+
run: go build -v ./...
18+
19+
- name: Test
20+
run: go test -v ./...
21+
22+
- name: Create a release
23+
id: create_release
24+
uses: actions/create-release@v1
25+
env:
26+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
27+
with:
28+
tag_name: v0.0.${{ github.run_number }}
29+
release_name: Release v0.0.${{ github.run_number }}
30+
draft: false
31+
prerelease: false

containerscan/containerscan_mock.go

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package containerscan
2+
3+
import (
4+
"bytes"
5+
"math/rand"
6+
"time"
7+
8+
"github.com/francoispqt/gojay"
9+
)
10+
11+
// GenerateContainerScanReportMock - generate a scan result
12+
func GenerateContainerScanReportMock() ScanResultReport {
13+
ds := ScanResultReport{
14+
WLID: "wlid://cluster-k8s-geriatrix-k8s-demo3/namespace-whisky-app/deployment-whisky4all-shipping",
15+
CustomerGUID: "1231bcb1-49ce-4a67-bdd3-5da7a393ae08",
16+
ImgTag: "dreg.armo.cloud:443/demoservice:v16",
17+
ImgHash: "docker-pullable://dreg.armo.cloud:443/demoservice@sha256:754f3cfca915a07ed10655a301dd7a8dc5526a06f9bd06e7c932f4d4108a8296",
18+
Timestamp: time.Now().UnixNano(),
19+
}
20+
21+
ds.Layers = make(LayersList, 0)
22+
layer := ScanResultLayer{}
23+
GenerateContainerScanLayer(&layer)
24+
ds.Layers = append(ds.Layers, layer)
25+
return ds
26+
}
27+
28+
// GenerateContainerScanReportMock - generate a scan result
29+
func GenerateContainerScanReportNoVulMock() ScanResultReport {
30+
ds := ScanResultReport{
31+
WLID: "wlid://cluster-k8s-geriatrix-k8s-demo3/namespace-whisky-app/deployment-whisky4all-shipping",
32+
CustomerGUID: "1231bcb1-49ce-4a67-bdd3-5da7a393ae08",
33+
ImgTag: "dreg.armo.cloud:443/demoservice:v16",
34+
ImgHash: "docker-pullable://dreg.armo.cloud:443/demoservice@sha256:754f3cfca915a07ed10655a301dd7a8dc5526a06f9bd06e7c932f4d4108a8296",
35+
Timestamp: time.Now().UnixNano(),
36+
ContainerName: "shipping",
37+
}
38+
39+
ds.Layers = make(LayersList, 0)
40+
layer := ScanResultLayer{LayerHash: "aaa"}
41+
ds.Layers = append(ds.Layers, layer)
42+
return ds
43+
}
44+
45+
var hash = []rune("abcdef0123456789")
46+
var nums = []rune("0123456789")
47+
48+
func randSeq(n int, bank []rune) string {
49+
rand.Seed(time.Now().UnixNano())
50+
51+
b := make([]rune, n)
52+
for i := range b {
53+
b[i] = bank[rand.Intn(len(bank))]
54+
}
55+
return string(b)
56+
}
57+
58+
// GenerateContainerScanLayer - generate a layer with random vuls
59+
func GenerateContainerScanLayer(layer *ScanResultLayer) {
60+
layer.LayerHash = randSeq(32, hash)
61+
layer.Vulnerabilities = make(VulnerabilitiesList, 0)
62+
layer.Packages = make(LinuxPkgs, 0)
63+
vuls := rand.Intn(10) + 1
64+
65+
for i := 0; i < vuls; i++ {
66+
v := Vulnerability{}
67+
GenerateVulnerability(&v)
68+
layer.Vulnerabilities = append(layer.Vulnerabilities, v)
69+
}
70+
71+
pkg := LinuxPackage{PackageName: "coreutils"}
72+
pkg.Files = make(PkgFiles, 0)
73+
pf := PackageFile{Filename: "aa"}
74+
pkg.Files = append(pkg.Files, pf)
75+
layer.Packages = append(layer.Packages, pkg)
76+
}
77+
78+
// GenerateVulnerability - generate a vul (just diff "cve"'s)
79+
func GenerateVulnerability(v *Vulnerability) error {
80+
baseVul := " { \"name\": \"CVE-2014-9471\", \"imageTag\": \"debian:8\", \"link\": \"https://security-tracker.debian.org/tracker/CVE-2014-9471\", \"description\": \"The parse_datetime function in GNU coreutils allows remote attackers to cause a denial of service (crash) or possibly execute arbitrary code via a crafted date string, as demonstrated by the sdf\", \"severity\": \"Low\", \"metadata\": { \"NVD\": { \"CVSSv2\": { \"Score\": 7.5, \"Vectors\": \"AV:N/AC:L/Au:N/C:P/I:P\" } } }, \"fixedIn\": [ { \"name\": \"coreutils\", \"imageTag\": \"debian:8\", \"version\": \"8.23-1\" } ] }"
81+
b := []byte(baseVul)
82+
r := bytes.NewReader(b)
83+
er := gojay.NewDecoder(r).DecodeObject(v)
84+
v.RelatedPackageName = "coreutils"
85+
v.Severity = HighSeverity
86+
v.Relevancy = Irelevant
87+
v.Name = "CVE-" + randSeq(4, nums) + "-" + randSeq(4, nums)
88+
return er
89+
90+
}

containerscan/containerscan_test.go

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package containerscan
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
"fmt"
7+
"strings"
8+
"testing"
9+
10+
"github.com/francoispqt/gojay"
11+
)
12+
13+
func TestDecodeScanWIthDangearousArtifacts(t *testing.T) {
14+
rhs := &ScanResultReport{}
15+
er := gojay.NewDecoder(strings.NewReader(nginxScanJSON)).DecodeObject(rhs)
16+
if er != nil {
17+
t.Errorf("decode failed due to: %v", er.Error())
18+
}
19+
sumObj := rhs.Summarize()
20+
if sumObj.Registry != "" {
21+
t.Errorf("sumObj.Registry = %v", sumObj.Registry)
22+
}
23+
if sumObj.VersionImage != "nginx:1.18.0" {
24+
t.Errorf("sumObj.VersionImage = %v", sumObj.Registry)
25+
}
26+
if sumObj.ImgTag != "nginx:1.18.0" {
27+
t.Errorf("sumObj.ImgTag = %v", sumObj.ImgTag)
28+
}
29+
if sumObj.Status != "Fail" {
30+
t.Errorf("sumObj.Status = %v", sumObj.Status)
31+
}
32+
if len(sumObj.ListOfDangerousArtifcats) != 3 {
33+
t.Errorf("sumObj.ListOfDangerousArtifcats = %v", sumObj.ListOfDangerousArtifcats)
34+
}
35+
}
36+
37+
func TestUnmarshalScanReport(t *testing.T) {
38+
ds := GenerateContainerScanReportMock()
39+
str1 := ds.AsFNVHash()
40+
rhs := &ScanResultReport{}
41+
42+
bolB, _ := json.Marshal(ds)
43+
r := bytes.NewReader(bolB)
44+
45+
er := gojay.NewDecoder(r).DecodeObject(rhs)
46+
if er != nil {
47+
t.Errorf("marshalling failed due to: %v", er.Error())
48+
}
49+
50+
if rhs.AsFNVHash() != str1 {
51+
t.Errorf("marshalling failed different values after marshal:\nOriginal:\n%v\nParsed:\n%v\n\n===\n", string(bolB), rhs)
52+
}
53+
}
54+
55+
func TestUnmarshalScanReport1(t *testing.T) {
56+
ds := Vulnerability{}
57+
if err := GenerateVulnerability(&ds); err != nil {
58+
t.Errorf("%v\n%v\n", ds, err)
59+
}
60+
}
61+
62+
func TestGetByPkgNameSuccess(t *testing.T) {
63+
ds := GenerateContainerScanReportMock()
64+
a := ds.Layers[0].GetFilesByPackage("coreutils")
65+
if a != nil {
66+
67+
fmt.Printf("%+v\n", *a)
68+
}
69+
70+
}
71+
72+
func TestGetByPkgNameMissing(t *testing.T) {
73+
ds := GenerateContainerScanReportMock()
74+
a := ds.Layers[0].GetFilesByPackage("s")
75+
if a != nil && len(*a) > 0 {
76+
t.Errorf("expected - no such package should be in that layer %v\n\n; found - %v", ds, a)
77+
}
78+
79+
}

containerscan/datastructures.go

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package containerscan
2+
3+
const (
4+
//defines Relevancy as enum-like
5+
Unknown = "Unknown"
6+
Relevant = "Relevant"
7+
Irelevant = "Irelevant"
8+
NoSP = "No signature profile to compare"
9+
10+
//Clair Severities
11+
UnknownSeverity = "Unknown"
12+
NegligibleSeverity = "Negligible"
13+
LowSeverity = "Low"
14+
MediumSeverity = "Medium"
15+
HighSeverity = "High"
16+
CriticalSeverity = "Critical"
17+
18+
ContainerScanRedisPrefix = "_containerscan"
19+
)
20+
21+
var KnownSeverities = map[string]bool{
22+
UnknownSeverity: true,
23+
NegligibleSeverity: true,
24+
LowSeverity: true,
25+
MediumSeverity: true,
26+
HighSeverity: true,
27+
CriticalSeverity: true,
28+
}
29+
30+
func CalculateFixed(Fixes []FixedIn) int {
31+
for _, fix := range Fixes {
32+
if fix.Version != "None" {
33+
return 1
34+
}
35+
}
36+
return 0
37+
}
+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package containerscan
2+
3+
import "strings"
4+
5+
func (layer *ScanResultLayer) GetFilesByPackage(pkgname string) (files *PkgFiles) {
6+
for _, pkg := range layer.Packages {
7+
if pkg.PackageName == pkgname {
8+
return &pkg.Files
9+
}
10+
}
11+
12+
return &PkgFiles{}
13+
}
14+
15+
func (layer *ScanResultLayer) GetPackagesNames() []string {
16+
pkgsNames := []string{}
17+
for _, pkg := range layer.Packages {
18+
pkgsNames = append(pkgsNames, pkg.PackageName)
19+
}
20+
return pkgsNames
21+
}
22+
23+
func (scanresult *ScanResultReport) Validate() bool {
24+
if scanresult.CustomerGUID == "" || (scanresult.ImgHash == "" && scanresult.ImgTag == "") || scanresult.Timestamp <= 0 {
25+
return false
26+
}
27+
28+
//TODO validate layers & vuls
29+
30+
return true
31+
}
32+
33+
func (v *Vulnerability) IsRCE() bool {
34+
desc := strings.ToLower(v.Description)
35+
36+
isRCE := strings.Contains(v.Description, "RCE")
37+
38+
return isRCE || strings.Contains(desc, "remote code execution") || strings.Contains(desc, "remote command execution") || strings.Contains(desc, "arbitrary code") || strings.Contains(desc, "code execution") || strings.Contains(desc, "code injection") || strings.Contains(desc, "command injection") || strings.Contains(desc, "inject arbitrary commands")
39+
}

0 commit comments

Comments
 (0)