From 712de1c63d9db97c81af68cd0dc4372c53d2e57a Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Tue, 15 Sep 2020 18:05:35 +0200 Subject: vendor/github.com/golangci/golangci-lint: update to v1.31 --- vendor/github.com/securego/gosec/v2/Dockerfile | 5 +- vendor/github.com/securego/gosec/v2/README.md | 30 +++-- vendor/github.com/securego/gosec/v2/USERS.md | 26 ++++ vendor/github.com/securego/gosec/v2/analyzer.go | 28 ++--- vendor/github.com/securego/gosec/v2/entrypoint.sh | 7 ++ vendor/github.com/securego/gosec/v2/go.mod | 11 +- vendor/github.com/securego/gosec/v2/go.sum | 35 ++++++ vendor/github.com/securego/gosec/v2/helpers.go | 22 +++- vendor/github.com/securego/gosec/v2/issue.go | 58 ++++++--- .../securego/gosec/v2/rules/bad_defer.go | 2 +- .../securego/gosec/v2/rules/blacklist.go | 94 --------------- .../securego/gosec/v2/rules/blocklist.go | 94 +++++++++++++++ .../securego/gosec/v2/rules/implicit_aliasing.go | 25 ++-- vendor/github.com/securego/gosec/v2/rules/rand.go | 3 +- .../github.com/securego/gosec/v2/rules/readfile.go | 1 + .../github.com/securego/gosec/v2/rules/rulelist.go | 12 +- vendor/github.com/securego/gosec/v2/rules/sql.go | 132 +++++++++++++++++---- vendor/github.com/securego/gosec/v2/rules/tls.go | 63 +++++++--- .../securego/gosec/v2/rules/weakcrypto.go | 6 +- 19 files changed, 446 insertions(+), 208 deletions(-) create mode 100644 vendor/github.com/securego/gosec/v2/USERS.md create mode 100644 vendor/github.com/securego/gosec/v2/entrypoint.sh delete mode 100644 vendor/github.com/securego/gosec/v2/rules/blacklist.go create mode 100644 vendor/github.com/securego/gosec/v2/rules/blocklist.go (limited to 'vendor/github.com/securego') diff --git a/vendor/github.com/securego/gosec/v2/Dockerfile b/vendor/github.com/securego/gosec/v2/Dockerfile index a874697e9..c937d5255 100644 --- a/vendor/github.com/securego/gosec/v2/Dockerfile +++ b/vendor/github.com/securego/gosec/v2/Dockerfile @@ -8,7 +8,8 @@ RUN go mod download RUN make build-linux FROM golang:${GO_VERSION}-alpine -RUN apk add --update --no-cache ca-certificates git gcc libc-dev +RUN apk add --update --no-cache ca-certificates bash git gcc libc-dev ENV GO111MODULE on COPY --from=builder /build/gosec /bin/gosec -ENTRYPOINT ["/bin/gosec"] +COPY entrypoint.sh /bin/entrypoint.sh +ENTRYPOINT ["/bin/entrypoint.sh"] diff --git a/vendor/github.com/securego/gosec/v2/README.md b/vendor/github.com/securego/gosec/v2/README.md index 52be73423..8fd10f16b 100644 --- a/vendor/github.com/securego/gosec/v2/README.md +++ b/vendor/github.com/securego/gosec/v2/README.md @@ -41,7 +41,7 @@ wget -O - -q https://raw.githubusercontent.com/securego/gosec/master/install.sh # then you will have to download a tar.gz file for your operating system instead of a binary file wget https://github.com/securego/gosec/releases/download/vX.Y.Z/gosec_vX.Y.Z_OS.tar.gz -# The file will be in the current folder where you run the command +# The file will be in the current folder where you run the command # and you can check the checksum like this echo " gosec_vX.Y.Z_OS.tar.gz" | sha256sum -c - @@ -66,7 +66,7 @@ jobs: env: GO111MODULE: on steps: - - name: Checkout Source + - name: Checkout Source uses: actions/checkout@v2 - name: Run Gosec Security Scanner uses: securego/gosec@master @@ -114,11 +114,11 @@ directory you can supply `./...` as the input argument. - G402: Look for bad TLS connection settings - G403: Ensure minimum RSA key length of 2048 bits - G404: Insecure random number source (rand) -- G501: Import blacklist: crypto/md5 -- G502: Import blacklist: crypto/des -- G503: Import blacklist: crypto/rc4 -- G504: Import blacklist: net/http/cgi -- G505: Import blacklist: crypto/sha1 +- G501: Import blocklist: crypto/md5 +- G502: Import blocklist: crypto/des +- G503: Import blocklist: crypto/rc4 +- G504: Import blocklist: net/http/cgi +- G505: Import blocklist: crypto/sha1 - G601: Implicit memory aliasing of items from a range statement ### Retired rules @@ -139,7 +139,7 @@ $ gosec -exclude=G303 ./... ``` ### CWE Mapping -Every issue detected by `gosec` is mapped to a [CWE (Common Weakness Enumeration)](http://cwe.mitre.org/data/index.html) which describes in more generic terms the vulnerability. The exact mapping can be found [here](https://github.com/securego/gosec/blob/53be8dd8644ee48802114178cff6eb7e29757414/issue.go#L49). +Every issue detected by `gosec` is mapped to a [CWE (Common Weakness Enumeration)](http://cwe.mitre.org/data/index.html) which describes in more generic terms the vulnerability. The exact mapping can be found [here](https://github.com/securego/gosec/blob/master/issue.go#L49). ### Configuration @@ -161,7 +161,7 @@ A number of global settings can be provided in a configuration file as follows: # Run with a global configuration file $ gosec -conf config.json . ``` -Also some rules accept configuration. For instance on rule `G104`, it is possible to define packages along with a list +Also some rules accept configuration. For instance on rule `G104`, it is possible to define packages along with a list of functions which will be skipped when auditing the not checked errors: ```JSON @@ -186,14 +186,14 @@ You can also configure the hard-coded credentials rule `G101` with additional pa } ``` -### Dependencies +### Dependencies gosec will fetch automatically the dependencies of the code which is being analyzed when go module is turned on (e.g.` GO111MODULE=on`). If this is not the case, the dependencies need to be explicitly downloaded by running the `go get -d` command before the scan. ### Excluding test files and folders -gosec will ignore test files across all packages and any dependencies in your vendor directory. +gosec will ignore test files across all packages and any dependencies in your vendor directory. The scanning of test files can be enabled with the following flag: @@ -233,7 +233,7 @@ func main(){ ``` When a specific false positive has been identified and verified as safe, you may wish to suppress only that single rule (or a specific set of rules) -within a section of code, while continuing to scan for other problems. To do this, you can list the rule(s) to be suppressed within +within a section of code, while continuing to scan for other problems. To do this, you can list the rule(s) to be suppressed within the `#nosec` annotation, e.g: `/* #nosec G401 */` or `// #nosec G201 G202 G203` In some cases you may also want to revisit places where `#nosec` annotations @@ -300,7 +300,7 @@ You can also build locally the docker image by using the command: make image ``` -You can run the `gosec` tool in a container against your local Go project. You only have to mount the project +You can run the `gosec` tool in a container against your local Go project. You only have to mount the project into a volume as follows: ```bash @@ -324,3 +324,7 @@ go generate ./... ``` This will generate the `rules/tls_config.go` file which will contain the current ciphers recommendation from Mozilla. + +## Who is using gosec? + +This is a [list](USERS.md) with some of the gosec's users. diff --git a/vendor/github.com/securego/gosec/v2/USERS.md b/vendor/github.com/securego/gosec/v2/USERS.md new file mode 100644 index 000000000..eac13d03f --- /dev/null +++ b/vendor/github.com/securego/gosec/v2/USERS.md @@ -0,0 +1,26 @@ +# Users + +This is a list of gosec's users. Please send a pull request with your organisation or project name if you are using gosec. + +## Companies + +1. [Gitlab](https://docs.gitlab.com/ee/user/application_security/sast/) +2. [CloudBees](https://cloudbees.com) +3. [VMware](https://www.vmware.com) +4. [Codacy](https://support.codacy.com/hc/en-us/articles/213632009-Engines) +5. [Coinbase](https://github.com/coinbase/watchdog/blob/master/Makefile#L12) +6. [RedHat/OpenShift](https://github.com/openshift/openshift-azure) +7. [Guardalis](https://www.guardrails.io/) +8. [1Password](https://github.com/1Password/srp) +9. [PingCAP/tidb](https://github.com/pingcap/tidb) + +## Projects + +1. [golangci-lint](https://github.com/golangci/golangci-lint) +2. [Kubenetes](https://github.com/kubernetes/kubernetes) (via golangci) +3. [caddy](https://github.com/caddyserver/caddy) (via golangci) +4. [Jenkins X](https://github.com/jenkins-x/jx/blob/bdc51840a41b75776159c1c7b7faa1cf477be473/hack/linter.sh#L25) +5. [HuskyCI](https://huskyci.opensource.globo.com/) +6. [GolangCI](https://golangci.com/) +7. [semgrep.live](https://semgrep.live/) +8. [gofiber](https://github.com/gofiber/fiber) diff --git a/vendor/github.com/securego/gosec/v2/analyzer.go b/vendor/github.com/securego/gosec/v2/analyzer.go index ca4440c20..d4aae3ad3 100644 --- a/vendor/github.com/securego/gosec/v2/analyzer.go +++ b/vendor/github.com/securego/gosec/v2/analyzer.go @@ -125,7 +125,12 @@ func (gosec *Analyzer) LoadRules(ruleDefinitions map[string]RuleBuilder) { // Process kicks off the analysis process for a given package func (gosec *Analyzer) Process(buildTags []string, packagePaths ...string) error { - config := gosec.pkgConfig(buildTags) + config := &packages.Config{ + Mode: LoadMode, + BuildFlags: buildTags, + Tests: gosec.tests, + } + for _, pkgPath := range packagePaths { pkgs, err := gosec.load(pkgPath, config) if err != nil { @@ -145,19 +150,6 @@ func (gosec *Analyzer) Process(buildTags []string, packagePaths ...string) error return nil } -func (gosec *Analyzer) pkgConfig(buildTags []string) *packages.Config { - flags := []string{} - if len(buildTags) > 0 { - tagsFlag := "-tags=" + strings.Join(buildTags, " ") - flags = append(flags, tagsFlag) - } - return &packages.Config{ - Mode: LoadMode, - BuildFlags: flags, - Tests: gosec.tests, - } -} - func (gosec *Analyzer) load(pkgPath string, conf *packages.Config) ([]*packages.Package, error) { abspath, err := GetPkgAbsPath(pkgPath) if err != nil { @@ -166,7 +158,11 @@ func (gosec *Analyzer) load(pkgPath string, conf *packages.Config) ([]*packages. } gosec.logger.Println("Import directory:", abspath) - basePackage, err := build.Default.ImportDir(pkgPath, build.ImportComment) + // step 1/3 create build context. + buildD := build.Default + // step 2/3: add build tags to get env dependent files into basePackage. + buildD.BuildTags = conf.BuildFlags + basePackage, err := buildD.ImportDir(pkgPath, build.ImportComment) if err != nil { return []*packages.Package{}, fmt.Errorf("importing dir %q: %v", pkgPath, err) } @@ -188,6 +184,8 @@ func (gosec *Analyzer) load(pkgPath string, conf *packages.Config) ([]*packages. } } + // step 3/3 remove build tags from conf to proceed build correctly. + conf.BuildFlags = nil pkgs, err := packages.Load(conf, packageFiles...) if err != nil { return []*packages.Package{}, fmt.Errorf("loading files from package %q: %v", pkgPath, err) diff --git a/vendor/github.com/securego/gosec/v2/entrypoint.sh b/vendor/github.com/securego/gosec/v2/entrypoint.sh new file mode 100644 index 000000000..4dc046729 --- /dev/null +++ b/vendor/github.com/securego/gosec/v2/entrypoint.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +# Expand the arguments into an array of strings. This is requires because the GitHub action +# provides all arguments concatenated as a single string. +ARGS=("$@") + +/bin/gosec ${ARGS[*]} diff --git a/vendor/github.com/securego/gosec/v2/go.mod b/vendor/github.com/securego/gosec/v2/go.mod index edfa3434c..e2654af19 100644 --- a/vendor/github.com/securego/gosec/v2/go.mod +++ b/vendor/github.com/securego/gosec/v2/go.mod @@ -2,18 +2,17 @@ module github.com/securego/gosec/v2 require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/golang/protobuf v1.3.2 // indirect - github.com/gookit/color v1.2.4 + github.com/gookit/color v1.2.5 github.com/kr/pretty v0.1.0 // indirect github.com/mozilla/tls-observatory v0.0.0-20200317151703-4fa42e1c2dee github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d - github.com/onsi/ginkgo v1.12.0 - github.com/onsi/gomega v1.9.0 + github.com/onsi/ginkgo v1.13.0 + github.com/onsi/gomega v1.10.1 github.com/stretchr/testify v1.4.0 // indirect golang.org/x/text v0.3.2 // indirect - golang.org/x/tools v0.0.0-20200331202046-9d5940d49312 + golang.org/x/tools v0.0.0-20200701041122-1837592efa10 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect - gopkg.in/yaml.v2 v2.2.8 + gopkg.in/yaml.v2 v2.3.0 ) go 1.14 diff --git a/vendor/github.com/securego/gosec/v2/go.sum b/vendor/github.com/securego/gosec/v2/go.sum index fff56a309..7f56b937d 100644 --- a/vendor/github.com/securego/gosec/v2/go.sum +++ b/vendor/github.com/securego/gosec/v2/go.sum @@ -3,12 +3,24 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/gookit/color v1.2.4 h1:xOYBan3Fwlrqj1M1UN2TlHOCRiek3bGzWf/vPnJ1roE= github.com/gookit/color v1.2.4/go.mod h1:AhIE+pS6D4Ql0SQWbBeXPHw7gY0/sjHoA4s/n1KB7xg= +github.com/gookit/color v1.2.5 h1:s1gzb/fg3HhkSLKyWVUsZcVBUo+R1TwEYTmmxH8gGFg= +github.com/gookit/color v1.2.5/go.mod h1:AhIE+pS6D4Ql0SQWbBeXPHw7gY0/sjHoA4s/n1KB7xg= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= @@ -20,15 +32,21 @@ github.com/mozilla/tls-observatory v0.0.0-20200317151703-4fa42e1c2dee h1:1xJ+Xi9 github.com/mozilla/tls-observatory v0.0.0-20200317151703-4fa42e1c2dee/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d h1:AREM5mwr4u1ORQBMvzfzBgpsctsbQikCVpvC+tX285E= github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU= github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.12.3/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.9.0 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg= github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= @@ -45,6 +63,7 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -52,8 +71,12 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= @@ -62,11 +85,21 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200331202046-9d5940d49312 h1:2PHG+Ia3gK1K2kjxZnSylizb//eyaMG8gDFbOG7wLV8= golang.org/x/tools v0.0.0-20200331202046-9d5940d49312/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200601175630-2caf76543d99 h1:deddXmhOJb/bvD/4M/j2AUMrhHeh6GkqykJSCWyTNVk= +golang.org/x/tools v0.0.0-20200601175630-2caf76543d99/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200701041122-1837592efa10 h1:/dVa/Kj8QBudsXg83xokTMENAVrcMqZdhECHe1y2LJ0= +golang.org/x/tools v0.0.0-20200701041122-1837592efa10/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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= @@ -80,3 +113,5 @@ gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/securego/gosec/v2/helpers.go b/vendor/github.com/securego/gosec/v2/helpers.go index 40dc8e9c3..83dfa293a 100644 --- a/vendor/github.com/securego/gosec/v2/helpers.go +++ b/vendor/github.com/securego/gosec/v2/helpers.go @@ -37,7 +37,6 @@ import ( // node, matched := MatchCallByPackage(n, ctx, "math/rand", "Read") // func MatchCallByPackage(n ast.Node, c *Context, pkg string, names ...string) (*ast.CallExpr, bool) { - importedName, found := GetImportedName(pkg, c) if !found { return nil, false @@ -226,6 +225,27 @@ func GetIdentStringValues(ident *ast.Ident) []string { return values } +// GetBinaryExprOperands returns all operands of a binary expression by traversing +// the expression tree +func GetBinaryExprOperands(be *ast.BinaryExpr) []ast.Node { + var traverse func(be *ast.BinaryExpr) + result := []ast.Node{} + traverse = func(be *ast.BinaryExpr) { + if lhs, ok := be.X.(*ast.BinaryExpr); ok { + traverse(lhs) + } else { + result = append(result, be.X) + } + if rhs, ok := be.Y.(*ast.BinaryExpr); ok { + traverse(rhs) + } else { + result = append(result, be.Y) + } + } + traverse(be) + return result +} + // GetImportedName returns the name used for the package within the // code. It will resolve aliases and ignores initialization only imports. func GetImportedName(path string, ctx *Context) (string, bool) { diff --git a/vendor/github.com/securego/gosec/v2/issue.go b/vendor/github.com/securego/gosec/v2/issue.go index 28ad726ba..aa58c3434 100644 --- a/vendor/github.com/securego/gosec/v2/issue.go +++ b/vendor/github.com/securego/gosec/v2/issue.go @@ -15,9 +15,12 @@ package gosec import ( + "bufio" + "bytes" "encoding/json" "fmt" "go/ast" + "go/token" "os" "strconv" ) @@ -34,6 +37,10 @@ const ( High ) +// SnippetOffset defines the number of lines captured before +// the beginning and after the end of a code snippet +const SnippetOffset = 1 + // Cwe id and url type Cwe struct { ID string @@ -53,6 +60,7 @@ var IssueToCWE = map[string]Cwe{ "G104": GetCwe("703"), "G106": GetCwe("322"), "G107": GetCwe("88"), + "G108": GetCwe("200"), "G109": GetCwe("190"), "G110": GetCwe("409"), "G201": GetCwe("89"), @@ -64,6 +72,8 @@ var IssueToCWE = map[string]Cwe{ "G303": GetCwe("377"), "G304": GetCwe("22"), "G305": GetCwe("22"), + "G306": GetCwe("276"), + "G307": GetCwe("703"), "G401": GetCwe("326"), "G402": GetCwe("295"), "G403": GetCwe("310"), @@ -73,6 +83,7 @@ var IssueToCWE = map[string]Cwe{ "G503": GetCwe("327"), "G504": GetCwe("327"), "G505": GetCwe("327"), + "G601": GetCwe("118"), } // Issue is returned by a gosec rule if it discovers an issue with the scanned code. @@ -120,43 +131,56 @@ func (c Score) String() string { return "UNDEFINED" } +// codeSnippet extracts a code snippet based on the ast reference func codeSnippet(file *os.File, start int64, end int64, n ast.Node) (string, error) { if n == nil { - return "", fmt.Errorf("Invalid AST node provided") + return "", fmt.Errorf("invalid AST node provided") } - - size := (int)(end - start) // Go bug, os.File.Read should return int64 ... - _, err := file.Seek(start, 0) // #nosec - if err != nil { - return "", fmt.Errorf("move to the beginning of file: %v", err) + var pos int64 + var buf bytes.Buffer + scanner := bufio.NewScanner(file) + scanner.Split(bufio.ScanLines) + for scanner.Scan() { + pos++ + if pos > end { + break + } else if pos >= start && pos <= end { + code := fmt.Sprintf("%d: %s\n", pos, scanner.Text()) + buf.WriteString(code) + } } + return buf.String(), nil +} - buf := make([]byte, size) - if nread, err := file.Read(buf); err != nil || nread != size { - return "", fmt.Errorf("Unable to read code") +func codeSnippetStartLine(node ast.Node, fobj *token.File) int64 { + s := (int64)(fobj.Line(node.Pos())) + if s-SnippetOffset > 0 { + return s - SnippetOffset } - return string(buf), nil + return s +} + +func codeSnippetEndLine(node ast.Node, fobj *token.File) int64 { + e := (int64)(fobj.Line(node.End())) + return e + SnippetOffset } // NewIssue creates a new Issue func NewIssue(ctx *Context, node ast.Node, ruleID, desc string, severity Score, confidence Score) *Issue { - var code string fobj := ctx.FileSet.File(node.Pos()) name := fobj.Name() - start, end := fobj.Line(node.Pos()), fobj.Line(node.End()) line := strconv.Itoa(start) if start != end { line = fmt.Sprintf("%d-%d", start, end) } - col := strconv.Itoa(fobj.Position(node.Pos()).Column) - // #nosec + var code string if file, err := os.Open(fobj.Name()); err == nil { - defer file.Close() - s := (int64)(fobj.Position(node.Pos()).Offset) // Go bug, should be int64 - e := (int64)(fobj.Position(node.End()).Offset) // Go bug, should be int64 + defer file.Close() // #nosec + s := codeSnippetStartLine(node, fobj) + e := codeSnippetEndLine(node, fobj) code, err = codeSnippet(file, s, e, node) if err != nil { code = err.Error() diff --git a/vendor/github.com/securego/gosec/v2/rules/bad_defer.go b/vendor/github.com/securego/gosec/v2/rules/bad_defer.go index 3c358806f..b33a0477c 100644 --- a/vendor/github.com/securego/gosec/v2/rules/bad_defer.go +++ b/vendor/github.com/securego/gosec/v2/rules/bad_defer.go @@ -40,7 +40,7 @@ func (r *badDefer) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { for _, deferTyp := range r.types { if typ, method, err := gosec.GetCallInfo(deferStmt.Call, c); err == nil { if normalize(typ) == deferTyp.typ && contains(deferTyp.methods, method) { - return gosec.NewIssue(c, n, r.ID(), fmt.Sprintf(r.What, typ, method), r.Severity, r.Confidence), nil + return gosec.NewIssue(c, n, r.ID(), fmt.Sprintf(r.What, method, typ), r.Severity, r.Confidence), nil } } } diff --git a/vendor/github.com/securego/gosec/v2/rules/blacklist.go b/vendor/github.com/securego/gosec/v2/rules/blacklist.go deleted file mode 100644 index 9bb73381f..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/blacklist.go +++ /dev/null @@ -1,94 +0,0 @@ -// (c) Copyright 2016 Hewlett Packard Enterprise Development LP -// -// 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 rules - -import ( - "go/ast" - "strings" - - "github.com/securego/gosec/v2" -) - -type blacklistedImport struct { - gosec.MetaData - Blacklisted map[string]string -} - -func unquote(original string) string { - copy := strings.TrimSpace(original) - copy = strings.TrimLeft(copy, `"`) - return strings.TrimRight(copy, `"`) -} - -func (r *blacklistedImport) ID() string { - return r.MetaData.ID -} - -func (r *blacklistedImport) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { - if node, ok := n.(*ast.ImportSpec); ok { - if description, ok := r.Blacklisted[unquote(node.Path.Value)]; ok { - return gosec.NewIssue(c, node, r.ID(), description, r.Severity, r.Confidence), nil - } - } - return nil, nil -} - -// NewBlacklistedImports reports when a blacklisted import is being used. -// Typically when a deprecated technology is being used. -func NewBlacklistedImports(id string, conf gosec.Config, blacklist map[string]string) (gosec.Rule, []ast.Node) { - return &blacklistedImport{ - MetaData: gosec.MetaData{ - ID: id, - Severity: gosec.Medium, - Confidence: gosec.High, - }, - Blacklisted: blacklist, - }, []ast.Node{(*ast.ImportSpec)(nil)} -} - -// NewBlacklistedImportMD5 fails if MD5 is imported -func NewBlacklistedImportMD5(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { - return NewBlacklistedImports(id, conf, map[string]string{ - "crypto/md5": "Blacklisted import crypto/md5: weak cryptographic primitive", - }) -} - -// NewBlacklistedImportDES fails if DES is imported -func NewBlacklistedImportDES(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { - return NewBlacklistedImports(id, conf, map[string]string{ - "crypto/des": "Blacklisted import crypto/des: weak cryptographic primitive", - }) -} - -// NewBlacklistedImportRC4 fails if DES is imported -func NewBlacklistedImportRC4(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { - return NewBlacklistedImports(id, conf, map[string]string{ - "crypto/rc4": "Blacklisted import crypto/rc4: weak cryptographic primitive", - }) -} - -// NewBlacklistedImportCGI fails if CGI is imported -func NewBlacklistedImportCGI(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { - return NewBlacklistedImports(id, conf, map[string]string{ - "net/http/cgi": "Blacklisted import net/http/cgi: Go versions < 1.6.3 are vulnerable to Httpoxy attack: (CVE-2016-5386)", - }) -} - -// NewBlacklistedImportSHA1 fails if SHA1 is imported -func NewBlacklistedImportSHA1(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { - return NewBlacklistedImports(id, conf, map[string]string{ - "crypto/sha1": "Blacklisted import crypto/sha1: weak cryptographic primitive", - }) -} diff --git a/vendor/github.com/securego/gosec/v2/rules/blocklist.go b/vendor/github.com/securego/gosec/v2/rules/blocklist.go new file mode 100644 index 000000000..afd4ee56b --- /dev/null +++ b/vendor/github.com/securego/gosec/v2/rules/blocklist.go @@ -0,0 +1,94 @@ +// (c) Copyright 2016 Hewlett Packard Enterprise Development LP +// +// 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 rules + +import ( + "go/ast" + "strings" + + "github.com/securego/gosec/v2" +) + +type blocklistedImport struct { + gosec.MetaData + Blocklisted map[string]string +} + +func unquote(original string) string { + copy := strings.TrimSpace(original) + copy = strings.TrimLeft(copy, `"`) + return strings.TrimRight(copy, `"`) +} + +func (r *blocklistedImport) ID() string { + return r.MetaData.ID +} + +func (r *blocklistedImport) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { + if node, ok := n.(*ast.ImportSpec); ok { + if description, ok := r.Blocklisted[unquote(node.Path.Value)]; ok { + return gosec.NewIssue(c, node, r.ID(), description, r.Severity, r.Confidence), nil + } + } + return nil, nil +} + +// NewBlocklistedImports reports when a blocklisted import is being used. +// Typically when a deprecated technology is being used. +func NewBlocklistedImports(id string, conf gosec.Config, blocklist map[string]string) (gosec.Rule, []ast.Node) { + return &blocklistedImport{ + MetaData: gosec.MetaData{ + ID: id, + Severity: gosec.Medium, + Confidence: gosec.High, + }, + Blocklisted: blocklist, + }, []ast.Node{(*ast.ImportSpec)(nil)} +} + +// NewBlocklistedImportMD5 fails if MD5 is imported +func NewBlocklistedImportMD5(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { + return NewBlocklistedImports(id, conf, map[string]string{ + "crypto/md5": "Blocklisted import crypto/md5: weak cryptographic primitive", + }) +} + +// NewBlocklistedImportDES fails if DES is imported +func NewBlocklistedImportDES(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { + return NewBlocklistedImports(id, conf, map[string]string{ + "crypto/des": "Blocklisted import crypto/des: weak cryptographic primitive", + }) +} + +// NewBlocklistedImportRC4 fails if DES is imported +func NewBlocklistedImportRC4(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { + return NewBlocklistedImports(id, conf, map[string]string{ + "crypto/rc4": "Blocklisted import crypto/rc4: weak cryptographic primitive", + }) +} + +// NewBlocklistedImportCGI fails if CGI is imported +func NewBlocklistedImportCGI(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { + return NewBlocklistedImports(id, conf, map[string]string{ + "net/http/cgi": "Blocklisted import net/http/cgi: Go versions < 1.6.3 are vulnerable to Httpoxy attack: (CVE-2016-5386)", + }) +} + +// NewBlocklistedImportSHA1 fails if SHA1 is imported +func NewBlocklistedImportSHA1(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { + return NewBlocklistedImports(id, conf, map[string]string{ + "crypto/sha1": "Blocklisted import crypto/sha1: weak cryptographic primitive", + }) +} diff --git a/vendor/github.com/securego/gosec/v2/rules/implicit_aliasing.go b/vendor/github.com/securego/gosec/v2/rules/implicit_aliasing.go index 65c7ae36d..b2668dec8 100644 --- a/vendor/github.com/securego/gosec/v2/rules/implicit_aliasing.go +++ b/vendor/github.com/securego/gosec/v2/rules/implicit_aliasing.go @@ -1,10 +1,10 @@ package rules import ( - "fmt" - "github.com/securego/gosec/v2" "go/ast" "go/token" + + "github.com/securego/gosec/v2" ) type implicitAliasing struct { @@ -33,20 +33,23 @@ func (r *implicitAliasing) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, er // When presented with a range statement, get the underlying Object bound to // by assignment and add it to our set (r.aliases) of objects to check for. if key, ok := node.Value.(*ast.Ident); ok { - if assignment, ok := key.Obj.Decl.(*ast.AssignStmt); ok { - if len(assignment.Lhs) < 2 { - return nil, nil - } + if key.Obj != nil { + if assignment, ok := key.Obj.Decl.(*ast.AssignStmt); ok { + if len(assignment.Lhs) < 2 { + return nil, nil + } - if object, ok := assignment.Lhs[1].(*ast.Ident); ok { - r.aliases[object.Obj] = struct{}{} + if object, ok := assignment.Lhs[1].(*ast.Ident); ok { + r.aliases[object.Obj] = struct{}{} - if r.rightBrace < node.Body.Rbrace { - r.rightBrace = node.Body.Rbrace + if r.rightBrace < node.Body.Rbrace { + r.rightBrace = node.Body.Rbrace + } } } } } + case *ast.UnaryExpr: // If this unary expression is outside of the last range statement we were looking at // then clear the list of objects we're concerned about because they're no longer in @@ -95,7 +98,7 @@ func NewImplicitAliasing(id string, conf gosec.Config) (gosec.Rule, []ast.Node) ID: id, Severity: gosec.Medium, Confidence: gosec.Medium, - What: fmt.Sprintf("Implicit memory aliasing in for loop."), + What: "Implicit memory aliasing in for loop.", }, }, []ast.Node{(*ast.RangeStmt)(nil), (*ast.UnaryExpr)(nil), (*ast.ReturnStmt)(nil)} } diff --git a/vendor/github.com/securego/gosec/v2/rules/rand.go b/vendor/github.com/securego/gosec/v2/rules/rand.go index 08c28fcad..bf86b762d 100644 --- a/vendor/github.com/securego/gosec/v2/rules/rand.go +++ b/vendor/github.com/securego/gosec/v2/rules/rand.go @@ -43,7 +43,8 @@ func (w *weakRand) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { // NewWeakRandCheck detects the use of random number generator that isn't cryptographically secure func NewWeakRandCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { return &weakRand{ - funcNames: []string{"Read", "Int"}, + funcNames: []string{"New", "Read", "Float32", "Float64", "Int", "Int31", + "Int31n", "Int63", "Int63n", "Intn", "NormalFloat64", "Uint32", "Uint64"}, packagePath: "math/rand", MetaData: gosec.MetaData{ ID: id, diff --git a/vendor/github.com/securego/gosec/v2/rules/readfile.go b/vendor/github.com/securego/gosec/v2/rules/readfile.go index a52f7425f..459b4ad2f 100644 --- a/vendor/github.com/securego/gosec/v2/rules/readfile.go +++ b/vendor/github.com/securego/gosec/v2/rules/readfile.go @@ -102,5 +102,6 @@ func NewReadFile(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { rule.pathJoin.Add("path", "Join") rule.Add("io/ioutil", "ReadFile") rule.Add("os", "Open") + rule.Add("os", "OpenFile") return rule, []ast.Node{(*ast.CallExpr)(nil)} } diff --git a/vendor/github.com/securego/gosec/v2/rules/rulelist.go b/vendor/github.com/securego/gosec/v2/rules/rulelist.go index 06e1dfb97..a3d9ca2f6 100644 --- a/vendor/github.com/securego/gosec/v2/rules/rulelist.go +++ b/vendor/github.com/securego/gosec/v2/rules/rulelist.go @@ -90,12 +90,12 @@ func Generate(filters ...RuleFilter) RuleList { {"G403", "Ensure minimum RSA key length of 2048 bits", NewWeakKeyStrength}, {"G404", "Insecure random number source (rand)", NewWeakRandCheck}, - // blacklist - {"G501", "Import blacklist: crypto/md5", NewBlacklistedImportMD5}, - {"G502", "Import blacklist: crypto/des", NewBlacklistedImportDES}, - {"G503", "Import blacklist: crypto/rc4", NewBlacklistedImportRC4}, - {"G504", "Import blacklist: net/http/cgi", NewBlacklistedImportCGI}, - {"G505", "Import blacklist: crypto/sha1", NewBlacklistedImportSHA1}, + // blocklist + {"G501", "Import blocklist: crypto/md5", NewBlocklistedImportMD5}, + {"G502", "Import blocklist: crypto/des", NewBlocklistedImportDES}, + {"G503", "Import blocklist: crypto/rc4", NewBlocklistedImportRC4}, + {"G504", "Import blocklist: net/http/cgi", NewBlocklistedImportCGI}, + {"G505", "Import blocklist: crypto/sha1", NewBlocklistedImportSHA1}, // memory safety {"G601", "Implicit memory aliasing in RangeStmt", NewImplicitAliasing}, diff --git a/vendor/github.com/securego/gosec/v2/rules/sql.go b/vendor/github.com/securego/gosec/v2/rules/sql.go index 3279a3400..127dec504 100644 --- a/vendor/github.com/securego/gosec/v2/rules/sql.go +++ b/vendor/github.com/securego/gosec/v2/rules/sql.go @@ -17,12 +17,14 @@ package rules import ( "go/ast" "regexp" + "strings" "github.com/securego/gosec/v2" ) type sqlStatement struct { gosec.MetaData + gosec.CallList // Contains a list of patterns which must all match for the rule to match. patterns []*regexp.Regexp @@ -65,33 +67,65 @@ func (s *sqlStrConcat) checkObject(n *ast.Ident, c *gosec.Context) bool { return false } -// Look for "SELECT * FROM table WHERE " + " ' OR 1=1" -func (s *sqlStrConcat) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { - if node, ok := n.(*ast.BinaryExpr); ok { - if start, ok := node.X.(*ast.BasicLit); ok { +// checkQuery verifies if the query parameters is a string concatenation +func (s *sqlStrConcat) checkQuery(call *ast.CallExpr, ctx *gosec.Context) (*gosec.Issue, error) { + _, fnName, err := gosec.GetCallInfo(call, ctx) + if err != nil { + return nil, err + } + var query ast.Node + if strings.HasSuffix(fnName, "Context") { + query = call.Args[1] + } else { + query = call.Args[0] + } + + if be, ok := query.(*ast.BinaryExpr); ok { + operands := gosec.GetBinaryExprOperands(be) + if start, ok := operands[0].(*ast.BasicLit); ok { if str, e := gosec.GetString(start); e == nil { if !s.MatchPatterns(str) { return nil, nil } - if _, ok := node.Y.(*ast.BasicLit); ok { - return nil, nil // string cat OK + } + for _, op := range operands[1:] { + if _, ok := op.(*ast.BasicLit); ok { + continue } - if second, ok := node.Y.(*ast.Ident); ok && s.checkObject(second, c) { - return nil, nil + if op, ok := op.(*ast.Ident); ok && s.checkObject(op, ctx) { + continue } - return gosec.NewIssue(c, n, s.ID(), s.What, s.Severity, s.Confidence), nil + return gosec.NewIssue(ctx, be, s.ID(), s.What, s.Severity, s.Confidence), nil } } } + + return nil, nil +} + +// Checks SQL query concatenation issues such as "SELECT * FROM table WHERE " + " ' OR 1=1" +func (s *sqlStrConcat) Match(n ast.Node, ctx *gosec.Context) (*gosec.Issue, error) { + switch stmt := n.(type) { + case *ast.AssignStmt: + for _, expr := range stmt.Rhs { + if sqlQueryCall, ok := expr.(*ast.CallExpr); ok && s.ContainsCallExpr(expr, ctx) != nil { + return s.checkQuery(sqlQueryCall, ctx) + } + } + case *ast.ExprStmt: + if sqlQueryCall, ok := stmt.X.(*ast.CallExpr); ok && s.ContainsCallExpr(stmt.X, ctx) != nil { + return s.checkQuery(sqlQueryCall, ctx) + } + } return nil, nil } // NewSQLStrConcat looks for cases where we are building SQL strings via concatenation func NewSQLStrConcat(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { - return &sqlStrConcat{ + rule := &sqlStrConcat{ sqlStatement: sqlStatement{ patterns: []*regexp.Regexp{ - regexp.MustCompile(`(?)(SELECT|DELETE|INSERT|UPDATE|INTO|FROM|WHERE) `), + regexp.MustCompile(`(?i)(SELECT|DELETE|INSERT|UPDATE|INTO|FROM|WHERE) `), }, MetaData: gosec.MetaData{ ID: id, @@ -99,13 +133,19 @@ func NewSQLStrConcat(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { Confidence: gosec.High, What: "SQL string concatenation", }, + CallList: gosec.NewCallList(), }, - }, []ast.Node{(*ast.BinaryExpr)(nil)} + } + + rule.AddAll("*database/sql.DB", "Query", "QueryContext", "QueryRow", "QueryRowContext") + rule.AddAll("*database/sql.Tx", "Query", "QueryContext", "QueryRow", "QueryRowContext") + return rule, []ast.Node{(*ast.AssignStmt)(nil), (*ast.ExprStmt)(nil)} } type sqlStrFormat struct { + gosec.CallList sqlStatement - calls gosec.CallList + fmtCalls gosec.CallList noIssue gosec.CallList noIssueQuoted gosec.CallList } @@ -130,14 +170,37 @@ func (s *sqlStrFormat) constObject(e ast.Expr, c *gosec.Context) bool { return false } -// Looks for "fmt.Sprintf("SELECT * FROM foo where '%s', userInput)" -func (s *sqlStrFormat) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { +func (s *sqlStrFormat) checkQuery(call *ast.CallExpr, ctx *gosec.Context) (*gosec.Issue, error) { + _, fnName, err := gosec.GetCallInfo(call, ctx) + if err != nil { + return nil, err + } + var query ast.Node + if strings.HasSuffix(fnName, "Context") { + query = call.Args[1] + } else { + query = call.Args[0] + } + + if ident, ok := query.(*ast.Ident); ok && ident.Obj != nil { + decl := ident.Obj.Decl + if assign, ok := decl.(*ast.AssignStmt); ok { + for _, expr := range assign.Rhs { + issue, err := s.checkFormatting(expr, ctx) + if issue != nil { + return issue, err + } + } + } + } + return nil, nil +} + +func (s *sqlStrFormat) checkFormatting(n ast.Node, ctx *gosec.Context) (*gosec.Issue, error) { // argIndex changes the function argument which gets matched to the regex argIndex := 0 - - // TODO(gm) improve confidence if database/sql is being used - if node := s.calls.ContainsPkgCallExpr(n, c, false); node != nil { + if node := s.fmtCalls.ContainsPkgCallExpr(n, ctx, false); node != nil { // if the function is fmt.Fprintf, search for SQL statement in Args[1] instead if sel, ok := node.Fun.(*ast.SelectorExpr); ok { if sel.Sel.Name == "Fprintf" { @@ -177,7 +240,7 @@ func (s *sqlStrFormat) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) if argIndex+1 < len(node.Args) { allSafe := true for _, arg := range node.Args[argIndex+1:] { - if n := s.noIssueQuoted.ContainsPkgCallExpr(arg, c, true); n == nil && !s.constObject(arg, c) { + if n := s.noIssueQuoted.ContainsPkgCallExpr(arg, ctx, true); n == nil && !s.constObject(arg, ctx) { allSafe = false break } @@ -187,7 +250,24 @@ func (s *sqlStrFormat) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) } } if s.MatchPatterns(formatter) { - return gosec.NewIssue(c, n, s.ID(), s.What, s.Severity, s.Confidence), nil + return gosec.NewIssue(ctx, n, s.ID(), s.What, s.Severity, s.Confidence), nil + } + } + return nil, nil +} + +// Check SQL query formatting issues such as "fmt.Sprintf("SELECT * FROM foo where '%s', userInput)" +func (s *sqlStrFormat) Match(n ast.Node, ctx *gosec.Context) (*gosec.Issue, error) { + switch stmt := n.(type) { + case *ast.AssignStmt: + for _, expr := range stmt.Rhs { + if sqlQueryCall, ok := expr.(*ast.CallExpr); ok && s.ContainsCallExpr(expr, ctx) != nil { + return s.checkQuery(sqlQueryCall, ctx) + } + } + case *ast.ExprStmt: + if sqlQueryCall, ok := stmt.X.(*ast.CallExpr); ok && s.ContainsCallExpr(stmt.X, ctx) != nil { + return s.checkQuery(sqlQueryCall, ctx) } } return nil, nil @@ -196,12 +276,13 @@ func (s *sqlStrFormat) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) // NewSQLStrFormat looks for cases where we're building SQL query strings using format strings func NewSQLStrFormat(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { rule := &sqlStrFormat{ - calls: gosec.NewCallList(), + CallList: gosec.NewCallList(), + fmtCalls: gosec.NewCallList(), noIssue: gosec.NewCallList(), noIssueQuoted: gosec.NewCallList(), sqlStatement: sqlStatement{ patterns: []*regexp.Regexp{ - regexp.MustCompile("(?)(SELECT|DELETE|INSERT|UPDATE|INTO|FROM|WHERE) "), + regexp.MustCompile("(?i)(SELECT|DELETE|INSERT|UPDATE|INTO|FROM|WHERE) "), regexp.MustCompile("%[^bdoxXfFp]"), }, MetaData: gosec.MetaData{ @@ -212,8 +293,11 @@ func NewSQLStrFormat(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { }, }, } - rule.calls.AddAll("fmt", "Sprint", "Sprintf", "Sprintln", "Fprintf") + rule.AddAll("*database/sql.DB", "Query", "QueryContext", "QueryRow", "QueryRowContext") + rule.AddAll("*database/sql.Tx", "Query", "QueryContext", "QueryRow", "QueryRowContext") + rule.fmtCalls.AddAll("fmt", "Sprint", "Sprintf", "Sprintln", "Fprintf") rule.noIssue.AddAll("os", "Stdout", "Stderr") rule.noIssueQuoted.Add("github.com/lib/pq", "QuoteIdentifier") - return rule, []ast.Node{(*ast.CallExpr)(nil)} + + return rule, []ast.Node{(*ast.AssignStmt)(nil), (*ast.ExprStmt)(nil)} } diff --git a/vendor/github.com/securego/gosec/v2/rules/tls.go b/vendor/github.com/securego/gosec/v2/rules/tls.go index fab9ee164..554378f42 100644 --- a/vendor/github.com/securego/gosec/v2/rules/tls.go +++ b/vendor/github.com/securego/gosec/v2/rules/tls.go @@ -17,6 +17,7 @@ package rules import ( + "crypto/tls" "fmt" "go/ast" @@ -25,10 +26,12 @@ import ( type insecureConfigTLS struct { gosec.MetaData - MinVersion int16 - MaxVersion int16 - requiredType string - goodCiphers []string + MinVersion int16 + MaxVersion int16 + requiredType string + goodCiphers []string + actualMinVersion int16 + actualMaxVersion int16 } func (t *insecureConfigTLS) ID() string { @@ -45,7 +48,6 @@ func stringInSlice(a string, list []string) bool { } func (t *insecureConfigTLS) processTLSCipherSuites(n ast.Node, c *gosec.Context) *gosec.Issue { - if ciphers, ok := n.(*ast.CompositeLit); ok { for _, cipher := range ciphers.Elts { if ident, ok := cipher.(*ast.SelectorExpr); ok { @@ -62,7 +64,6 @@ func (t *insecureConfigTLS) processTLSCipherSuites(n ast.Node, c *gosec.Context) func (t *insecureConfigTLS) processTLSConfVal(n *ast.KeyValueExpr, c *gosec.Context) *gosec.Issue { if ident, ok := n.Key.(*ast.Ident); ok { switch ident.Name { - case "InsecureSkipVerify": if node, ok := n.Value.(*ast.Ident); ok { if node.Name != "false" { @@ -85,20 +86,24 @@ func (t *insecureConfigTLS) processTLSConfVal(n *ast.KeyValueExpr, c *gosec.Cont case "MinVersion": if ival, ierr := gosec.GetInt(n.Value); ierr == nil { - if (int16)(ival) < t.MinVersion { - return gosec.NewIssue(c, n, t.ID(), "TLS MinVersion too low.", gosec.High, gosec.High) + t.actualMinVersion = (int16)(ival) + } else { + if se, ok := n.Value.(*ast.SelectorExpr); ok { + if pkg, ok := se.X.(*ast.Ident); ok && pkg.Name == "tls" { + t.actualMinVersion = t.mapVersion(se.Sel.Name) + } } - // TODO(tk): symbol tab look up to get the actual value - return gosec.NewIssue(c, n, t.ID(), "TLS MinVersion may be too low.", gosec.High, gosec.Low) } case "MaxVersion": if ival, ierr := gosec.GetInt(n.Value); ierr == nil { - if (int16)(ival) < t.MaxVersion { - return gosec.NewIssue(c, n, t.ID(), "TLS MaxVersion too low.", gosec.High, gosec.High) + t.actualMaxVersion = (int16)(ival) + } else { + if se, ok := n.Value.(*ast.SelectorExpr); ok { + if pkg, ok := se.X.(*ast.Ident); ok && pkg.Name == "tls" { + t.actualMaxVersion = t.mapVersion(se.Sel.Name) + } } - // TODO(tk): symbol tab look up to get the actual value - return gosec.NewIssue(c, n, t.ID(), "TLS MaxVersion may be too low.", gosec.High, gosec.Low) } case "CipherSuites": @@ -112,6 +117,35 @@ func (t *insecureConfigTLS) processTLSConfVal(n *ast.KeyValueExpr, c *gosec.Cont return nil } +func (t *insecureConfigTLS) mapVersion(version string) int16 { + var v int16 + switch version { + case "VersionTLS13": + v = tls.VersionTLS13 + case "VersionTLS12": + v = tls.VersionTLS12 + case "VersionTLS11": + v = tls.VersionTLS11 + case "VersionTLS10": + v = tls.VersionTLS10 + } + return v +} + +func (t *insecureConfigTLS) checkVersion(n ast.Node, c *gosec.Context) *gosec.Issue { + if t.actualMaxVersion == 0 && t.actualMinVersion >= t.MinVersion { + // no warning is generated since the min version is grater than the secure min version + return nil + } + if t.actualMinVersion < t.MinVersion { + return gosec.NewIssue(c, n, t.ID(), "TLS MinVersion too low.", gosec.High, gosec.High) + } + if t.actualMaxVersion < t.MaxVersion { + return gosec.NewIssue(c, n, t.ID(), "TLS MaxVersion too low.", gosec.High, gosec.High) + } + return nil +} + func (t *insecureConfigTLS) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { if complit, ok := n.(*ast.CompositeLit); ok && complit.Type != nil { actualType := c.Info.TypeOf(complit.Type) @@ -124,6 +158,7 @@ func (t *insecureConfigTLS) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, e } } } + return t.checkVersion(complit, c), nil } } return nil, nil diff --git a/vendor/github.com/securego/gosec/v2/rules/weakcrypto.go b/vendor/github.com/securego/gosec/v2/rules/weakcrypto.go index 0e45393db..eecb88f04 100644 --- a/vendor/github.com/securego/gosec/v2/rules/weakcrypto.go +++ b/vendor/github.com/securego/gosec/v2/rules/weakcrypto.go @@ -22,7 +22,7 @@ import ( type usesWeakCryptography struct { gosec.MetaData - blacklist map[string][]string + blocklist map[string][]string } func (r *usesWeakCryptography) ID() string { @@ -30,7 +30,7 @@ func (r *usesWeakCryptography) ID() string { } func (r *usesWeakCryptography) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { - for pkg, funcs := range r.blacklist { + for pkg, funcs := range r.blocklist { if _, matched := gosec.MatchCallByPackage(n, c, pkg, funcs...); matched { return gosec.NewIssue(c, n, r.ID(), r.What, r.Severity, r.Confidence), nil } @@ -46,7 +46,7 @@ func NewUsesWeakCryptography(id string, conf gosec.Config) (gosec.Rule, []ast.No calls["crypto/sha1"] = []string{"New", "Sum"} calls["crypto/rc4"] = []string{"NewCipher"} rule := &usesWeakCryptography{ - blacklist: calls, + blocklist: calls, MetaData: gosec.MetaData{ ID: id, Severity: gosec.Medium, -- cgit mrf-deployment