From ec891368e9a251190e6e493ecaa499ad0b6c808b Mon Sep 17 00:00:00 2001 From: Matthias Simonis Date: Thu, 29 Feb 2024 11:17:34 +0100 Subject: [PATCH] Add/virus scan (#374) * implement git-diff scan This tool is meant for pull requests. It compares the current branch to a given target branch. The resulting file list will than be scaned via vaas. * adds a push of the git-scan image when releasing go this image will be the base for implementing the github action and the gitlab template --- .github/workflows/ci-golang.yaml | 10 +++ golang/vaas/cmd/git-scan/main.go | 111 +++++++++++++++++++++++++++++++ golang/vaas/git-scan.Dockerfile | 13 ++++ golang/vaas/go.mod | 9 +-- golang/vaas/go.sum | 10 ++- 5 files changed, 147 insertions(+), 6 deletions(-) create mode 100644 golang/vaas/cmd/git-scan/main.go create mode 100644 golang/vaas/git-scan.Dockerfile diff --git a/.github/workflows/ci-golang.yaml b/.github/workflows/ci-golang.yaml index bff7bd8a..70814aae 100644 --- a/.github/workflows/ci-golang.yaml +++ b/.github/workflows/ci-golang.yaml @@ -81,3 +81,13 @@ jobs: with: webhook_url: ${{ secrets.MSTEAMS_WEBHOOK }} overwrite: "{title: `Failed workflow on for VaaS-SDK ${workflow}`, sections: [{activityTitle: 'build failed', activitySubtitle: `Failed workflow on for VaaS-SDK ${workflow}`, activityImage: 'https://adaptivecards.io/content/cats/3.png'}], themeColor: '#ff0000'}" + + - name: push git-scan + if: startsWith(github.ref, 'refs/tags/go') + working-directory: golang/vaas/ + run: | + docker build -t ghrc.io/gdatasoftwareag/vaas/git-scan:${GITHUB_REF#refs/tags/go} -f git-scan.Dockerfile . + docker tag ghrc.io/gdatasoftwareag/vaas/git-scan:${GITHUB_REF#refs/tags/go} ghrc.io/gdatasoftwareag/vaas/git-scan:latest + docker login ghcr.io -u ${{ secrets.VAAS_GHCR_USER }} -p ${{ secrets.VAAS_GHCR_TOKEN }} + docker push ghrc.io/gdatasoftwareag/vaas/git-scan:${GITHUB_REF#refs/tags/go} + docker push ghrc.io/gdatasoftwareag/vaas/git-scan:latest diff --git a/golang/vaas/cmd/git-scan/main.go b/golang/vaas/cmd/git-scan/main.go new file mode 100644 index 00000000..2c003385 --- /dev/null +++ b/golang/vaas/cmd/git-scan/main.go @@ -0,0 +1,111 @@ +package main + +import ( + "context" + "log" + "os" + "os/exec" + "path/filepath" + "strings" + + "github.com/GDATASoftwareAG/vaas/golang/vaas/pkg/authenticator" + "github.com/GDATASoftwareAG/vaas/golang/vaas/pkg/messages" + "github.com/GDATASoftwareAG/vaas/golang/vaas/pkg/options" + "github.com/GDATASoftwareAG/vaas/golang/vaas/pkg/vaas" +) + +func main() { + if len(os.Args) < 3 { + log.Fatal("need 2 parameter: path, targetBranch") + } + path := os.Args[1] + if path == "" { + log.Fatal("no path set") + } + + targetBranch := os.Args[2] + if targetBranch == "" { + log.Fatal("no targetBranch set") + } + remote := "" + if len(os.Args) > 3 { + remote = os.Args[3] + } + if remote == "" { + remote = "origin" + } + + err := os.Chdir(path) + if err != nil { + log.Fatal(err) + } + + clientID, exists := os.LookupEnv("CLIENT_ID") + if !exists { + log.Fatal("no Client ID set") + } + clientSecret, exists := os.LookupEnv("CLIENT_SECRET") + if !exists { + log.Fatal("no Client Secret set") + } + vaasUrl, exists := os.LookupEnv("VAAS_URL") + if !exists { + vaasUrl = "wss://gateway.production.vaas.gdatasecurity.de/" + } + tokenUrl, exists := os.LookupEnv("TOKEN_URL") + if !exists { + tokenUrl = "https://account.gdata.de/realms/vaas-production/protocol/openid-connect/token" + } + + gitRevParseCommand := exec.Command("git", "rev-parse", "--show-toplevel") + rootDirectoryBytes, err := gitRevParseCommand.Output() + if err != nil { + log.Fatal("git rev-parse", err) + } + rootDirectory := strings.Split(strings.ReplaceAll(string(rootDirectoryBytes), "\r\n", "\n"), "\n")[0] + + exec.Command("git", "fetch", remote, targetBranch) + gitDiffCommand := exec.Command("git", "diff", "--name-only", targetBranch) + diffBytes, err := gitDiffCommand.Output() + if err != nil { + log.Fatal("git diff", err) + } + files := strings.Split(strings.ReplaceAll(string(diffBytes), "\r\n", "\n"), "\n") + if len(files) < 1 { + log.Println("no changed files found in diff") + os.Exit(0) + } + + authenticator := authenticator.New(clientID, clientSecret, tokenUrl) + + vaas := vaas.New(options.DefaultOptions(), vaasUrl) + ctx, webSocketCancel := context.WithCancel(context.Background()) + termChan, err := vaas.Connect(ctx, authenticator) + if err != nil { + log.Fatal("vaas connect error", err) + } + if termChan == nil { + log.Fatal("vaas connect error") + } + var maliciousFileFound bool + for _, file := range files { + if file != "" { + pathToFile := filepath.Join(rootDirectory, file) + verdict, err := vaas.ForFile(context.Background(), pathToFile) + if err != nil { + log.Fatalln(err) + } + log.Println(pathToFile + ": " + string(verdict.Verdict)) + if verdict.Verdict == messages.Malicious { + maliciousFileFound = true + } + } + } + webSocketCancel() + if err = <-termChan; err != nil { + log.Printf("Websocket shutdown with an error - %v", err) + } + if maliciousFileFound { + os.Exit(1) + } +} diff --git a/golang/vaas/git-scan.Dockerfile b/golang/vaas/git-scan.Dockerfile new file mode 100644 index 00000000..aab1c822 --- /dev/null +++ b/golang/vaas/git-scan.Dockerfile @@ -0,0 +1,13 @@ +FROM ubuntu:22.04 as runner + +RUN apt update && apt install -y git +WORKDIR /app + +FROM golang:1.22 as builder + +COPY . . +RUN go build -o /build/git-scan cmd/git-scan/main.go + +FROM runner +COPY --from=builder /build/git-scan /app/git-scan +ENTRYPOINT ["/app/git-scan"] \ No newline at end of file diff --git a/golang/vaas/go.mod b/golang/vaas/go.mod index d635ce08..4c5d3bf2 100644 --- a/golang/vaas/go.mod +++ b/golang/vaas/go.mod @@ -1,6 +1,6 @@ module github.com/GDATASoftwareAG/vaas/golang/vaas -go 1.22.0 +go 1.22 require ( github.com/Noooste/websocket v1.0.3 @@ -16,17 +16,18 @@ require ( github.com/cloudflare/circl v1.3.7 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 // indirect - github.com/klauspost/compress v1.17.6 // indirect + github.com/klauspost/compress v1.17.7 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/onsi/ginkgo/v2 v2.15.0 // indirect github.com/onsi/gomega v1.30.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/quic-go/quic-go v0.41.0 // indirect - github.com/refraction-networking/utls v1.6.2 // indirect - golang.org/x/crypto v0.19.0 // indirect + github.com/refraction-networking/utls v1.6.3 // indirect + golang.org/x/crypto v0.20.0 // indirect golang.org/x/net v0.21.0 // indirect golang.org/x/sys v0.17.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/tools v0.18.0 // indirect + gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/golang/vaas/go.sum b/golang/vaas/go.sum index e18395e2..83687591 100644 --- a/golang/vaas/go.sum +++ b/golang/vaas/go.sum @@ -25,6 +25,8 @@ github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI= github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= +github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -40,12 +42,16 @@ github.com/quic-go/quic-go v0.41.0 h1:aD8MmHfgqTURWNJy48IYFg2OnxwHT3JL7ahGs73lb4 github.com/quic-go/quic-go v0.41.0/go.mod h1:qCkNjqczPEvgsOnxZ0eCD14lv+B2LHlFAB++CNOh9hA= github.com/refraction-networking/utls v1.6.2 h1:iTeeGY0o6nMNcGyirxkD5bFIsVctP5InGZ3E0HrzS7k= github.com/refraction-networking/utls v1.6.2/go.mod h1:yil9+7qSl+gBwJqztoQseO6Pr3h62pQoY1lXiNR/FPs= +github.com/refraction-networking/utls v1.6.3 h1:MFOfRN35sSx6K5AZNIoESsBuBxS2LCgRilRIdHb6fDc= +github.com/refraction-networking/utls v1.6.3/go.mod h1:yil9+7qSl+gBwJqztoQseO6Pr3h62pQoY1lXiNR/FPs= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg= +golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= @@ -55,7 +61,7 @@ golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=