From 7b4377ad9d8a7205416df8d6217ef2b010f89481 Mon Sep 17 00:00:00 2001 From: Taras Madan Date: Wed, 22 Jan 2025 16:07:17 +0100 Subject: vendor: delete --- vendor/github.com/securego/gosec/v2/.gitignore | 40 -- vendor/github.com/securego/gosec/v2/.golangci.yml | 49 -- .../github.com/securego/gosec/v2/.goreleaser.yml | 37 -- vendor/github.com/securego/gosec/v2/Dockerfile | 15 - vendor/github.com/securego/gosec/v2/LICENSE.txt | 154 ----- vendor/github.com/securego/gosec/v2/Makefile | 98 --- vendor/github.com/securego/gosec/v2/README.md | 491 -------------- vendor/github.com/securego/gosec/v2/USERS.md | 30 - vendor/github.com/securego/gosec/v2/action.yml | 19 - vendor/github.com/securego/gosec/v2/analyzer.go | 718 --------------------- .../securego/gosec/v2/analyzers/analyzers_set.go | 38 -- .../securego/gosec/v2/analyzers/analyzerslist.go | 95 --- .../gosec/v2/analyzers/conversion_overflow.go | 560 ---------------- .../securego/gosec/v2/analyzers/hardcodedNonce.go | 246 ------- .../securego/gosec/v2/analyzers/slice_bounds.go | 399 ------------ .../github.com/securego/gosec/v2/analyzers/util.go | 100 --- vendor/github.com/securego/gosec/v2/call_list.go | 118 ---- vendor/github.com/securego/gosec/v2/config.go | 137 ---- vendor/github.com/securego/gosec/v2/cosign.pub | 4 - vendor/github.com/securego/gosec/v2/cwe/data.go | 150 ----- vendor/github.com/securego/gosec/v2/cwe/types.go | 38 -- vendor/github.com/securego/gosec/v2/entrypoint.sh | 11 - vendor/github.com/securego/gosec/v2/errors.go | 33 - vendor/github.com/securego/gosec/v2/helpers.go | 555 ---------------- .../github.com/securego/gosec/v2/import_tracker.go | 78 --- vendor/github.com/securego/gosec/v2/install.sh | 377 ----------- vendor/github.com/securego/gosec/v2/issue/issue.go | 232 ------- vendor/github.com/securego/gosec/v2/perf-diff.sh | 44 -- vendor/github.com/securego/gosec/v2/renovate.json | 25 - vendor/github.com/securego/gosec/v2/report.go | 28 - vendor/github.com/securego/gosec/v2/resolve.go | 95 --- vendor/github.com/securego/gosec/v2/rule.go | 72 --- .../github.com/securego/gosec/v2/rules/archive.go | 66 -- vendor/github.com/securego/gosec/v2/rules/bind.go | 84 --- .../securego/gosec/v2/rules/blocklist.go | 109 ---- .../securego/gosec/v2/rules/decompression-bomb.go | 111 ---- .../securego/gosec/v2/rules/directory-traversal.go | 65 -- .../github.com/securego/gosec/v2/rules/errors.go | 122 ---- .../securego/gosec/v2/rules/fileperms.go | 176 ----- .../gosec/v2/rules/hardcoded_credentials.go | 394 ----------- .../securego/gosec/v2/rules/http_serve.go | 39 -- .../securego/gosec/v2/rules/implicit_aliasing.go | 148 ----- .../securego/gosec/v2/rules/integer_overflow.go | 90 --- .../securego/gosec/v2/rules/math_big_rat.go | 45 -- vendor/github.com/securego/gosec/v2/rules/pprof.go | 43 -- vendor/github.com/securego/gosec/v2/rules/rand.go | 63 -- .../github.com/securego/gosec/v2/rules/readfile.go | 153 ----- vendor/github.com/securego/gosec/v2/rules/rsa.go | 59 -- .../github.com/securego/gosec/v2/rules/rulelist.go | 134 ---- .../securego/gosec/v2/rules/slowloris.go | 71 -- vendor/github.com/securego/gosec/v2/rules/sql.go | 405 ------------ vendor/github.com/securego/gosec/v2/rules/ssh.go | 39 -- vendor/github.com/securego/gosec/v2/rules/ssrf.go | 67 -- .../github.com/securego/gosec/v2/rules/subproc.go | 123 ---- .../securego/gosec/v2/rules/tempfiles.go | 88 --- .../securego/gosec/v2/rules/templates.go | 64 -- vendor/github.com/securego/gosec/v2/rules/tls.go | 239 ------- .../securego/gosec/v2/rules/tls_config.go | 93 --- .../github.com/securego/gosec/v2/rules/unsafe.go | 54 -- .../securego/gosec/v2/rules/weakcrypto.go | 57 -- .../securego/gosec/v2/rules/weakcryptohash.go | 55 -- .../gosec/v2/rules/weakdepricatedcryptohash.go | 57 -- 62 files changed, 8399 deletions(-) delete mode 100644 vendor/github.com/securego/gosec/v2/.gitignore delete mode 100644 vendor/github.com/securego/gosec/v2/.golangci.yml delete mode 100644 vendor/github.com/securego/gosec/v2/.goreleaser.yml delete mode 100644 vendor/github.com/securego/gosec/v2/Dockerfile delete mode 100644 vendor/github.com/securego/gosec/v2/LICENSE.txt delete mode 100644 vendor/github.com/securego/gosec/v2/Makefile delete mode 100644 vendor/github.com/securego/gosec/v2/README.md delete mode 100644 vendor/github.com/securego/gosec/v2/USERS.md delete mode 100644 vendor/github.com/securego/gosec/v2/action.yml delete mode 100644 vendor/github.com/securego/gosec/v2/analyzer.go delete mode 100644 vendor/github.com/securego/gosec/v2/analyzers/analyzers_set.go delete mode 100644 vendor/github.com/securego/gosec/v2/analyzers/analyzerslist.go delete mode 100644 vendor/github.com/securego/gosec/v2/analyzers/conversion_overflow.go delete mode 100644 vendor/github.com/securego/gosec/v2/analyzers/hardcodedNonce.go delete mode 100644 vendor/github.com/securego/gosec/v2/analyzers/slice_bounds.go delete mode 100644 vendor/github.com/securego/gosec/v2/analyzers/util.go delete mode 100644 vendor/github.com/securego/gosec/v2/call_list.go delete mode 100644 vendor/github.com/securego/gosec/v2/config.go delete mode 100644 vendor/github.com/securego/gosec/v2/cosign.pub delete mode 100644 vendor/github.com/securego/gosec/v2/cwe/data.go delete mode 100644 vendor/github.com/securego/gosec/v2/cwe/types.go delete mode 100644 vendor/github.com/securego/gosec/v2/entrypoint.sh delete mode 100644 vendor/github.com/securego/gosec/v2/errors.go delete mode 100644 vendor/github.com/securego/gosec/v2/helpers.go delete mode 100644 vendor/github.com/securego/gosec/v2/import_tracker.go delete mode 100644 vendor/github.com/securego/gosec/v2/install.sh delete mode 100644 vendor/github.com/securego/gosec/v2/issue/issue.go delete mode 100644 vendor/github.com/securego/gosec/v2/perf-diff.sh delete mode 100644 vendor/github.com/securego/gosec/v2/renovate.json delete mode 100644 vendor/github.com/securego/gosec/v2/report.go delete mode 100644 vendor/github.com/securego/gosec/v2/resolve.go delete mode 100644 vendor/github.com/securego/gosec/v2/rule.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/archive.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/bind.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/blocklist.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/decompression-bomb.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/directory-traversal.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/errors.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/fileperms.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/hardcoded_credentials.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/http_serve.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/implicit_aliasing.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/integer_overflow.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/math_big_rat.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/pprof.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/rand.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/readfile.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/rsa.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/rulelist.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/slowloris.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/sql.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/ssh.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/ssrf.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/subproc.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/tempfiles.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/templates.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/tls.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/tls_config.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/unsafe.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/weakcrypto.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/weakcryptohash.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/weakdepricatedcryptohash.go (limited to 'vendor/github.com/securego') diff --git a/vendor/github.com/securego/gosec/v2/.gitignore b/vendor/github.com/securego/gosec/v2/.gitignore deleted file mode 100644 index 45460260f..000000000 --- a/vendor/github.com/securego/gosec/v2/.gitignore +++ /dev/null @@ -1,40 +0,0 @@ -# transient files -/image - -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so -*.swp -/gosec - -# Folders -_obj -_test -vendor -dist - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof - -.DS_Store - -.vscode -.idea - -# SBOMs generated during CI -/bom.json -1 \ No newline at end of file diff --git a/vendor/github.com/securego/gosec/v2/.golangci.yml b/vendor/github.com/securego/gosec/v2/.golangci.yml deleted file mode 100644 index c63a7cc5a..000000000 --- a/vendor/github.com/securego/gosec/v2/.golangci.yml +++ /dev/null @@ -1,49 +0,0 @@ -linters: - enable: - - asciicheck - - bodyclose - - copyloopvar - - dogsled - - durationcheck - - errcheck - - errorlint - - gci - - ginkgolinter - - gochecknoinits - - gofmt - - gofumpt - - goimports - - gosec - - gosimple - - govet - - importas - - ineffassign - - misspell - - nakedret - - nolintlint - - revive - - staticcheck - - typecheck - - unconvert - - unparam - - unused - - wastedassign - -linters-settings: - gci: - sections: - - standard - - default - - prefix(github.com/securego) - staticcheck: - checks: - - all - - '-SA1019' - - revive: - rules: - - name: dot-imports - disabled: true - -run: - timeout: 5m diff --git a/vendor/github.com/securego/gosec/v2/.goreleaser.yml b/vendor/github.com/securego/gosec/v2/.goreleaser.yml deleted file mode 100644 index bd85bab3a..000000000 --- a/vendor/github.com/securego/gosec/v2/.goreleaser.yml +++ /dev/null @@ -1,37 +0,0 @@ ---- -project_name: gosec - -release: - extra_files: - - glob: ./bom.json - github: - owner: securego - name: gosec - -builds: - - main: ./cmd/gosec/ - binary: gosec - goos: - - darwin - - linux - - windows - goarch: - - amd64 - - arm64 - - s390x - - ppc64le - ldflags: -X main.Version={{.Version}} -X main.GitTag={{.Tag}} -X main.BuildDate={{.Date}} - env: - - CGO_ENABLED=0 - -signs: -- cmd: cosign - stdin: '{{ .Env.COSIGN_PASSWORD}}' - args: - - "sign-blob" - - "--key=/tmp/cosign.key" - - "--output=${signature}" - - "${artifact}" - - "--yes" - artifacts: all - diff --git a/vendor/github.com/securego/gosec/v2/Dockerfile b/vendor/github.com/securego/gosec/v2/Dockerfile deleted file mode 100644 index 1bf94da7d..000000000 --- a/vendor/github.com/securego/gosec/v2/Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -ARG GO_VERSION -FROM golang:${GO_VERSION}-alpine AS builder -RUN apk add --no-cache ca-certificates make git curl gcc libc-dev \ - && mkdir -p /build -WORKDIR /build -COPY . /build/ -RUN go mod download \ - && make build-linux - -FROM golang:${GO_VERSION}-alpine -RUN apk add --no-cache ca-certificates bash git gcc libc-dev openssh -ENV GO111MODULE on -COPY --from=builder /build/gosec /bin/gosec -COPY entrypoint.sh /bin/entrypoint.sh -ENTRYPOINT ["/bin/entrypoint.sh"] diff --git a/vendor/github.com/securego/gosec/v2/LICENSE.txt b/vendor/github.com/securego/gosec/v2/LICENSE.txt deleted file mode 100644 index 1756c7821..000000000 --- a/vendor/github.com/securego/gosec/v2/LICENSE.txt +++ /dev/null @@ -1,154 +0,0 @@ -Apache License - -Version 2.0, January 2004 - -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and -distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright -owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities -that control, are controlled by, or are under common control with that entity. -For the purposes of this definition, "control" means (i) the power, direct or -indirect, to cause the direction or management of such entity, whether by -contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the -outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising -permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including -but not limited to software source code, documentation source, and configuration -files. - -"Object" form shall mean any form resulting from mechanical transformation or -translation of a Source form, including but not limited to compiled object code, -generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made -available under the License, as indicated by a copyright notice that is included -in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that -is based on (or derived from) the Work and for which the editorial revisions, -annotations, elaborations, or other modifications represent, as a whole, an -original work of authorship. For the purposes of this License, Derivative Works -shall not include works that remain separable from, or merely link (or bind by -name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version -of the Work and any modifications or additions to that Work or Derivative Works -thereof, that is intentionally submitted to Licensor for inclusion in the Work -by the copyright owner or by an individual or Legal Entity authorized to submit -on behalf of the copyright owner. For the purposes of this definition, -"submitted" means any form of electronic, verbal, or written communication sent -to the Licensor or its representatives, including but not limited to -communication on electronic mailing lists, source code control systems, and -issue tracking systems that are managed by, or on behalf of, the Licensor for -the purpose of discussing and improving the Work, but excluding communication -that is conspicuously marked or otherwise designated in writing by the copyright -owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf -of whom a Contribution has been received by Licensor and subsequently -incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of this -License, each Contributor hereby grants to You a perpetual, worldwide, -non-exclusive, no-charge, royalty-free, irrevocable copyright license to -reproduce, prepare Derivative Works of, publicly display, publicly perform, -sublicense, and distribute the Work and such Derivative Works in Source or -Object form. - -3. Grant of Patent License. Subject to the terms and conditions of this License, -each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, -no-charge, royalty-free, irrevocable (except as stated in this section) patent -license to make, have made, use, offer to sell, sell, import, and otherwise -transfer the Work, where such license applies only to those patent claims -licensable by such Contributor that are necessarily infringed by their -Contribution(s) alone or by combination of their Contribution(s) with the Work -to which such Contribution(s) was submitted. If You institute patent litigation -against any entity (including a cross-claim or counterclaim in a lawsuit) -alleging that the Work or a Contribution incorporated within the Work -constitutes direct or contributory patent infringement, then any patent licenses -granted to You under this License for that Work shall terminate as of the date -such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the Work or -Derivative Works thereof in any medium, with or without modifications, and in -Source or Object form, provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of -this License; and You must cause any modified files to carry prominent notices -stating that You changed the files; and You must retain, in the Source form of -any Derivative Works that You distribute, all copyright, patent, trademark, and -attribution notices from the Source form of the Work, excluding those notices -that do not pertain to any part of the Derivative Works; and If the Work -includes a "NOTICE" text file as part of its distribution, then any Derivative -Works that You distribute must include a readable copy of the attribution -notices contained within such NOTICE file, excluding those notices that do not -pertain to any part of the Derivative Works, in at least one of the following -places: within a NOTICE text file distributed as part of the Derivative Works; -within the Source form or documentation, if provided along with the Derivative -Works; or, within a display generated by the Derivative Works, if and wherever -such third-party notices normally appear. The contents of the NOTICE file are -for informational purposes only and do not modify the License. You may add Your -own attribution notices within Derivative Works that You distribute, alongside -or as an addendum to the NOTICE text from the Work, provided that such -additional attribution notices cannot be construed as modifying the License. - -You may add Your own copyright statement to Your modifications and may provide -additional or different license terms and conditions for use, reproduction, or -distribution of Your modifications, or for any such Derivative Works as a whole, -provided Your use, reproduction, and distribution of the Work otherwise complies -with the conditions stated in this License. 5. Submission of Contributions. -Unless You explicitly state otherwise, any Contribution intentionally submitted -for inclusion in the Work by You to the Licensor shall be under the terms and -conditions of this License, without any additional terms or conditions. -Notwithstanding the above, nothing herein shall supersede or modify the terms of -any separate license agreement you may have executed with Licensor regarding -such Contributions. - -6. Trademarks. This License does not grant permission to use the trade names, -trademarks, service marks, or product names of the Licensor, except as required -for reasonable and customary use in describing the origin of the Work and -reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or agreed to in -writing, Licensor provides the Work (and each Contributor provides its -Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied, including, without limitation, any warranties -or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A -PARTICULAR PURPOSE. You are solely responsible for determining the -appropriateness of using or redistributing the Work and assume any risks -associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, whether in -tort (including negligence), contract, or otherwise, unless required by -applicable law (such as deliberate and grossly negligent acts) or agreed to in -writing, shall any Contributor be liable to You for damages, including any -direct, indirect, special, incidental, or consequential damages of any character -arising as a result of this License or out of the use or inability to use the -Work (including but not limited to damages for loss of goodwill, work stoppage, -computer failure or malfunction, or any and all other commercial damages or -losses), even if such Contributor has been advised of the possibility of such -damages. - -9. Accepting Warranty or Additional Liability. While redistributing the Work or -Derivative Works thereof, You may choose to offer, and charge a fee for, -acceptance of support, warranty, indemnity, or other liability obligations -and/or rights consistent with this License. However, in accepting such -obligations, You may act only on Your own behalf and on Your sole -responsibility, not on behalf of any other Contributor, and only if You agree to -indemnify, defend, and hold each Contributor harmless for any liability incurred -by, or claims asserted against, such Contributor by reason of your accepting any -such warranty or additional liability. - -END OF TERMS AND CONDITIONS diff --git a/vendor/github.com/securego/gosec/v2/Makefile b/vendor/github.com/securego/gosec/v2/Makefile deleted file mode 100644 index bcfda6c1c..000000000 --- a/vendor/github.com/securego/gosec/v2/Makefile +++ /dev/null @@ -1,98 +0,0 @@ -GIT_TAG?= $(shell git describe --always --tags) -BIN = gosec -FMT_CMD = $(gofmt -s -l -w $(find . -type f -name '*.go' -not -path './vendor/*') | tee /dev/stderr) -IMAGE_REPO = securego -DATE_FMT=+%Y-%m-%d -ifdef SOURCE_DATE_EPOCH - BUILD_DATE ?= $(shell date -u -d "@$(SOURCE_DATE_EPOCH)" "$(DATE_FMT)" 2>/dev/null || date -u -r "$(SOURCE_DATE_EPOCH)" "$(DATE_FMT)" 2>/dev/null || date -u "$(DATE_FMT)") -else - BUILD_DATE ?= $(shell date "$(DATE_FMT)") -endif -BUILDFLAGS := "-w -s -X 'main.Version=$(GIT_TAG)' -X 'main.GitTag=$(GIT_TAG)' -X 'main.BuildDate=$(BUILD_DATE)'" -CGO_ENABLED = 0 -GO := GO111MODULE=on go -GOPATH ?= $(shell $(GO) env GOPATH) -GOBIN ?= $(GOPATH)/bin -GOSEC ?= $(GOBIN)/gosec -GINKGO ?= $(GOBIN)/ginkgo -GO_MINOR_VERSION = $(shell $(GO) version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f2) -GOVULN_MIN_VERSION = 17 -GO_VERSION = 1.23 - -default: - $(MAKE) build - -install-test-deps: - go install github.com/onsi/ginkgo/v2/ginkgo@latest - go install golang.org/x/crypto/...@latest - go install github.com/lib/pq/...@latest - -install-govulncheck: - @if [ $(GO_MINOR_VERSION) -gt $(GOVULN_MIN_VERSION) ]; then \ - go install golang.org/x/vuln/cmd/govulncheck@latest; \ - fi - -test: install-test-deps build-race fmt vet sec govulncheck - $(GINKGO) -v --fail-fast - -fmt: - @echo "FORMATTING" - @FORMATTED=`$(GO) fmt ./...` - @([ ! -z "$(FORMATTED)" ] && printf "Fixed unformatted files:\n$(FORMATTED)") || true - -vet: - @echo "VETTING" - $(GO) vet ./... - -golangci: - @echo "LINTING: golangci-lint" - golangci-lint run - -sec: - @echo "SECURITY SCANNING" - ./$(BIN) ./... - -govulncheck: install-govulncheck - @echo "CHECKING VULNERABILITIES" - @if [ $(GO_MINOR_VERSION) -gt $(GOVULN_MIN_VERSION) ]; then \ - govulncheck ./...; \ - fi - -test-coverage: install-test-deps - go test -race -v -count=1 -coverprofile=coverage.out ./... - -build: - go build -o $(BIN) ./cmd/gosec/ - -build-race: - go build -race -o $(BIN) ./cmd/gosec/ - -clean: - rm -rf build vendor dist coverage.out - rm -f release image $(BIN) - -release: - @echo "Releasing the gosec binary..." - goreleaser release - -build-linux: - CGO_ENABLED=$(CGO_ENABLED) GOOS=linux go build -ldflags=$(BUILDFLAGS) -o $(BIN) ./cmd/gosec/ - -image: - @echo "Building the Docker image..." - docker build -t $(IMAGE_REPO)/$(BIN):$(GIT_TAG) --build-arg GO_VERSION=$(GO_VERSION) . - docker tag $(IMAGE_REPO)/$(BIN):$(GIT_TAG) $(IMAGE_REPO)/$(BIN):latest - touch image - -image-push: image - @echo "Pushing the Docker image..." - docker push $(IMAGE_REPO)/$(BIN):$(GIT_TAG) - docker push $(IMAGE_REPO)/$(BIN):latest - -tlsconfig: - go generate ./... - -perf-diff: - ./perf-diff.sh - -.PHONY: test build clean release image image-push tlsconfig perf-diff diff --git a/vendor/github.com/securego/gosec/v2/README.md b/vendor/github.com/securego/gosec/v2/README.md deleted file mode 100644 index 7b8b526a8..000000000 --- a/vendor/github.com/securego/gosec/v2/README.md +++ /dev/null @@ -1,491 +0,0 @@ - -# gosec - Go Security Checker - -Inspects source code for security problems by scanning the Go AST and SSA code representation. - - - -## License - -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 [here](http://www.apache.org/licenses/LICENSE-2.0). - -## Project status - -[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/3218/badge)](https://bestpractices.coreinfrastructure.org/projects/3218) -[![Build Status](https://github.com/securego/gosec/workflows/CI/badge.svg)](https://github.com/securego/gosec/actions?query=workflows%3ACI) -[![Coverage Status](https://codecov.io/gh/securego/gosec/branch/master/graph/badge.svg)](https://codecov.io/gh/securego/gosec) -[![GoReport](https://goreportcard.com/badge/github.com/securego/gosec)](https://goreportcard.com/report/github.com/securego/gosec) -[![GoDoc](https://pkg.go.dev/badge/github.com/securego/gosec/v2)](https://pkg.go.dev/github.com/securego/gosec/v2) -[![Docs](https://readthedocs.org/projects/docs/badge/?version=latest)](https://securego.io/) -[![Downloads](https://img.shields.io/github/downloads/securego/gosec/total.svg)](https://github.com/securego/gosec/releases) -[![Docker Pulls](https://img.shields.io/docker/pulls/securego/gosec.svg)](https://hub.docker.com/r/securego/gosec/tags) -[![Slack](https://img.shields.io/badge/Slack-4A154B?style=for-the-badge&logo=slack&logoColor=white)](http://securego.slack.com) - -## Install - -### CI Installation - -```bash -# binary will be $(go env GOPATH)/bin/gosec -curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s -- -b $(go env GOPATH)/bin vX.Y.Z - -# or install it into ./bin/ -curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s vX.Y.Z - -# In alpine linux (as it does not come with curl by default) -wget -O - -q https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s vX.Y.Z - -# If you want to use the checksums provided on the "Releases" page -# 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 -# and you can check the checksum like this -echo " gosec_vX.Y.Z_OS.tar.gz" | sha256sum -c - - -gosec --help -``` - -### GitHub Action - -You can run `gosec` as a GitHub action as follows: - -```yaml -name: Run Gosec -on: - push: - branches: - - master - pull_request: - branches: - - master -jobs: - tests: - runs-on: ubuntu-latest - env: - GO111MODULE: on - steps: - - name: Checkout Source - uses: actions/checkout@v3 - - name: Run Gosec Security Scanner - uses: securego/gosec@master - with: - args: ./... -``` - -### Integrating with code scanning - -You can [integrate third-party code analysis tools](https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/integrating-with-code-scanning) with GitHub code scanning by uploading data as SARIF files. - -The workflow shows an example of running the `gosec` as a step in a GitHub action workflow which outputs the `results.sarif` file. The workflow then uploads the `results.sarif` file to GitHub using the `upload-sarif` action. - -```yaml -name: "Security Scan" - -# Run workflow each time code is pushed to your repository and on a schedule. -# The scheduled workflow runs every at 00:00 on Sunday UTC time. -on: - push: - schedule: - - cron: '0 0 * * 0' - -jobs: - tests: - runs-on: ubuntu-latest - env: - GO111MODULE: on - steps: - - name: Checkout Source - uses: actions/checkout@v3 - - name: Run Gosec Security Scanner - uses: securego/gosec@master - with: - # we let the report trigger content trigger a failure using the GitHub Security features. - args: '-no-fail -fmt sarif -out results.sarif ./...' - - name: Upload SARIF file - uses: github/codeql-action/upload-sarif@v2 - with: - # Path to SARIF file relative to the root of the repository - sarif_file: results.sarif -``` - -### Local Installation - -```bash -go install github.com/securego/gosec/v2/cmd/gosec@latest -``` - -## Usage - -Gosec can be configured to only run a subset of rules, to exclude certain file -paths, and produce reports in different formats. By default all rules will be -run against the supplied input files. To recursively scan from the current -directory you can supply `./...` as the input argument. - -### Available rules - -- G101: Look for hard coded credentials -- G102: Bind to all interfaces -- G103: Audit the use of unsafe block -- G104: Audit errors not checked -- G106: Audit the use of ssh.InsecureIgnoreHostKey -- G107: Url provided to HTTP request as taint input -- G108: Profiling endpoint automatically exposed on /debug/pprof -- G109: Potential Integer overflow made by strconv.Atoi result conversion to int16/32 -- G110: Potential DoS vulnerability via decompression bomb -- G111: Potential directory traversal -- G112: Potential slowloris attack -- G113: Usage of Rat.SetString in math/big with an overflow (CVE-2022-23772) -- G114: Use of net/http serve function that has no support for setting timeouts -- G115: Potential integer overflow when converting between integer types -- G201: SQL query construction using format string -- G202: SQL query construction using string concatenation -- G203: Use of unescaped data in HTML templates -- G204: Audit use of command execution -- G301: Poor file permissions used when creating a directory -- G302: Poor file permissions used with chmod -- G303: Creating tempfile using a predictable path -- G304: File path provided as taint input -- G305: File traversal when extracting zip/tar archive -- G306: Poor file permissions used when writing to a new file -- G307: Poor file permissions used when creating a file with os.Create -- G401: Detect the usage of MD5 or SHA1 -- G402: Look for bad TLS connection settings -- G403: Ensure minimum RSA key length of 2048 bits -- G404: Insecure random number source (rand) -- G405: Detect the usage of DES or RC4 -- G406: Detect the usage of MD4 or RIPEMD160 -- G407: Detect the usage of hardcoded Initialization Vector(IV)/Nonce -- 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 -- G506: Import blocklist: golang.org/x/crypto/md4 -- G507: Import blocklist: golang.org/x/crypto/ripemd160 -- G601: Implicit memory aliasing of items from a range statement (only for Go 1.21 or lower) -- G602: Slice access out of bounds - -### Retired rules - -- G105: Audit the use of math/big.Int.Exp - [CVE is fixed](https://github.com/golang/go/issues/15184) -- G307: Deferring a method which returns an error - causing more inconvenience than fixing a security issue, despite the details from this [blog post](https://www.joeshaw.org/dont-defer-close-on-writable-files/) - -### Selecting rules - -By default, gosec will run all rules against the supplied file paths. It is however possible to select a subset of rules to run via the `-include=` flag, -or to specify a set of rules to explicitly exclude using the `-exclude=` flag. - -```bash -# Run a specific set of rules -$ gosec -include=G101,G203,G401 ./... - -# Run everything except for rule G303 -$ 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/master/issue/issue.go#L50). - -### Configuration - -A number of global settings can be provided in a configuration file as follows: - -```JSON -{ - "global": { - "nosec": "enabled", - "audit": "enabled" - } -} -``` - -- `nosec`: this setting will overwrite all `#nosec` directives defined throughout the code base -- `audit`: runs in audit mode which enables addition checks that for normal code analysis might be too nosy - -```bash -# 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 -of functions which will be skipped when auditing the not checked errors: - -```JSON -{ - "G104": { - "ioutil": ["WriteFile"] - } -} -``` - -You can also configure the hard-coded credentials rule `G101` with additional patterns, or adjust the entropy threshold: - -```JSON -{ - "G101": { - "pattern": "(?i)passwd|pass|password|pwd|secret|private_key|token", - "ignore_entropy": false, - "entropy_threshold": "80.0", - "per_char_threshold": "3.0", - "truncate": "32" - } -} -``` - -#### Go version - -Some rules require a specific Go version which is retrieved from the Go module file present in the project. If this version cannot be found, it will fallback to Go runtime version. - -The Go module version is parsed using the `go list` command which in some cases might lead to performance degradation. In this situation, the go module version can be easily provided by setting the environment variable `GOSECGOVERSION=go1.21.1`. - -### 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. - -The scanning of test files can be enabled with the following flag: - -```bash -gosec -tests ./... -``` - -Also additional folders can be excluded as follows: - -```bash - gosec -exclude-dir=rules -exclude-dir=cmd ./... -``` - -### Excluding generated files - -gosec can ignore generated go files with default generated code comment. - -``` -// Code generated by some generator DO NOT EDIT. -``` - -```bash -gosec -exclude-generated ./... -``` - -### Auto fixing vulnerabilities -gosec can suggest fixes based on AI recommendation. It will call an AI API to receive a suggestion for a security finding. - -You can enable this feature by providing the following command line arguments: -- `ai-api-provider`: the name of the AI API provider, currently only `gemini`is supported. -- `ai-api-key` or set the environment variable `GOSEC_AI_API_KEY`: the key to access the AI API, -For gemini, you can create an API key following [these instructions](https://ai.google.dev/gemini-api/docs/api-key). -- `ai-endpoint`: the endpoint of the AI provider, this is optional argument. - - -```bash -gosec -ai-api-provider="gemini" -ai-api-key="your_key" ./... -``` - -### Annotating code - -As with all automated detection tools, there will be cases of false positives. -In cases where gosec reports a failure that has been manually verified as being safe, -it is possible to annotate the code with a comment that starts with `#nosec`. - -The `#nosec` comment should have the format `#nosec [RuleList] [-- Justification]`. - -The `#nosec` comment needs to be placed on the line where the warning is reported. - -```go -func main() { - tr := &http.Transport{ - TLSClientConfig: &tls.Config{ - InsecureSkipVerify: true, // #nosec G402 - }, - } - - client := &http.Client{Transport: tr} - _, err := client.Get("https://golang.org/") - if err != nil { - fmt.Println(err) - } -} -``` - -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 -the `#nosec` annotation, e.g: `/* #nosec G401 */` or `//#nosec G201 G202 G203` - -You could put the description or justification text for the annotation. The -justification should be after the rule(s) to suppress and start with two or -more dashes, e.g: `//#nosec G101 G102 -- This is a false positive` - -In some cases you may also want to revisit places where `#nosec` annotations -have been used. To run the scanner and ignore any `#nosec` annotations you -can do the following: - -```bash -gosec -nosec=true ./... -``` - -### Tracking suppressions - -As described above, we could suppress violations externally (using `-include`/ -`-exclude`) or inline (using `#nosec` annotations) in gosec. This suppression -inflammation can be used to generate corresponding signals for auditing -purposes. - -We could track suppressions by the `-track-suppressions` flag as follows: - -```bash -gosec -track-suppressions -exclude=G101 -fmt=sarif -out=results.sarif ./... -``` - -- For external suppressions, gosec records suppression info where `kind` is -`external` and `justification` is a certain sentence "Globally suppressed". -- For inline suppressions, gosec records suppression info where `kind` is -`inSource` and `justification` is the text after two or more dashes in the -comment. - -**Note:** Only SARIF and JSON formats support tracking suppressions. - -### Build tags - -gosec is able to pass your [Go build tags](https://golang.org/pkg/go/build/) to the analyzer. -They can be provided as a comma separated list as follows: - -```bash -gosec -tags debug,ignore ./... -``` - -### Output formats - -gosec currently supports `text`, `json`, `yaml`, `csv`, `sonarqube`, `JUnit XML`, `html` and `golint` output formats. By default -results will be reported to stdout, but can also be written to an output -file. The output format is controlled by the `-fmt` flag, and the output file is controlled by the `-out` flag as follows: - -```bash -# Write output in json format to results.json -$ gosec -fmt=json -out=results.json *.go -``` - -Results will be reported to stdout as well as to the provided output file by `-stdout` flag. The `-verbose` flag overrides the -output format when stdout the results while saving them in the output file -```bash -# Write output in json format to results.json as well as stdout -$ gosec -fmt=json -out=results.json -stdout *.go - -# Overrides the output format to 'text' when stdout the results, while writing it to results.json -$ gosec -fmt=json -out=results.json -stdout -verbose=text *.go -``` - -**Note:** gosec generates the [generic issue import format](https://docs.sonarqube.org/latest/analysis/generic-issue/) for SonarQube, and a report has to be imported into SonarQube using `sonar.externalIssuesReportPaths=path/to/gosec-report.json`. - -## Development - -### Build - -You can build the binary with: - -```bash -make -``` - -### Note on Sarif Types Generation - -Install the tool with : - -```bash -go get -u github.com/a-h/generate/cmd/schema-generate -``` - -Then generate the types with : - -```bash -schema-generate -i sarif-schema-2.1.0.json -o mypath/types.go -``` - -Most of the MarshallJSON/UnmarshalJSON are removed except the one for PropertyBag which is handy to inline the additional properties. The rest can be removed. -The URI,ID, UUID, GUID were renamed so it fits the Go convention defined [here](https://github.com/golang/lint/blob/master/lint.go#L700) - -### Tests - -You can run all unit tests using: - -```bash -make test -``` - -### Release - -You can create a release by tagging the version as follows: - -``` bash -git tag v1.0.0 -m "Release version v1.0.0" -git push origin v1.0.0 -``` - -The GitHub [release workflow](.github/workflows/release.yml) triggers immediately after the tag is pushed upstream. This flow will -release the binaries using the [goreleaser](https://goreleaser.com/actions/) action and then it will build and publish the docker image into Docker Hub. - -The released artifacts are signed using [cosign](https://docs.sigstore.dev/). You can use the public key from [cosign.pub](cosign.pub) -file to verify the signature of docker image and binaries files. - -The docker image signature can be verified with the following command: -``` -cosign verify --key cosign.pub securego/gosec: -``` - -The binary files signature can be verified with the following command: -``` -cosign verify-blob --key cosign.pub --signature gosec__darwin_amd64.tar.gz.sig gosec__darwin_amd64.tar.gz -``` - -### Docker image - -You can also build locally the docker image by using the command: - -```bash -make image -``` - -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 -docker run --rm -it -w // -v /:/ securego/gosec //... -``` - -**Note:** the current working directory needs to be set with `-w` option in order to get successfully resolved the dependencies from go module file - -### Generate TLS rule - -The configuration of TLS rule can be generated from [Mozilla's TLS ciphers recommendation](https://statics.tls.security.mozilla.org/server-side-tls-conf.json). - -First you need to install the generator tool: - -```bash -go get github.com/securego/gosec/v2/cmd/tlsconfig/... -``` - -You can invoke now the `go generate` in the root of the project: - -```bash -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. - -## Sponsors - -Support this project by becoming a sponsor. Your logo will show up here with a link to your website - - diff --git a/vendor/github.com/securego/gosec/v2/USERS.md b/vendor/github.com/securego/gosec/v2/USERS.md deleted file mode 100644 index 9b6e4eeee..000000000 --- a/vendor/github.com/securego/gosec/v2/USERS.md +++ /dev/null @@ -1,30 +0,0 @@ -# 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) -10. [Checkmarx](https://www.checkmarx.com/) -11. [SeatGeek](https://www.seatgeek.com/) -12. [reMarkable](https://remarkable.com) - -## Projects - -1. [golangci-lint](https://github.com/golangci/golangci-lint) -2. [Kubernetes](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) -9. [KICS](https://github.com/Checkmarx/kics) diff --git a/vendor/github.com/securego/gosec/v2/action.yml b/vendor/github.com/securego/gosec/v2/action.yml deleted file mode 100644 index 2b2deaab7..000000000 --- a/vendor/github.com/securego/gosec/v2/action.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: 'Gosec Security Checker' -description: 'Runs the gosec security checker' -author: '@ccojocar' - -inputs: - args: - description: 'Arguments for gosec' - required: true - default: '-h' - -runs: - using: 'docker' - image: 'docker://securego/gosec:2.21.3' - args: - - ${{ inputs.args }} - -branding: - icon: 'shield' - color: 'blue' diff --git a/vendor/github.com/securego/gosec/v2/analyzer.go b/vendor/github.com/securego/gosec/v2/analyzer.go deleted file mode 100644 index bfa7e1940..000000000 --- a/vendor/github.com/securego/gosec/v2/analyzer.go +++ /dev/null @@ -1,718 +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 gosec holds the central scanning logic used by gosec security scanner -package gosec - -import ( - "fmt" - "go/ast" - "go/build" - "go/token" - "go/types" - "log" - "os" - "path" - "path/filepath" - "reflect" - "regexp" - "strconv" - "strings" - "sync" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/buildssa" - "golang.org/x/tools/go/packages" - - "github.com/securego/gosec/v2/analyzers" - "github.com/securego/gosec/v2/issue" -) - -// LoadMode controls the amount of details to return when loading the packages -const LoadMode = packages.NeedName | - packages.NeedFiles | - packages.NeedCompiledGoFiles | - packages.NeedImports | - packages.NeedTypes | - packages.NeedTypesSizes | - packages.NeedTypesInfo | - packages.NeedSyntax | - packages.NeedModule | - packages.NeedEmbedFiles | - packages.NeedEmbedPatterns - -const externalSuppressionJustification = "Globally suppressed." - -const aliasOfAllRules = "*" - -type ignore struct { - start int - end int - suppressions map[string][]issue.SuppressionInfo -} - -type ignores map[string][]ignore - -func newIgnores() ignores { - return make(map[string][]ignore) -} - -func (i ignores) parseLine(line string) (int, int) { - parts := strings.Split(line, "-") - start, err := strconv.Atoi(parts[0]) - if err != nil { - start = 0 - } - end := start - if len(parts) > 1 { - if e, err := strconv.Atoi(parts[1]); err == nil { - end = e - } - } - return start, end -} - -func (i ignores) add(file string, line string, suppressions map[string]issue.SuppressionInfo) { - is := []ignore{} - if _, ok := i[file]; ok { - is = i[file] - } - found := false - start, end := i.parseLine(line) - for _, ig := range is { - if ig.start <= start && ig.end >= end { - found = true - for r, s := range suppressions { - ss, ok := ig.suppressions[r] - if !ok { - ss = []issue.SuppressionInfo{} - } - ss = append(ss, s) - ig.suppressions[r] = ss - } - break - } - } - if !found { - ig := ignore{ - start: start, - end: end, - suppressions: map[string][]issue.SuppressionInfo{}, - } - for r, s := range suppressions { - ig.suppressions[r] = []issue.SuppressionInfo{s} - } - is = append(is, ig) - } - i[file] = is -} - -func (i ignores) get(file string, line string) map[string][]issue.SuppressionInfo { - start, end := i.parseLine(line) - if is, ok := i[file]; ok { - for _, i := range is { - if i.start <= start && i.end >= end || start <= i.start && end >= i.end { - return i.suppressions - } - } - } - return map[string][]issue.SuppressionInfo{} -} - -// The Context is populated with data parsed from the source code as it is scanned. -// It is passed through to all rule functions as they are called. Rules may use -// this data in conjunction with the encountered AST node. -type Context struct { - FileSet *token.FileSet - Comments ast.CommentMap - Info *types.Info - Pkg *types.Package - PkgFiles []*ast.File - Root *ast.File - Imports *ImportTracker - Config Config - Ignores ignores - PassedValues map[string]interface{} -} - -// GetFileAtNodePos returns the file at the node position in the file set available in the context. -func (ctx *Context) GetFileAtNodePos(node ast.Node) *token.File { - return ctx.FileSet.File(node.Pos()) -} - -// NewIssue creates a new issue -func (ctx *Context) NewIssue(node ast.Node, ruleID, desc string, - severity, confidence issue.Score, -) *issue.Issue { - return issue.New(ctx.GetFileAtNodePos(node), node, ruleID, desc, severity, confidence) -} - -// Metrics used when reporting information about a scanning run. -type Metrics struct { - NumFiles int `json:"files"` - NumLines int `json:"lines"` - NumNosec int `json:"nosec"` - NumFound int `json:"found"` -} - -// Analyzer object is the main object of gosec. It has methods traverse an AST -// and invoke the correct checking rules as on each node as required. -type Analyzer struct { - ignoreNosec bool - ruleset RuleSet - context *Context - config Config - logger *log.Logger - issues []*issue.Issue - stats *Metrics - errors map[string][]Error // keys are file paths; values are the golang errors in those files - tests bool - excludeGenerated bool - showIgnored bool - trackSuppressions bool - concurrency int - analyzerSet *analyzers.AnalyzerSet - mu sync.Mutex -} - -// NewAnalyzer builds a new analyzer. -func NewAnalyzer(conf Config, tests bool, excludeGenerated bool, trackSuppressions bool, concurrency int, logger *log.Logger) *Analyzer { - ignoreNoSec := false - if enabled, err := conf.IsGlobalEnabled(Nosec); err == nil { - ignoreNoSec = enabled - } - showIgnored := false - if enabled, err := conf.IsGlobalEnabled(ShowIgnored); err == nil { - showIgnored = enabled - } - if logger == nil { - logger = log.New(os.Stderr, "[gosec]", log.LstdFlags) - } - return &Analyzer{ - ignoreNosec: ignoreNoSec, - showIgnored: showIgnored, - ruleset: NewRuleSet(), - context: &Context{}, - config: conf, - logger: logger, - issues: make([]*issue.Issue, 0, 16), - stats: &Metrics{}, - errors: make(map[string][]Error), - tests: tests, - concurrency: concurrency, - excludeGenerated: excludeGenerated, - trackSuppressions: trackSuppressions, - analyzerSet: analyzers.NewAnalyzerSet(), - } -} - -// SetConfig updates the analyzer configuration -func (gosec *Analyzer) SetConfig(conf Config) { - gosec.config = conf -} - -// Config returns the current configuration -func (gosec *Analyzer) Config() Config { - return gosec.config -} - -// LoadRules instantiates all the rules to be used when analyzing source -// packages -func (gosec *Analyzer) LoadRules(ruleDefinitions map[string]RuleBuilder, ruleSuppressed map[string]bool) { - for id, def := range ruleDefinitions { - r, nodes := def(id, gosec.config) - gosec.ruleset.Register(r, ruleSuppressed[id], nodes...) - } -} - -// LoadAnalyzers instantiates all the analyzers to be used when analyzing source -// packages -func (gosec *Analyzer) LoadAnalyzers(analyzerDefinitions map[string]analyzers.AnalyzerDefinition, analyzerSuppressed map[string]bool) { - for id, def := range analyzerDefinitions { - r := def.Create(def.ID, def.Description) - gosec.analyzerSet.Register(r, analyzerSuppressed[id]) - } -} - -// Process kicks off the analysis process for a given package -func (gosec *Analyzer) Process(buildTags []string, packagePaths ...string) error { - config := &packages.Config{ - Mode: LoadMode, - BuildFlags: buildTags, - Tests: gosec.tests, - } - - type result struct { - pkgPath string - pkgs []*packages.Package - err error - } - - results := make(chan result) - jobs := make(chan string, len(packagePaths)) - quit := make(chan struct{}) - - var wg sync.WaitGroup - - worker := func(j chan string, r chan result, quit chan struct{}) { - for { - select { - case s := <-j: - pkgs, err := gosec.load(s, config) - select { - case r <- result{pkgPath: s, pkgs: pkgs, err: err}: - case <-quit: - // we've been told to stop, probably an error while - // processing a previous result. - wg.Done() - return - } - default: - // j is empty and there are no jobs left - wg.Done() - return - } - } - } - - // fill the buffer - for _, pkgPath := range packagePaths { - jobs <- pkgPath - } - - for i := 0; i < gosec.concurrency; i++ { - wg.Add(1) - go worker(jobs, results, quit) - } - - go func() { - wg.Wait() - close(results) - }() - - for r := range results { - if r.err != nil { - gosec.AppendError(r.pkgPath, r.err) - } - for _, pkg := range r.pkgs { - if pkg.Name != "" { - err := gosec.ParseErrors(pkg) - if err != nil { - close(quit) - wg.Wait() // wait for the goroutines to stop - return fmt.Errorf("parsing errors in pkg %q: %w", pkg.Name, err) - } - gosec.CheckRules(pkg) - gosec.CheckAnalyzers(pkg) - } - } - } - sortErrors(gosec.errors) - return nil -} - -func (gosec *Analyzer) load(pkgPath string, conf *packages.Config) ([]*packages.Package, error) { - abspath, err := GetPkgAbsPath(pkgPath) - if err != nil { - gosec.logger.Printf("Skipping: %s. Path doesn't exist.", abspath) - return []*packages.Package{}, nil - } - - gosec.logger.Println("Import directory:", abspath) - // step 1/3 create build context. - buildD := build.Default - // step 2/3: add build tags to get env dependent files into basePackage. - gosec.mu.Lock() - buildD.BuildTags = conf.BuildFlags - gosec.mu.Unlock() - basePackage, err := buildD.ImportDir(pkgPath, build.ImportComment) - if err != nil { - return []*packages.Package{}, fmt.Errorf("importing dir %q: %w", pkgPath, err) - } - - var packageFiles []string - for _, filename := range basePackage.GoFiles { - packageFiles = append(packageFiles, path.Join(pkgPath, filename)) - } - for _, filename := range basePackage.CgoFiles { - packageFiles = append(packageFiles, path.Join(pkgPath, filename)) - } - - if gosec.tests { - testsFiles := make([]string, 0) - testsFiles = append(testsFiles, basePackage.TestGoFiles...) - testsFiles = append(testsFiles, basePackage.XTestGoFiles...) - for _, filename := range testsFiles { - packageFiles = append(packageFiles, path.Join(pkgPath, filename)) - } - } - - // step 3/3 remove build tags from conf to proceed build correctly. - gosec.mu.Lock() - conf.BuildFlags = nil - defer gosec.mu.Unlock() - pkgs, err := packages.Load(conf, packageFiles...) - if err != nil { - return []*packages.Package{}, fmt.Errorf("loading files from package %q: %w", pkgPath, err) - } - return pkgs, nil -} - -// CheckRules runs analysis on the given package. -func (gosec *Analyzer) CheckRules(pkg *packages.Package) { - gosec.logger.Println("Checking package:", pkg.Name) - for _, file := range pkg.Syntax { - fp := pkg.Fset.File(file.Pos()) - if fp == nil { - // skip files which cannot be located - continue - } - checkedFile := fp.Name() - // Skip the no-Go file from analysis (e.g. a Cgo files is expanded in 3 different files - // stored in the cache which do not need to by analyzed) - if filepath.Ext(checkedFile) != ".go" { - continue - } - if gosec.excludeGenerated && ast.IsGenerated(file) { - gosec.logger.Println("Ignoring generated file:", checkedFile) - continue - } - - gosec.logger.Println("Checking file:", checkedFile) - gosec.context.FileSet = pkg.Fset - gosec.context.Config = gosec.config - gosec.context.Comments = ast.NewCommentMap(gosec.context.FileSet, file, file.Comments) - gosec.context.Root = file - gosec.context.Info = pkg.TypesInfo - gosec.context.Pkg = pkg.Types - gosec.context.PkgFiles = pkg.Syntax - gosec.context.Imports = NewImportTracker() - gosec.context.PassedValues = make(map[string]interface{}) - gosec.updateIgnores() - ast.Walk(gosec, file) - gosec.stats.NumFiles++ - gosec.stats.NumLines += pkg.Fset.File(file.Pos()).LineCount() - } -} - -// CheckAnalyzers runs analyzers on a given package. -func (gosec *Analyzer) CheckAnalyzers(pkg *packages.Package) { - ssaResult, err := gosec.buildSSA(pkg) - if err != nil || ssaResult == nil { - gosec.logger.Printf("Error building the SSA representation of the package %q: %s", pkg.Name, err) - return - } - - resultMap := map[*analysis.Analyzer]interface{}{ - buildssa.Analyzer: &analyzers.SSAAnalyzerResult{ - Config: gosec.Config(), - Logger: gosec.logger, - SSA: ssaResult.(*buildssa.SSA), - }, - } - - generatedFiles := gosec.generatedFiles(pkg) - - for _, analyzer := range gosec.analyzerSet.Analyzers { - pass := &analysis.Pass{ - Analyzer: analyzer, - Fset: pkg.Fset, - Files: pkg.Syntax, - OtherFiles: pkg.OtherFiles, - IgnoredFiles: pkg.IgnoredFiles, - Pkg: pkg.Types, - TypesInfo: pkg.TypesInfo, - TypesSizes: pkg.TypesSizes, - ResultOf: resultMap, - Report: func(d analysis.Diagnostic) {}, - ImportObjectFact: nil, - ExportObjectFact: nil, - ImportPackageFact: nil, - ExportPackageFact: nil, - AllObjectFacts: nil, - AllPackageFacts: nil, - } - result, err := pass.Analyzer.Run(pass) - if err != nil { - gosec.logger.Printf("Error running analyzer %s: %s\n", analyzer.Name, err) - continue - } - if result != nil { - if passIssues, ok := result.([]*issue.Issue); ok { - for _, iss := range passIssues { - if gosec.excludeGenerated { - if _, ok := generatedFiles[iss.File]; ok { - continue - } - } - gosec.updateIssues(iss) - } - } - } - } -} - -func (gosec *Analyzer) generatedFiles(pkg *packages.Package) map[string]bool { - generatedFiles := map[string]bool{} - for _, file := range pkg.Syntax { - if ast.IsGenerated(file) { - fp := pkg.Fset.File(file.Pos()) - if fp == nil { - // skip files which cannot be located - continue - } - generatedFiles[fp.Name()] = true - } - } - return generatedFiles -} - -// buildSSA runs the SSA pass which builds the SSA representation of the package. It handles gracefully any panic. -func (gosec *Analyzer) buildSSA(pkg *packages.Package) (interface{}, error) { - defer func() { - if r := recover(); r != nil { - gosec.logger.Printf("Panic when running SSA analyser on package: %s", pkg.Name) - } - }() - ssaPass := &analysis.Pass{ - Analyzer: buildssa.Analyzer, - Fset: pkg.Fset, - Files: pkg.Syntax, - OtherFiles: pkg.OtherFiles, - IgnoredFiles: pkg.IgnoredFiles, - Pkg: pkg.Types, - TypesInfo: pkg.TypesInfo, - TypesSizes: pkg.TypesSizes, - ResultOf: nil, - Report: nil, - ImportObjectFact: nil, - ExportObjectFact: nil, - ImportPackageFact: nil, - ExportPackageFact: nil, - AllObjectFacts: nil, - AllPackageFacts: nil, - } - - return ssaPass.Analyzer.Run(ssaPass) -} - -// ParseErrors parses the errors from given package -func (gosec *Analyzer) ParseErrors(pkg *packages.Package) error { - if len(pkg.Errors) == 0 { - return nil - } - for _, pkgErr := range pkg.Errors { - parts := strings.Split(pkgErr.Pos, ":") - file := parts[0] - var err error - var line int - if len(parts) > 1 { - if line, err = strconv.Atoi(parts[1]); err != nil { - return fmt.Errorf("parsing line: %w", err) - } - } - var column int - if len(parts) > 2 { - if column, err = strconv.Atoi(parts[2]); err != nil { - return fmt.Errorf("parsing column: %w", err) - } - } - msg := strings.TrimSpace(pkgErr.Msg) - newErr := NewError(line, column, msg) - if errSlice, ok := gosec.errors[file]; ok { - gosec.errors[file] = append(errSlice, *newErr) - } else { - errSlice = []Error{} - gosec.errors[file] = append(errSlice, *newErr) - } - } - return nil -} - -// AppendError appends an error to the file errors -func (gosec *Analyzer) AppendError(file string, err error) { - // Do not report the error for empty packages (e.g. files excluded from build with a tag) - r := regexp.MustCompile(`no buildable Go source files in`) - if r.MatchString(err.Error()) { - return - } - errors := make([]Error, 0) - if ferrs, ok := gosec.errors[file]; ok { - errors = ferrs - } - ferr := NewError(0, 0, err.Error()) - errors = append(errors, *ferr) - gosec.errors[file] = errors -} - -// ignore a node (and sub-tree) if it is tagged with a nosec tag comment -func (gosec *Analyzer) ignore(n ast.Node) map[string]issue.SuppressionInfo { - if groups, ok := gosec.context.Comments[n]; ok && !gosec.ignoreNosec { - - // Checks if an alternative for #nosec is set and, if not, uses the default. - noSecDefaultTag, err := gosec.config.GetGlobal(Nosec) - if err != nil { - noSecDefaultTag = NoSecTag(string(Nosec)) - } else { - noSecDefaultTag = NoSecTag(noSecDefaultTag) - } - noSecAlternativeTag, err := gosec.config.GetGlobal(NoSecAlternative) - if err != nil { - noSecAlternativeTag = noSecDefaultTag - } else { - noSecAlternativeTag = NoSecTag(noSecAlternativeTag) - } - - for _, group := range groups { - comment := strings.TrimSpace(group.Text()) - foundDefaultTag := strings.HasPrefix(comment, noSecDefaultTag) || regexp.MustCompile("\n *"+noSecDefaultTag).MatchString(comment) - foundAlternativeTag := strings.HasPrefix(comment, noSecAlternativeTag) || regexp.MustCompile("\n *"+noSecAlternativeTag).MatchString(comment) - - if foundDefaultTag || foundAlternativeTag { - gosec.stats.NumNosec++ - - // Discard what's in front of the nosec tag. - if foundDefaultTag { - comment = strings.SplitN(comment, noSecDefaultTag, 2)[1] - } else { - comment = strings.SplitN(comment, noSecAlternativeTag, 2)[1] - } - - // Extract the directive and the justification. - justification := "" - commentParts := regexp.MustCompile(`-{2,}`).Split(comment, 2) - directive := commentParts[0] - if len(commentParts) > 1 { - justification = strings.TrimSpace(strings.TrimRight(commentParts[1], "\n")) - } - - // Pull out the specific rules that are listed to be ignored. - re := regexp.MustCompile(`(G\d{3})`) - matches := re.FindAllStringSubmatch(directive, -1) - - suppression := issue.SuppressionInfo{ - Kind: "inSource", - Justification: justification, - } - - // Find the rule IDs to ignore. - ignores := make(map[string]issue.SuppressionInfo) - for _, v := range matches { - ignores[v[1]] = suppression - } - - // If no specific rules were given, ignore everything. - if len(matches) == 0 { - ignores[aliasOfAllRules] = suppression - } - return ignores - } - } - } - return nil -} - -// Visit runs the gosec visitor logic over an AST created by parsing go code. -// Rule methods added with AddRule will be invoked as necessary. -func (gosec *Analyzer) Visit(n ast.Node) ast.Visitor { - // Using ast.File instead of ast.ImportSpec, so that we can track all imports at once. - switch i := n.(type) { - case *ast.File: - gosec.context.Imports.TrackFile(i) - } - - for _, rule := range gosec.ruleset.RegisteredFor(n) { - issue, err := rule.Match(n, gosec.context) - if err != nil { - file, line := GetLocation(n, gosec.context) - file = path.Base(file) - gosec.logger.Printf("Rule error: %v => %s (%s:%d)\n", reflect.TypeOf(rule), err, file, line) - } - gosec.updateIssues(issue) - } - return gosec -} - -func (gosec *Analyzer) updateIgnores() { - for n := range gosec.context.Comments { - gosec.updateIgnoredRulesForNode(n) - } -} - -func (gosec *Analyzer) updateIgnoredRulesForNode(n ast.Node) { - ignoredRules := gosec.ignore(n) - if len(ignoredRules) > 0 { - if gosec.context.Ignores == nil { - gosec.context.Ignores = newIgnores() - } - line := issue.GetLine(gosec.context.FileSet.File(n.Pos()), n) - gosec.context.Ignores.add( - gosec.context.FileSet.File(n.Pos()).Name(), - line, - ignoredRules, - ) - } -} - -func (gosec *Analyzer) getSuppressionsAtLineInFile(file string, line string, id string) ([]issue.SuppressionInfo, bool) { - ignoredRules := gosec.context.Ignores.get(file, line) - - // Check if the rule was specifically suppressed at this location. - generalSuppressions, generalIgnored := ignoredRules[aliasOfAllRules] - ruleSuppressions, ruleIgnored := ignoredRules[id] - ignored := generalIgnored || ruleIgnored - suppressions := append(generalSuppressions, ruleSuppressions...) - - // Track external suppressions of this rule. - if gosec.ruleset.IsRuleSuppressed(id) || gosec.analyzerSet.IsSuppressed(id) { - ignored = true - suppressions = append(suppressions, issue.SuppressionInfo{ - Kind: "external", - Justification: externalSuppressionJustification, - }) - } - return suppressions, ignored -} - -func (gosec *Analyzer) updateIssues(issue *issue.Issue) { - if issue != nil { - suppressions, ignored := gosec.getSuppressionsAtLineInFile(issue.File, issue.Line, issue.RuleID) - if gosec.showIgnored { - issue.NoSec = ignored - } - if !ignored || !gosec.showIgnored { - gosec.stats.NumFound++ - } - if ignored && gosec.trackSuppressions { - issue.WithSuppressions(suppressions) - gosec.issues = append(gosec.issues, issue) - } else if !ignored || gosec.showIgnored || gosec.ignoreNosec { - gosec.issues = append(gosec.issues, issue) - } - } -} - -// Report returns the current issues discovered and the metrics about the scan -func (gosec *Analyzer) Report() ([]*issue.Issue, *Metrics, map[string][]Error) { - return gosec.issues, gosec.stats, gosec.errors -} - -// Reset clears state such as context, issues and metrics from the configured analyzer -func (gosec *Analyzer) Reset() { - gosec.context = &Context{} - gosec.issues = make([]*issue.Issue, 0, 16) - gosec.stats = &Metrics{} - gosec.ruleset = NewRuleSet() - gosec.analyzerSet = analyzers.NewAnalyzerSet() -} diff --git a/vendor/github.com/securego/gosec/v2/analyzers/analyzers_set.go b/vendor/github.com/securego/gosec/v2/analyzers/analyzers_set.go deleted file mode 100644 index e2fe51c92..000000000 --- a/vendor/github.com/securego/gosec/v2/analyzers/analyzers_set.go +++ /dev/null @@ -1,38 +0,0 @@ -// (c) Copyright gosec's authors -// -// 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 analyzers - -import "golang.org/x/tools/go/analysis" - -type AnalyzerSet struct { - Analyzers []*analysis.Analyzer - AnalyzerSuppressedMap map[string]bool -} - -// NewAnalyzerSet constructs a new AnalyzerSet -func NewAnalyzerSet() *AnalyzerSet { - return &AnalyzerSet{nil, make(map[string]bool)} -} - -// Register adds a trigger for the supplied analyzer -func (a *AnalyzerSet) Register(analyzer *analysis.Analyzer, isSuppressed bool) { - a.Analyzers = append(a.Analyzers, analyzer) - a.AnalyzerSuppressedMap[analyzer.Name] = isSuppressed -} - -// IsSuppressed will return whether the Analyzer is suppressed. -func (a *AnalyzerSet) IsSuppressed(ruleID string) bool { - return a.AnalyzerSuppressedMap[ruleID] -} diff --git a/vendor/github.com/securego/gosec/v2/analyzers/analyzerslist.go b/vendor/github.com/securego/gosec/v2/analyzers/analyzerslist.go deleted file mode 100644 index 8d222384a..000000000 --- a/vendor/github.com/securego/gosec/v2/analyzers/analyzerslist.go +++ /dev/null @@ -1,95 +0,0 @@ -// (c) Copyright gosec's authors -// -// 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 analyzers - -import ( - "golang.org/x/tools/go/analysis" -) - -// AnalyzerDefinition contains the description of an analyzer and a mechanism to -// create it. -type AnalyzerDefinition struct { - ID string - Description string - Create AnalyzerBuilder -} - -// AnalyzerBuilder is used to register an analyzer definition with the analyzer -type AnalyzerBuilder func(id string, description string) *analysis.Analyzer - -// AnalyzerList contains a mapping of analyzer ID's to analyzer definitions and a mapping -// of analyzer ID's to whether analyzers are suppressed. -type AnalyzerList struct { - Analyzers map[string]AnalyzerDefinition - AnalyzerSuppressed map[string]bool -} - -// AnalyzersInfo returns all the create methods and the analyzer suppressed map for a -// given list -func (al *AnalyzerList) AnalyzersInfo() (map[string]AnalyzerDefinition, map[string]bool) { - builders := make(map[string]AnalyzerDefinition) - for _, def := range al.Analyzers { - builders[def.ID] = def - } - return builders, al.AnalyzerSuppressed -} - -// AnalyzerFilter can be used to include or exclude an analyzer depending on the return -// value of the function -type AnalyzerFilter func(string) bool - -// NewAnalyzerFilter is a closure that will include/exclude the analyzer ID's based on -// the supplied boolean value (false means don't remove, true means exclude). -func NewAnalyzerFilter(action bool, analyzerIDs ...string) AnalyzerFilter { - analyzerlist := make(map[string]bool) - for _, analyzer := range analyzerIDs { - analyzerlist[analyzer] = true - } - return func(analyzer string) bool { - if _, found := analyzerlist[analyzer]; found { - return action - } - return !action - } -} - -var defaultAnalyzers = []AnalyzerDefinition{ - {"G115", "Type conversion which leads to integer overflow", newConversionOverflowAnalyzer}, - {"G602", "Possible slice bounds out of range", newSliceBoundsAnalyzer}, - {"G407", "Use of hardcoded IV/nonce for encryption", newHardCodedNonce}, -} - -// Generate the list of analyzers to use -func Generate(trackSuppressions bool, filters ...AnalyzerFilter) *AnalyzerList { - analyzerMap := make(map[string]AnalyzerDefinition) - analyzerSuppressedMap := make(map[string]bool) - - for _, analyzer := range defaultAnalyzers { - analyzerSuppressedMap[analyzer.ID] = false - addToAnalyzerList := true - for _, filter := range filters { - if filter(analyzer.ID) { - analyzerSuppressedMap[analyzer.ID] = true - if !trackSuppressions { - addToAnalyzerList = false - } - } - } - if addToAnalyzerList { - analyzerMap[analyzer.ID] = analyzer - } - } - return &AnalyzerList{Analyzers: analyzerMap, AnalyzerSuppressed: analyzerSuppressedMap} -} diff --git a/vendor/github.com/securego/gosec/v2/analyzers/conversion_overflow.go b/vendor/github.com/securego/gosec/v2/analyzers/conversion_overflow.go deleted file mode 100644 index bebe9b834..000000000 --- a/vendor/github.com/securego/gosec/v2/analyzers/conversion_overflow.go +++ /dev/null @@ -1,560 +0,0 @@ -// (c) Copyright gosec's authors -// -// 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 analyzers - -import ( - "fmt" - "go/token" - "math" - "regexp" - "strconv" - "strings" - - "golang.org/x/exp/constraints" - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/buildssa" - "golang.org/x/tools/go/ssa" - - "github.com/securego/gosec/v2/issue" -) - -type integer struct { - signed bool - size int - min int - max uint -} - -type rangeResult struct { - minValue int - maxValue uint - explicitPositiveVals []uint - explicitNegativeVals []int - isRangeCheck bool - convertFound bool -} - -type branchResults struct { - minValue *int - maxValue *uint - explixitPositiveVals []uint - explicitNegativeVals []int - convertFound bool -} - -func newConversionOverflowAnalyzer(id string, description string) *analysis.Analyzer { - return &analysis.Analyzer{ - Name: id, - Doc: description, - Run: runConversionOverflow, - Requires: []*analysis.Analyzer{buildssa.Analyzer}, - } -} - -func runConversionOverflow(pass *analysis.Pass) (interface{}, error) { - ssaResult, err := getSSAResult(pass) - if err != nil { - return nil, fmt.Errorf("building ssa representation: %w", err) - } - - issues := []*issue.Issue{} - for _, mcall := range ssaResult.SSA.SrcFuncs { - for _, block := range mcall.DomPreorder() { - for _, instr := range block.Instrs { - switch instr := instr.(type) { - case *ssa.Convert: - src := instr.X.Type().Underlying().String() - dst := instr.Type().Underlying().String() - if isIntOverflow(src, dst) { - if isSafeConversion(instr) { - continue - } - issue := newIssue(pass.Analyzer.Name, - fmt.Sprintf("integer overflow conversion %s -> %s", src, dst), - pass.Fset, - instr.Pos(), - issue.High, - issue.Medium, - ) - issues = append(issues, issue) - } - } - } - } - } - - if len(issues) > 0 { - return issues, nil - } - return nil, nil -} - -func isIntOverflow(src string, dst string) bool { - srcInt, err := parseIntType(src) - if err != nil { - return false - } - - dstInt, err := parseIntType(dst) - if err != nil { - return false - } - - return srcInt.min < dstInt.min || srcInt.max > dstInt.max -} - -func parseIntType(intType string) (integer, error) { - re := regexp.MustCompile(`^(?Pu?int)(?P\d{1,2})?$`) - matches := re.FindStringSubmatch(intType) - if matches == nil { - return integer{}, fmt.Errorf("no integer type match found for %s", intType) - } - - it := matches[re.SubexpIndex("type")] - is := matches[re.SubexpIndex("size")] - - signed := it == "int" - - // use default system int type in case size is not present in the type. - intSize := strconv.IntSize - if is != "" { - var err error - intSize, err = strconv.Atoi(is) - if err != nil { - return integer{}, fmt.Errorf("failed to parse the integer type size: %w", err) - } - } - - if intSize != 8 && intSize != 16 && intSize != 32 && intSize != 64 && is != "" { - return integer{}, fmt.Errorf("invalid bit size: %d", intSize) - } - - var min int - var max uint - - if signed { - shiftAmount := intSize - 1 - - // Perform a bounds check. - if shiftAmount < 0 { - return integer{}, fmt.Errorf("invalid shift amount: %d", shiftAmount) - } - - max = (1 << uint(shiftAmount)) - 1 - min = -1 << (intSize - 1) - - } else { - max = (1 << uint(intSize)) - 1 - min = 0 - } - - return integer{ - signed: signed, - size: intSize, - min: min, - max: max, - }, nil -} - -func isSafeConversion(instr *ssa.Convert) bool { - dstType := instr.Type().Underlying().String() - - // Check for constant conversions. - if constVal, ok := instr.X.(*ssa.Const); ok { - if isConstantInRange(constVal, dstType) { - return true - } - } - - // Check for string to integer conversions with specified bit size. - if isStringToIntConversion(instr, dstType) { - return true - } - - // Check for explicit range checks. - if hasExplicitRangeCheck(instr, dstType) { - return true - } - - return false -} - -func isConstantInRange(constVal *ssa.Const, dstType string) bool { - value, err := strconv.ParseInt(constVal.Value.String(), 10, 64) - if err != nil { - return false - } - - dstInt, err := parseIntType(dstType) - if err != nil { - return false - } - - if dstInt.signed { - return value >= -(1<<(dstInt.size-1)) && value <= (1<<(dstInt.size-1))-1 - } - return value >= 0 && value <= (1< dstInt.min && maxValue < dstInt.max { - return true - } - - visitedIfs := make(map[*ssa.If]bool) - for _, block := range instr.Parent().Blocks { - for _, blockInstr := range block.Instrs { - switch v := blockInstr.(type) { - case *ssa.If: - result := getResultRange(v, instr, visitedIfs) - if result.isRangeCheck { - minValue = max(minValue, &result.minValue) - maxValue = min(maxValue, &result.maxValue) - explicitPositiveVals = append(explicitPositiveVals, result.explicitPositiveVals...) - explicitNegativeVals = append(explicitNegativeVals, result.explicitNegativeVals...) - } - case *ssa.Call: - // These function return an int of a guaranteed size. - if v != instr.X { - continue - } - if fn, isBuiltin := v.Call.Value.(*ssa.Builtin); isBuiltin { - switch fn.Name() { - case "len", "cap": - minValue = 0 - } - } - } - - if explicitValsInRange(explicitPositiveVals, explicitNegativeVals, dstInt) { - return true - } else if minValue >= dstInt.min && maxValue <= dstInt.max { - return true - } - } - } - return false -} - -// getResultRange is a recursive function that walks the branches of the if statement to find the range of the variable. -func getResultRange(ifInstr *ssa.If, instr *ssa.Convert, visitedIfs map[*ssa.If]bool) rangeResult { - if visitedIfs[ifInstr] { - return rangeResult{minValue: math.MinInt, maxValue: math.MaxUint} - } - visitedIfs[ifInstr] = true - - cond := ifInstr.Cond - binOp, ok := cond.(*ssa.BinOp) - if !ok || !isRangeCheck(binOp, instr.X) { - return rangeResult{minValue: math.MinInt, maxValue: math.MaxUint} - } - - result := rangeResult{ - minValue: math.MinInt, - maxValue: math.MaxUint, - isRangeCheck: true, - } - - thenBounds := walkBranchForConvert(ifInstr.Block().Succs[0], instr, visitedIfs) - elseBounds := walkBranchForConvert(ifInstr.Block().Succs[1], instr, visitedIfs) - - updateResultFromBinOp(&result, binOp, instr, thenBounds.convertFound) - - if thenBounds.convertFound { - result.convertFound = true - result.minValue = max(result.minValue, thenBounds.minValue) - result.maxValue = min(result.maxValue, thenBounds.maxValue) - } else if elseBounds.convertFound { - result.convertFound = true - result.minValue = max(result.minValue, elseBounds.minValue) - result.maxValue = min(result.maxValue, elseBounds.maxValue) - } - - result.explicitPositiveVals = append(result.explicitPositiveVals, thenBounds.explixitPositiveVals...) - result.explicitNegativeVals = append(result.explicitNegativeVals, thenBounds.explicitNegativeVals...) - result.explicitPositiveVals = append(result.explicitPositiveVals, elseBounds.explixitPositiveVals...) - result.explicitNegativeVals = append(result.explicitNegativeVals, elseBounds.explicitNegativeVals...) - - return result -} - -// updateResultFromBinOp updates the rangeResult based on the BinOp instruction and the location of the Convert instruction. -func updateResultFromBinOp(result *rangeResult, binOp *ssa.BinOp, instr *ssa.Convert, successPathConvert bool) { - x, y := binOp.X, binOp.Y - operandsFlipped := false - - compareVal, op := getRealValueFromOperation(instr.X) - - // Handle FieldAddr - if fieldAddr, ok := compareVal.(*ssa.FieldAddr); ok { - compareVal = fieldAddr - } - - if !isSameOrRelated(x, compareVal) { - y = x - operandsFlipped = true - } - - constVal, ok := y.(*ssa.Const) - if !ok { - return - } - // TODO: constVal.Value nil check avoids #1229 panic but seems to be hiding a bug in the code above or in x/tools/go/ssa. - if constVal.Value == nil { - // log.Fatalf("[gosec] constVal.Value is nil flipped=%t, constVal=%#v, binOp=%#v", operandsFlipped, constVal, binOp) - return - } - switch binOp.Op { - case token.LEQ, token.LSS: - updateMinMaxForLessOrEqual(result, constVal, binOp.Op, operandsFlipped, successPathConvert) - case token.GEQ, token.GTR: - updateMinMaxForGreaterOrEqual(result, constVal, binOp.Op, operandsFlipped, successPathConvert) - case token.EQL: - if !successPathConvert { - break - } - updateExplicitValues(result, constVal) - case token.NEQ: - if successPathConvert { - break - } - updateExplicitValues(result, constVal) - } - - if op == "neg" { - min := result.minValue - max := result.maxValue - - if min >= 0 { - result.maxValue = uint(min) - } - if max <= math.MaxInt { - result.minValue = int(max) - } - } -} - -func updateExplicitValues(result *rangeResult, constVal *ssa.Const) { - if strings.Contains(constVal.String(), "-") { - result.explicitNegativeVals = append(result.explicitNegativeVals, int(constVal.Int64())) - } else { - result.explicitPositiveVals = append(result.explicitPositiveVals, uint(constVal.Uint64())) - } -} - -func updateMinMaxForLessOrEqual(result *rangeResult, constVal *ssa.Const, op token.Token, operandsFlipped bool, successPathConvert bool) { - // If the success path has a conversion and the operands are not flipped, then the constant value is the maximum value. - if successPathConvert && !operandsFlipped { - result.maxValue = uint(constVal.Uint64()) - if op == token.LEQ { - result.maxValue-- - } - } else { - result.minValue = int(constVal.Int64()) - if op == token.GTR { - result.minValue++ - } - } -} - -func updateMinMaxForGreaterOrEqual(result *rangeResult, constVal *ssa.Const, op token.Token, operandsFlipped bool, successPathConvert bool) { - // If the success path has a conversion and the operands are not flipped, then the constant value is the minimum value. - if successPathConvert && !operandsFlipped { - result.minValue = int(constVal.Int64()) - if op == token.GEQ { - result.minValue++ - } - } else { - result.maxValue = uint(constVal.Uint64()) - if op == token.LSS { - result.maxValue-- - } - } -} - -// walkBranchForConvert walks the branch of the if statement to find the range of the variable and where the conversion is. -func walkBranchForConvert(block *ssa.BasicBlock, instr *ssa.Convert, visitedIfs map[*ssa.If]bool) branchResults { - bounds := branchResults{} - - for _, blockInstr := range block.Instrs { - switch v := blockInstr.(type) { - case *ssa.If: - result := getResultRange(v, instr, visitedIfs) - bounds.convertFound = bounds.convertFound || result.convertFound - - if result.isRangeCheck { - bounds.minValue = toPtr(max(result.minValue, bounds.minValue)) - bounds.maxValue = toPtr(min(result.maxValue, bounds.maxValue)) - bounds.explixitPositiveVals = append(bounds.explixitPositiveVals, result.explicitPositiveVals...) - bounds.explicitNegativeVals = append(bounds.explicitNegativeVals, result.explicitNegativeVals...) - } - case *ssa.Call: - if v == instr.X { - if fn, isBuiltin := v.Call.Value.(*ssa.Builtin); isBuiltin && (fn.Name() == "len" || fn.Name() == "cap") { - bounds.minValue = toPtr(0) - } - } - case *ssa.Convert: - if v == instr { - bounds.convertFound = true - return bounds - } - } - } - - return bounds -} - -func isRangeCheck(v ssa.Value, x ssa.Value) bool { - compareVal, _ := getRealValueFromOperation(x) - - switch op := v.(type) { - case *ssa.BinOp: - switch op.Op { - case token.LSS, token.LEQ, token.GTR, token.GEQ, token.EQL, token.NEQ: - leftMatch := isSameOrRelated(op.X, compareVal) - rightMatch := isSameOrRelated(op.Y, compareVal) - return leftMatch || rightMatch - } - } - return false -} - -func getRealValueFromOperation(v ssa.Value) (ssa.Value, string) { - switch v := v.(type) { - case *ssa.UnOp: - if v.Op == token.SUB { - val, _ := getRealValueFromOperation(v.X) - return val, "neg" - } - return getRealValueFromOperation(v.X) - case *ssa.FieldAddr: - return v, "field" - case *ssa.Alloc: - return v, "alloc" - } - return v, "" -} - -func isSameOrRelated(a, b ssa.Value) bool { - aVal, _ := getRealValueFromOperation(a) - bVal, _ := getRealValueFromOperation(b) - - if aVal == bVal { - return true - } - - // Check if both are FieldAddr operations referring to the same field of the same struct - if aField, aOk := aVal.(*ssa.FieldAddr); aOk { - if bField, bOk := bVal.(*ssa.FieldAddr); bOk { - return aField.X == bField.X && aField.Field == bField.Field - } - } - - return false -} - -func explicitValsInRange(explicitPosVals []uint, explicitNegVals []int, dstInt integer) bool { - if len(explicitPosVals) == 0 && len(explicitNegVals) == 0 { - return false - } - - for _, val := range explicitPosVals { - if val > dstInt.max { - return false - } - } - - for _, val := range explicitNegVals { - if val < dstInt.min { - return false - } - } - - return true -} - -func min[T constraints.Integer](a T, b *T) T { - if b == nil { - return a - } - if a < *b { - return a - } - return *b -} - -func max[T constraints.Integer](a T, b *T) T { - if b == nil { - return a - } - if a > *b { - return a - } - return *b -} - -func toPtr[T any](a T) *T { - return &a -} diff --git a/vendor/github.com/securego/gosec/v2/analyzers/hardcodedNonce.go b/vendor/github.com/securego/gosec/v2/analyzers/hardcodedNonce.go deleted file mode 100644 index b07363388..000000000 --- a/vendor/github.com/securego/gosec/v2/analyzers/hardcodedNonce.go +++ /dev/null @@ -1,246 +0,0 @@ -// (c) Copyright gosec's authors -// -// 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 analyzers - -import ( - "errors" - "fmt" - "go/token" - "strings" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/buildssa" - "golang.org/x/tools/go/ssa" - - "github.com/securego/gosec/v2/issue" -) - -const defaultIssueDescription = "Use of hardcoded IV/nonce for encryption" - -func newHardCodedNonce(id string, description string) *analysis.Analyzer { - return &analysis.Analyzer{ - Name: id, - Doc: description, - Run: runHardCodedNonce, - Requires: []*analysis.Analyzer{buildssa.Analyzer}, - } -} - -func runHardCodedNonce(pass *analysis.Pass) (interface{}, error) { - ssaResult, err := getSSAResult(pass) - if err != nil { - return nil, fmt.Errorf("building ssa representation: %w", err) - } - - // Holds the function name as key, the number of arguments that the function accepts, and at which index of those accepted arguments is the nonce/IV - // Example "Test" 3, 1 -- means the function "Test" which accepts 3 arguments, and has the nonce arg as second argument - calls := map[string][]int{ - "(crypto/cipher.AEAD).Seal": {4, 1}, - "(crypto/cipher.AEAD).Open": {4, 1}, - "crypto/cipher.NewCBCDecrypter": {2, 1}, - "crypto/cipher.NewCBCEncrypter": {2, 1}, - "crypto/cipher.NewCFBDecrypter": {2, 1}, - "crypto/cipher.NewCFBEncrypter": {2, 1}, - "crypto/cipher.NewCTR": {2, 1}, - "crypto/cipher.NewOFB": {2, 1}, - } - ssaPkgFunctions := ssaResult.SSA.SrcFuncs - args := getArgsFromTrackedFunctions(ssaPkgFunctions, calls) - if args == nil { - return nil, errors.New("no tracked functions found, resulting in no variables to track") - } - var issues []*issue.Issue - for _, arg := range args { - if arg == nil { - continue - } - i, err := raiseIssue(*arg, calls, ssaPkgFunctions, pass, "") - if err != nil { - return issues, fmt.Errorf("raising issue error: %w", err) - } - issues = append(issues, i...) - } - return issues, nil -} - -func raiseIssue(val ssa.Value, funcsToTrack map[string][]int, ssaFuncs []*ssa.Function, - pass *analysis.Pass, issueDescription string, -) ([]*issue.Issue, error) { - if issueDescription == "" { - issueDescription = defaultIssueDescription - } - var err error - var allIssues []*issue.Issue - var issues []*issue.Issue - switch valType := (val).(type) { - case *ssa.Slice: - issueDescription += " by passing hardcoded slice/array" - issues, err = iterateThroughReferrers(val, funcsToTrack, pass.Analyzer.Name, issueDescription, pass.Fset, issue.High) - allIssues = append(allIssues, issues...) - case *ssa.UnOp: - // Check if it's a dereference operation (a.k.a pointer) - if valType.Op == token.MUL { - issueDescription += " by passing pointer which points to hardcoded variable" - issues, err = iterateThroughReferrers(val, funcsToTrack, pass.Analyzer.Name, issueDescription, pass.Fset, issue.Low) - allIssues = append(allIssues, issues...) - } - // When the value assigned to a variable is a function call. - // It goes and check if this function contains call to crypto/rand.Read - // in it's body(Assuming that calling crypto/rand.Read in a function, - // is used for the generation of nonce/iv ) - case *ssa.Call: - if callValue := valType.Call.Value; callValue != nil { - if calledFunction, ok := callValue.(*ssa.Function); ok { - if contains, funcErr := isFuncContainsCryptoRand(calledFunction); !contains && funcErr == nil { - issueDescription += " by passing a value from function which doesn't use crypto/rand" - issues, err = iterateThroughReferrers(val, funcsToTrack, pass.Analyzer.Name, issueDescription, pass.Fset, issue.Medium) - allIssues = append(allIssues, issues...) - } else if funcErr != nil { - err = funcErr - } - } - } - // only checks from strings->[]byte - // might need to add additional types - case *ssa.Convert: - if valType.Type().String() == "[]byte" && valType.X.Type().String() == "string" { - issueDescription += " by passing converted string" - issues, err = iterateThroughReferrers(val, funcsToTrack, pass.Analyzer.Name, issueDescription, pass.Fset, issue.High) - allIssues = append(allIssues, issues...) - } - case *ssa.Parameter: - // arg given to tracked function is wrapped in another function, example: - // func encrypt(..,nonce,...){ - // aesgcm.Seal(nonce) - // } - // save parameter position, by checking the name of the variable used in - // tracked functions and comparing it with the name of the arg - if valType.Parent() != nil { - trackedFunctions := make(map[string][]int) - for index, funcArgs := range valType.Parent().Params { - if funcArgs.Name() == valType.Name() && funcArgs.Type() == valType.Type() { - trackedFunctions[valType.Parent().String()] = []int{len(valType.Parent().Params), index} - } - } - args := getArgsFromTrackedFunctions(ssaFuncs, trackedFunctions) - - issueDescription += " by passing a parameter to a function and" - // recursively backtrack to where the origin of a variable passed to multiple functions is - for _, arg := range args { - if arg == nil { - continue - } - issues, err = raiseIssue(*arg, trackedFunctions, ssaFuncs, pass, issueDescription) - allIssues = append(allIssues, issues...) - } - } - } - return allIssues, err -} - -// iterateThroughReferrers iterates through all places that use the `variable` argument and check if it's used in one of the tracked functions. -func iterateThroughReferrers(variable ssa.Value, funcsToTrack map[string][]int, - analyzerID string, issueDescription string, - fileSet *token.FileSet, issueConfidence issue.Score, -) ([]*issue.Issue, error) { - if funcsToTrack == nil || variable == nil || analyzerID == "" || issueDescription == "" || fileSet == nil { - return nil, errors.New("received a nil object") - } - var gosecIssues []*issue.Issue - refs := variable.Referrers() - if refs == nil { - return gosecIssues, nil - } - // Go trough all functions that use the given arg variable - for _, ref := range *refs { - // Iterate trough the functions we are interested - for trackedFunc := range funcsToTrack { - - // Split the functions we are interested in, by the '.' because we will use the function name to do the comparison - // MIGHT GIVE SOME FALSE POSITIVES THIS WAY - trackedFuncParts := strings.Split(trackedFunc, ".") - trackedFuncPartsName := trackedFuncParts[len(trackedFuncParts)-1] - if strings.Contains(ref.String(), trackedFuncPartsName) { - gosecIssues = append(gosecIssues, newIssue(analyzerID, issueDescription, fileSet, ref.Pos(), issue.High, issueConfidence)) - } - } - } - return gosecIssues, nil -} - -// isFuncContainsCryptoRand checks whether a function contains a call to crypto/rand.Read in it's function body. -func isFuncContainsCryptoRand(funcCall *ssa.Function) (bool, error) { - if funcCall == nil { - return false, errors.New("passed ssa.Function object is nil") - } - for _, block := range funcCall.Blocks { - for _, instr := range block.Instrs { - if call, ok := instr.(*ssa.Call); ok { - if calledFunction, ok := call.Call.Value.(*ssa.Function); ok { - if calledFunction.Pkg != nil && calledFunction.Pkg.Pkg.Path() == "crypto/rand" && calledFunction.Name() == "Read" { - return true, nil - } - } - } - } - } - return false, nil -} - -func addToVarsMap(value ssa.Value, mapToAddTo map[string]*ssa.Value) { - key := value.Name() + value.Type().String() + value.String() + value.Parent().String() - mapToAddTo[key] = &value -} - -func isContainedInMap(value ssa.Value, mapToCheck map[string]*ssa.Value) bool { - key := value.Name() + value.Type().String() + value.String() + value.Parent().String() - _, contained := mapToCheck[key] - return contained -} - -func getArgsFromTrackedFunctions(ssaFuncs []*ssa.Function, trackedFunc map[string][]int) map[string]*ssa.Value { - values := make(map[string]*ssa.Value) - for _, pkgFunc := range ssaFuncs { - for _, funcBlock := range pkgFunc.Blocks { - for _, funcBlocInstr := range funcBlock.Instrs { - iterateTrackedFunctionsAndAddArgs(funcBlocInstr, trackedFunc, values) - } - } - } - return values -} - -func iterateTrackedFunctionsAndAddArgs(funcBlocInstr ssa.Instruction, trackedFunc map[string][]int, values map[string]*ssa.Value) { - if funcCall, ok := (funcBlocInstr).(*ssa.Call); ok { - for trackedFuncName, trackedFuncArgsInfo := range trackedFunc { - // only process functions that have the same number of arguments as the ones we track - if len(funcCall.Call.Args) == trackedFuncArgsInfo[0] { - tmpArg := funcCall.Call.Args[trackedFuncArgsInfo[1]] - // check if the function is called from an object or directly from the package - if funcCall.Call.Method != nil { - if methodFullname := funcCall.Call.Method.FullName(); methodFullname == trackedFuncName { - if !isContainedInMap(tmpArg, values) { - addToVarsMap(tmpArg, values) - } - } - } else if funcCall.Call.Value.String() == trackedFuncName { - if !isContainedInMap(tmpArg, values) { - addToVarsMap(tmpArg, values) - } - } - } - } - } -} diff --git a/vendor/github.com/securego/gosec/v2/analyzers/slice_bounds.go b/vendor/github.com/securego/gosec/v2/analyzers/slice_bounds.go deleted file mode 100644 index 968102f26..000000000 --- a/vendor/github.com/securego/gosec/v2/analyzers/slice_bounds.go +++ /dev/null @@ -1,399 +0,0 @@ -// (c) Copyright gosec's authors -// -// 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 analyzers - -import ( - "errors" - "fmt" - "go/token" - "regexp" - "strconv" - "strings" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/buildssa" - "golang.org/x/tools/go/ssa" - - "github.com/securego/gosec/v2/issue" -) - -type bound int - -const ( - lowerUnbounded bound = iota - upperUnbounded - unbounded - upperBounded -) - -const maxDepth = 20 - -func newSliceBoundsAnalyzer(id string, description string) *analysis.Analyzer { - return &analysis.Analyzer{ - Name: id, - Doc: description, - Run: runSliceBounds, - Requires: []*analysis.Analyzer{buildssa.Analyzer}, - } -} - -func runSliceBounds(pass *analysis.Pass) (interface{}, error) { - ssaResult, err := getSSAResult(pass) - if err != nil { - return nil, err - } - - issues := map[ssa.Instruction]*issue.Issue{} - ifs := map[ssa.If]*ssa.BinOp{} - for _, mcall := range ssaResult.SSA.SrcFuncs { - for _, block := range mcall.DomPreorder() { - for _, instr := range block.Instrs { - switch instr := instr.(type) { - case *ssa.Alloc: - sliceCap, err := extractSliceCapFromAlloc(instr.String()) - if err != nil { - break - } - allocRefs := instr.Referrers() - if allocRefs == nil { - break - } - for _, instr := range *allocRefs { - if slice, ok := instr.(*ssa.Slice); ok { - if _, ok := slice.X.(*ssa.Alloc); ok { - if slice.Parent() != nil { - l, h := extractSliceBounds(slice) - newCap := computeSliceNewCap(l, h, sliceCap) - violations := []ssa.Instruction{} - trackSliceBounds(0, newCap, slice, &violations, ifs) - for _, s := range violations { - switch s := s.(type) { - case *ssa.Slice: - issue := newIssue( - pass.Analyzer.Name, - "slice bounds out of range", - pass.Fset, - s.Pos(), - issue.Low, - issue.High) - issues[s] = issue - case *ssa.IndexAddr: - issue := newIssue( - pass.Analyzer.Name, - "slice index out of range", - pass.Fset, - s.Pos(), - issue.Low, - issue.High) - issues[s] = issue - } - } - } - } - } - } - } - } - } - } - - for ifref, binop := range ifs { - bound, value, err := extractBinOpBound(binop) - if err != nil { - continue - } - for i, block := range ifref.Block().Succs { - if i == 1 { - bound = invBound(bound) - } - var processBlock func(block *ssa.BasicBlock, depth int) - processBlock = func(block *ssa.BasicBlock, depth int) { - if depth == maxDepth { - return - } - depth++ - for _, instr := range block.Instrs { - if _, ok := issues[instr]; ok { - switch bound { - case lowerUnbounded: - break - case upperUnbounded, unbounded: - delete(issues, instr) - case upperBounded: - switch tinstr := instr.(type) { - case *ssa.Slice: - lower, upper := extractSliceBounds(tinstr) - if isSliceInsideBounds(0, value, lower, upper) { - delete(issues, instr) - } - case *ssa.IndexAddr: - indexValue, err := extractIntValue(tinstr.Index.String()) - if err != nil { - break - } - if isSliceIndexInsideBounds(0, value, indexValue) { - delete(issues, instr) - } - } - } - } else if nestedIfInstr, ok := instr.(*ssa.If); ok { - for _, nestedBlock := range nestedIfInstr.Block().Succs { - processBlock(nestedBlock, depth) - } - } - } - } - - processBlock(block, 0) - } - } - - foundIssues := []*issue.Issue{} - for _, issue := range issues { - foundIssues = append(foundIssues, issue) - } - if len(foundIssues) > 0 { - return foundIssues, nil - } - return nil, nil -} - -func trackSliceBounds(depth int, sliceCap int, slice ssa.Node, violations *[]ssa.Instruction, ifs map[ssa.If]*ssa.BinOp) { - if depth == maxDepth { - return - } - depth++ - if violations == nil { - violations = &[]ssa.Instruction{} - } - referrers := slice.Referrers() - if referrers != nil { - for _, refinstr := range *referrers { - switch refinstr := refinstr.(type) { - case *ssa.Slice: - checkAllSlicesBounds(depth, sliceCap, refinstr, violations, ifs) - switch refinstr.X.(type) { - case *ssa.Alloc, *ssa.Parameter: - l, h := extractSliceBounds(refinstr) - newCap := computeSliceNewCap(l, h, sliceCap) - trackSliceBounds(depth, newCap, refinstr, violations, ifs) - } - case *ssa.IndexAddr: - indexValue, err := extractIntValue(refinstr.Index.String()) - if err == nil && !isSliceIndexInsideBounds(0, sliceCap, indexValue) { - *violations = append(*violations, refinstr) - } - case *ssa.Call: - if ifref, cond := extractSliceIfLenCondition(refinstr); ifref != nil && cond != nil { - ifs[*ifref] = cond - } else { - parPos := -1 - for pos, arg := range refinstr.Call.Args { - if a, ok := arg.(*ssa.Slice); ok && a == slice { - parPos = pos - } - } - if fn, ok := refinstr.Call.Value.(*ssa.Function); ok { - if len(fn.Params) > parPos && parPos > -1 { - param := fn.Params[parPos] - trackSliceBounds(depth, sliceCap, param, violations, ifs) - } - } - } - } - } - } -} - -func checkAllSlicesBounds(depth int, sliceCap int, slice *ssa.Slice, violations *[]ssa.Instruction, ifs map[ssa.If]*ssa.BinOp) { - if depth == maxDepth { - return - } - depth++ - if violations == nil { - violations = &[]ssa.Instruction{} - } - sliceLow, sliceHigh := extractSliceBounds(slice) - if !isSliceInsideBounds(0, sliceCap, sliceLow, sliceHigh) { - *violations = append(*violations, slice) - } - switch slice.X.(type) { - case *ssa.Alloc, *ssa.Parameter, *ssa.Slice: - l, h := extractSliceBounds(slice) - newCap := computeSliceNewCap(l, h, sliceCap) - trackSliceBounds(depth, newCap, slice, violations, ifs) - } - - references := slice.Referrers() - if references == nil { - return - } - for _, ref := range *references { - switch s := ref.(type) { - case *ssa.Slice: - checkAllSlicesBounds(depth, sliceCap, s, violations, ifs) - switch s.X.(type) { - case *ssa.Alloc, *ssa.Parameter: - l, h := extractSliceBounds(s) - newCap := computeSliceNewCap(l, h, sliceCap) - trackSliceBounds(depth, newCap, s, violations, ifs) - } - } - } -} - -func extractSliceIfLenCondition(call *ssa.Call) (*ssa.If, *ssa.BinOp) { - if builtInLen, ok := call.Call.Value.(*ssa.Builtin); ok { - if builtInLen.Name() == "len" { - refs := call.Referrers() - if refs != nil { - for _, ref := range *refs { - if binop, ok := ref.(*ssa.BinOp); ok { - binoprefs := binop.Referrers() - for _, ref := range *binoprefs { - if ifref, ok := ref.(*ssa.If); ok { - return ifref, binop - } - } - } - } - } - } - } - return nil, nil -} - -func computeSliceNewCap(l, h, oldCap int) int { - if l == 0 && h == 0 { - return oldCap - } - if l > 0 && h == 0 { - return oldCap - l - } - if l == 0 && h > 0 { - return h - } - return h - l -} - -func invBound(bound bound) bound { - switch bound { - case lowerUnbounded: - return upperUnbounded - case upperUnbounded: - return lowerUnbounded - case upperBounded: - return unbounded - case unbounded: - return upperBounded - default: - return unbounded - } -} - -func extractBinOpBound(binop *ssa.BinOp) (bound, int, error) { - if binop.X != nil { - if x, ok := binop.X.(*ssa.Const); ok { - value, err := strconv.Atoi(x.Value.String()) - if err != nil { - return lowerUnbounded, value, err - } - switch binop.Op { - case token.LSS, token.LEQ: - return upperUnbounded, value, nil - case token.GTR, token.GEQ: - return lowerUnbounded, value, nil - case token.EQL: - return upperBounded, value, nil - case token.NEQ: - return unbounded, value, nil - } - } - } - if binop.Y != nil { - if y, ok := binop.Y.(*ssa.Const); ok { - value, err := strconv.Atoi(y.Value.String()) - if err != nil { - return lowerUnbounded, value, err - } - switch binop.Op { - case token.LSS, token.LEQ: - return lowerUnbounded, value, nil - case token.GTR, token.GEQ: - return upperUnbounded, value, nil - case token.EQL: - return upperBounded, value, nil - case token.NEQ: - return unbounded, value, nil - } - } - } - return lowerUnbounded, 0, fmt.Errorf("unable to extract constant from binop") -} - -func isSliceIndexInsideBounds(l, h int, index int) bool { - return (l <= index && index < h) -} - -func isSliceInsideBounds(l, h int, cl, ch int) bool { - return (l <= cl && h >= ch) && (l <= ch && h >= cl) -} - -func extractSliceBounds(slice *ssa.Slice) (int, int) { - var low int - if slice.Low != nil { - l, err := extractIntValue(slice.Low.String()) - if err == nil { - low = l - } - } - var high int - if slice.High != nil { - h, err := extractIntValue(slice.High.String()) - if err == nil { - high = h - } - } - return low, high -} - -func extractIntValue(value string) (int, error) { - parts := strings.Split(value, ":") - if len(parts) != 2 { - return 0, fmt.Errorf("invalid value: %s", value) - } - if parts[1] != "int" { - return 0, fmt.Errorf("invalid value: %s", value) - } - return strconv.Atoi(parts[0]) -} - -func extractSliceCapFromAlloc(instr string) (int, error) { - re := regexp.MustCompile(`new \[(\d+)\]*`) - var sliceCap int - matches := re.FindAllStringSubmatch(instr, -1) - if matches == nil { - return sliceCap, errors.New("no slice cap found") - } - - if len(matches) > 0 { - m := matches[0] - if len(m) > 1 { - return strconv.Atoi(m[1]) - } - } - - return 0, errors.New("no slice cap found") -} diff --git a/vendor/github.com/securego/gosec/v2/analyzers/util.go b/vendor/github.com/securego/gosec/v2/analyzers/util.go deleted file mode 100644 index e7961a56b..000000000 --- a/vendor/github.com/securego/gosec/v2/analyzers/util.go +++ /dev/null @@ -1,100 +0,0 @@ -// (c) Copyright gosec's authors -// -// 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 analyzers - -import ( - "fmt" - "go/token" - "log" - "os" - "strconv" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/buildssa" - - "github.com/securego/gosec/v2/issue" -) - -// SSAAnalyzerResult contains various information returned by the -// SSA analysis along with some configuration -type SSAAnalyzerResult struct { - Config map[string]interface{} - Logger *log.Logger - SSA *buildssa.SSA -} - -// BuildDefaultAnalyzers returns the default list of analyzers -func BuildDefaultAnalyzers() []*analysis.Analyzer { - return []*analysis.Analyzer{ - newConversionOverflowAnalyzer("G115", "Type conversion which leads to integer overflow"), - newSliceBoundsAnalyzer("G602", "Possible slice bounds out of range"), - newHardCodedNonce("G407", "Use of hardcoded IV/nonce for encryption"), - } -} - -// getSSAResult retrieves the SSA result from analysis pass -func getSSAResult(pass *analysis.Pass) (*SSAAnalyzerResult, error) { - result, ok := pass.ResultOf[buildssa.Analyzer] - if !ok { - return nil, fmt.Errorf("no SSA result found in the analysis pass") - } - ssaResult, ok := result.(*SSAAnalyzerResult) - if !ok { - return nil, fmt.Errorf("the analysis pass result is not of type SSA") - } - return ssaResult, nil -} - -// newIssue creates a new gosec issue -func newIssue(analyzerID string, desc string, fileSet *token.FileSet, - pos token.Pos, severity, confidence issue.Score, -) *issue.Issue { - file := fileSet.File(pos) - line := file.Line(pos) - col := file.Position(pos).Column - - return &issue.Issue{ - RuleID: analyzerID, - File: file.Name(), - Line: strconv.Itoa(line), - Col: strconv.Itoa(col), - Severity: severity, - Confidence: confidence, - What: desc, - Cwe: issue.GetCweByRule(analyzerID), - Code: issueCodeSnippet(fileSet, pos), - } -} - -func issueCodeSnippet(fileSet *token.FileSet, pos token.Pos) string { - file := fileSet.File(pos) - - start := (int64)(file.Line(pos)) - if start-issue.SnippetOffset > 0 { - start = start - issue.SnippetOffset - } - end := (int64)(file.Line(pos)) - end = end + issue.SnippetOffset - - var code string - if file, err := os.Open(file.Name()); err == nil { - defer file.Close() // #nosec - code, err = issue.CodeSnippet(file, start, end) - if err != nil { - return err.Error() - } - } - return code -} diff --git a/vendor/github.com/securego/gosec/v2/call_list.go b/vendor/github.com/securego/gosec/v2/call_list.go deleted file mode 100644 index 4f2d6c54e..000000000 --- a/vendor/github.com/securego/gosec/v2/call_list.go +++ /dev/null @@ -1,118 +0,0 @@ -// -// 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 gosec - -import ( - "go/ast" - "strings" -) - -const vendorPath = "vendor/" - -type set map[string]bool - -// CallList is used to check for usage of specific packages -// and functions. -type CallList map[string]set - -// NewCallList creates a new empty CallList -func NewCallList() CallList { - return make(CallList) -} - -// AddAll will add several calls to the call list at once -func (c CallList) AddAll(selector string, idents ...string) { - for _, ident := range idents { - c.Add(selector, ident) - } -} - -// Add a selector and call to the call list -func (c CallList) Add(selector, ident string) { - if _, ok := c[selector]; !ok { - c[selector] = make(set) - } - c[selector][ident] = true -} - -// Contains returns true if the package and function are -// members of this call list. -func (c CallList) Contains(selector, ident string) bool { - if idents, ok := c[selector]; ok { - _, found := idents[ident] - return found - } - return false -} - -// ContainsPointer returns true if a pointer to the selector type or the type -// itself is a members of this call list. -func (c CallList) ContainsPointer(selector, indent string) bool { - if strings.HasPrefix(selector, "*") { - if c.Contains(selector, indent) { - return true - } - s := strings.TrimPrefix(selector, "*") - return c.Contains(s, indent) - } - return false -} - -// ContainsPkgCallExpr resolves the call expression name and type, and then further looks -// up the package path for that type. Finally, it determines if the call exists within the call list -func (c CallList) ContainsPkgCallExpr(n ast.Node, ctx *Context, stripVendor bool) *ast.CallExpr { - selector, ident, err := GetCallInfo(n, ctx) - if err != nil { - return nil - } - - // Selector can have two forms: - // 1. A short name if a module function is called (expr.Name). - // E.g., "big" if called function from math/big. - // 2. A full name if a structure function is called (TypeOf(expr)). - // E.g., "math/big.Rat" if called function of Rat structure from math/big. - if !strings.ContainsRune(selector, '.') { - // Use only explicit path (optionally strip vendor path prefix) to reduce conflicts - path, ok := GetImportPath(selector, ctx) - if !ok { - return nil - } - selector = path - } - - if stripVendor { - if vendorIdx := strings.Index(selector, vendorPath); vendorIdx >= 0 { - selector = selector[vendorIdx+len(vendorPath):] - } - } - if !c.Contains(selector, ident) { - return nil - } - - return n.(*ast.CallExpr) -} - -// ContainsCallExpr resolves the call expression name and type, and then determines -// if the call exists with the call list -func (c CallList) ContainsCallExpr(n ast.Node, ctx *Context) *ast.CallExpr { - selector, ident, err := GetCallInfo(n, ctx) - if err != nil { - return nil - } - if !c.Contains(selector, ident) && !c.ContainsPointer(selector, ident) { - return nil - } - - return n.(*ast.CallExpr) -} diff --git a/vendor/github.com/securego/gosec/v2/config.go b/vendor/github.com/securego/gosec/v2/config.go deleted file mode 100644 index 9cbb7a713..000000000 --- a/vendor/github.com/securego/gosec/v2/config.go +++ /dev/null @@ -1,137 +0,0 @@ -package gosec - -import ( - "bytes" - "encoding/json" - "fmt" - "io" -) - -const ( - // Globals are applicable to all rules and used for general - // configuration settings for gosec. - Globals = "global" -) - -// GlobalOption defines the name of the global options -type GlobalOption string - -const ( - // Nosec global option for #nosec directive - Nosec GlobalOption = "nosec" - // ShowIgnored defines whether nosec issues are counted as finding or not - ShowIgnored GlobalOption = "show-ignored" - // Audit global option which indicates that gosec runs in audit mode - Audit GlobalOption = "audit" - // NoSecAlternative global option alternative for #nosec directive - NoSecAlternative GlobalOption = "#nosec" - // ExcludeRules global option for some rules should not be load - ExcludeRules GlobalOption = "exclude" - // IncludeRules global option for should be load - IncludeRules GlobalOption = "include" - // SSA global option to enable go analysis framework with SSA support - SSA GlobalOption = "ssa" -) - -// NoSecTag returns the tag used to disable gosec for a line of code. -func NoSecTag(tag string) string { - return fmt.Sprintf("%s%s", "#", tag) -} - -// Config is used to provide configuration and customization to each of the rules. -type Config map[string]interface{} - -// NewConfig initializes a new configuration instance. The configuration data then -// needs to be loaded via c.ReadFrom(strings.NewReader("config data")) -// or from a *os.File. -func NewConfig() Config { - cfg := make(Config) - cfg[Globals] = make(map[GlobalOption]string) - return cfg -} - -func (c Config) keyToGlobalOptions(key string) GlobalOption { - return GlobalOption(key) -} - -func (c Config) convertGlobals() { - if globals, ok := c[Globals]; ok { - if settings, ok := globals.(map[string]interface{}); ok { - validGlobals := map[GlobalOption]string{} - for k, v := range settings { - validGlobals[c.keyToGlobalOptions(k)] = fmt.Sprintf("%v", v) - } - c[Globals] = validGlobals - } - } -} - -// ReadFrom implements the io.ReaderFrom interface. This -// should be used with io.Reader to load configuration from -// file or from string etc. -func (c Config) ReadFrom(r io.Reader) (int64, error) { - data, err := io.ReadAll(r) - if err != nil { - return int64(len(data)), err - } - if err = json.Unmarshal(data, &c); err != nil { - return int64(len(data)), err - } - c.convertGlobals() - return int64(len(data)), nil -} - -// WriteTo implements the io.WriteTo interface. This should -// be used to save or print out the configuration information. -func (c Config) WriteTo(w io.Writer) (int64, error) { - data, err := json.Marshal(c) - if err != nil { - return int64(len(data)), err - } - return io.Copy(w, bytes.NewReader(data)) -} - -// Get returns the configuration section for the supplied key -func (c Config) Get(section string) (interface{}, error) { - settings, found := c[section] - if !found { - return nil, fmt.Errorf("Section %s not in configuration", section) - } - return settings, nil -} - -// Set section in the configuration to specified value -func (c Config) Set(section string, value interface{}) { - c[section] = value -} - -// GetGlobal returns value associated with global configuration option -func (c Config) GetGlobal(option GlobalOption) (string, error) { - if globals, ok := c[Globals]; ok { - if settings, ok := globals.(map[GlobalOption]string); ok { - if value, ok := settings[option]; ok { - return value, nil - } - return "", fmt.Errorf("global setting for %s not found", option) - } - } - return "", fmt.Errorf("no global config options found") -} - -// SetGlobal associates a value with a global configuration option -func (c Config) SetGlobal(option GlobalOption, value string) { - if globals, ok := c[Globals]; ok { - if settings, ok := globals.(map[GlobalOption]string); ok { - settings[option] = value - } - } -} - -// IsGlobalEnabled checks if a global option is enabled -func (c Config) IsGlobalEnabled(option GlobalOption) (bool, error) { - value, err := c.GetGlobal(option) - if err != nil { - return false, err - } - return (value == "true" || value == "enabled"), nil -} diff --git a/vendor/github.com/securego/gosec/v2/cosign.pub b/vendor/github.com/securego/gosec/v2/cosign.pub deleted file mode 100644 index c6fd55988..000000000 --- a/vendor/github.com/securego/gosec/v2/cosign.pub +++ /dev/null @@ -1,4 +0,0 @@ ------BEGIN PUBLIC KEY----- -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFphl7f2VuFRfsi4wqiLUCQ9xHQgV -O2VMDNcvh+kxiymLXa+GkPzSKExFYIlVwfg13URvCiB+kFvITmLzuLiGQg== ------END PUBLIC KEY----- diff --git a/vendor/github.com/securego/gosec/v2/cwe/data.go b/vendor/github.com/securego/gosec/v2/cwe/data.go deleted file mode 100644 index a9568ba4d..000000000 --- a/vendor/github.com/securego/gosec/v2/cwe/data.go +++ /dev/null @@ -1,150 +0,0 @@ -package cwe - -const ( - // Acronym is the acronym of CWE - Acronym = "CWE" - // Version the CWE version - Version = "4.4" - // ReleaseDateUtc the release Date of CWE Version - ReleaseDateUtc = "2021-03-15" - // Organization MITRE - Organization = "MITRE" - // Description the description of CWE - Description = "The MITRE Common Weakness Enumeration" - // InformationURI link to the published CWE PDF - InformationURI = "https://cwe.mitre.org/data/published/cwe_v" + Version + ".pdf/" - // DownloadURI link to the zipped XML of the CWE list - DownloadURI = "https://cwe.mitre.org/data/xml/cwec_v" + Version + ".xml.zip" -) - -var idWeaknesses = map[string]*Weakness{ - "22": { - ID: "22", - Description: "The software uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the software does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.", - Name: "Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')", - }, - "78": { - ID: "78", - Description: "The software constructs all or part of an OS command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended OS command when it is sent to a downstream component.", - Name: "Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')", - }, - "79": { - ID: "79", - Description: "The software does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.", - Name: "Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')", - }, - "88": { - ID: "88", - Description: "The software constructs a string for a command to executed by a separate component\nin another control sphere, but it does not properly delimit the\nintended arguments, options, or switches within that command string.", - Name: "Improper Neutralization of Argument Delimiters in a Command ('Argument Injection')", - }, - "89": { - ID: "89", - Description: "The software constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component.", - Name: "Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')", - }, - "118": { - ID: "118", - Description: "The software does not restrict or incorrectly restricts operations within the boundaries of a resource that is accessed using an index or pointer, such as memory or files.", - Name: "Incorrect Access of Indexable Resource ('Range Error')", - }, - "190": { - ID: "190", - Description: "The software performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value. This can introduce other weaknesses when the calculation is used for resource management or execution control.", - Name: "Integer Overflow or Wraparound", - }, - "200": { - ID: "200", - Description: "The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information.", - Name: "Exposure of Sensitive Information to an Unauthorized Actor", - }, - "242": { - ID: "242", - Description: "The program calls a function that can never be guaranteed to work safely.", - Name: "Use of Inherently Dangerous Function", - }, - "276": { - ID: "276", - Description: "During installation, installed file permissions are set to allow anyone to modify those files.", - Name: "Incorrect Default Permissions", - }, - "295": { - ID: "295", - Description: "The software does not validate, or incorrectly validates, a certificate.", - Name: "Improper Certificate Validation", - }, - "310": { - ID: "310", - Description: "Weaknesses in this category are related to the design and implementation of data confidentiality and integrity. Frequently these deal with the use of encoding techniques, encryption libraries, and hashing algorithms. The weaknesses in this category could lead to a degradation of the quality data if they are not addressed.", - Name: "Cryptographic Issues", - }, - "322": { - ID: "322", - Description: "The software performs a key exchange with an actor without verifying the identity of that actor.", - Name: "Key Exchange without Entity Authentication", - }, - "326": { - ID: "326", - Description: "The software stores or transmits sensitive data using an encryption scheme that is theoretically sound, but is not strong enough for the level of protection required.", - Name: "Inadequate Encryption Strength", - }, - "327": { - ID: "327", - Description: "The use of a broken or risky cryptographic algorithm is an unnecessary risk that may result in the exposure of sensitive information.", - Name: "Use of a Broken or Risky Cryptographic Algorithm", - }, - "328": { - ID: "328", - Description: "The product uses an algorithm that produces a digest (output value) that does not meet security expectations for a hash function that allows an adversary to reasonably determine the original input (preimage attack), find another input that can produce the same hash (2nd preimage attack), or find multiple inputs that evaluate to the same hash (birthday attack). ", - Name: "Use of Weak Hash", - }, - "338": { - ID: "338", - Description: "The product uses a Pseudo-Random Number Generator (PRNG) in a security context, but the PRNG's algorithm is not cryptographically strong.", - Name: "Use of Cryptographically Weak Pseudo-Random Number Generator (PRNG)", - }, - "377": { - ID: "377", - Description: "Creating and using insecure temporary files can leave application and system data vulnerable to attack.", - Name: "Insecure Temporary File", - }, - "400": { - ID: "400", - Description: "The software does not properly control the allocation and maintenance of a limited resource, thereby enabling an actor to influence the amount of resources consumed, eventually leading to the exhaustion of available resources.", - Name: "Uncontrolled Resource Consumption", - }, - "409": { - ID: "409", - Description: "The software does not handle or incorrectly handles a compressed input with a very high compression ratio that produces a large output.", - Name: "Improper Handling of Highly Compressed Data (Data Amplification)", - }, - "676": { - ID: "676", - Description: "The program invokes a potentially dangerous function that could introduce a vulnerability if it is used incorrectly, but the function can also be used safely.", - Name: "Use of Potentially Dangerous Function", - }, - "703": { - ID: "703", - Description: "The software does not properly anticipate or handle exceptional conditions that rarely occur during normal operation of the software.", - Name: "Improper Check or Handling of Exceptional Conditions", - }, - "798": { - ID: "798", - Description: "The software contains hard-coded credentials, such as a password or cryptographic key, which it uses for its own inbound authentication, outbound communication to external components, or encryption of internal data.", - Name: "Use of Hard-coded Credentials", - }, - "1204": { - ID: "1204", - Description: "The product uses a cryptographic primitive that uses an Initialization Vector (IV), but the product does not generate IVs that are sufficiently unpredictable or unique according to the expected cryptographic requirements for that primitive.", - Name: "Generation of Weak Initialization Vector (IV)", - }, -} - -// Get Retrieves a CWE weakness by it's id -func Get(id string) *Weakness { - weakness, ok := idWeaknesses[id] - if ok && weakness != nil { - return weakness - } - return nil -} diff --git a/vendor/github.com/securego/gosec/v2/cwe/types.go b/vendor/github.com/securego/gosec/v2/cwe/types.go deleted file mode 100644 index 562510a8b..000000000 --- a/vendor/github.com/securego/gosec/v2/cwe/types.go +++ /dev/null @@ -1,38 +0,0 @@ -package cwe - -import ( - "encoding/json" - "fmt" -) - -// Weakness defines a CWE weakness based on http://cwe.mitre.org/data/xsd/cwe_schema_v6.4.xsd -type Weakness struct { - ID string - Name string - Description string -} - -// SprintURL format the CWE URL -func (w *Weakness) SprintURL() string { - return fmt.Sprintf("https://cwe.mitre.org/data/definitions/%s.html", w.ID) -} - -// SprintID format the CWE ID -func (w *Weakness) SprintID() string { - id := "0000" - if w != nil { - id = w.ID - } - return fmt.Sprintf("%s-%s", Acronym, id) -} - -// MarshalJSON print only id and URL -func (w *Weakness) MarshalJSON() ([]byte, error) { - return json.Marshal(&struct { - ID string `json:"id"` - URL string `json:"url"` - }{ - ID: w.ID, - URL: w.SprintURL(), - }) -} diff --git a/vendor/github.com/securego/gosec/v2/entrypoint.sh b/vendor/github.com/securego/gosec/v2/entrypoint.sh deleted file mode 100644 index bc6ad6a24..000000000 --- a/vendor/github.com/securego/gosec/v2/entrypoint.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -# Expand the arguments into an array of strings. This is required because the GitHub action -# provides all arguments concatenated as a single string. -ARGS=("$@") - -if [[ ! -z "${GITHUB_AUTHENTICATION_TOKEN}" ]]; then - git config --global --add url."https://x-access-token:${GITHUB_AUTHENTICATION_TOKEN}@github.com/".insteadOf "https://github.com/" -fi - -/bin/gosec ${ARGS[*]} diff --git a/vendor/github.com/securego/gosec/v2/errors.go b/vendor/github.com/securego/gosec/v2/errors.go deleted file mode 100644 index 2f6672704..000000000 --- a/vendor/github.com/securego/gosec/v2/errors.go +++ /dev/null @@ -1,33 +0,0 @@ -package gosec - -import ( - "sort" -) - -// Error is used when there are golang errors while parsing the AST -type Error struct { - Line int `json:"line"` - Column int `json:"column"` - Err string `json:"error"` -} - -// NewError creates Error object -func NewError(line, column int, err string) *Error { - return &Error{ - Line: line, - Column: column, - Err: err, - } -} - -// sortErrors sorts the golang errors by line -func sortErrors(allErrors map[string][]Error) { - for _, errors := range allErrors { - sort.Slice(errors, func(i, j int) bool { - if errors[i].Line == errors[j].Line { - return errors[i].Column <= errors[j].Column - } - return errors[i].Line < errors[j].Line - }) - } -} diff --git a/vendor/github.com/securego/gosec/v2/helpers.go b/vendor/github.com/securego/gosec/v2/helpers.go deleted file mode 100644 index 1089f52c0..000000000 --- a/vendor/github.com/securego/gosec/v2/helpers.go +++ /dev/null @@ -1,555 +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 gosec - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "go/ast" - "go/token" - "go/types" - "os" - "os/exec" - "os/user" - "path/filepath" - "regexp" - "runtime" - "strconv" - "strings" -) - -// envGoModVersion overrides the Go version detection. -const envGoModVersion = "GOSECGOVERSION" - -// MatchCallByPackage ensures that the specified package is imported, -// adjusts the name for any aliases and ignores cases that are -// initialization only imports. -// -// Usage: -// -// node, matched := MatchCallByPackage(n, ctx, "math/rand", "Read") -func MatchCallByPackage(n ast.Node, c *Context, pkg string, names ...string) (*ast.CallExpr, bool) { - importedNames, found := GetImportedNames(pkg, c) - if !found { - return nil, false - } - - if callExpr, ok := n.(*ast.CallExpr); ok { - packageName, callName, err := GetCallInfo(callExpr, c) - if err != nil { - return nil, false - } - for _, in := range importedNames { - if packageName != in { - continue - } - for _, name := range names { - if callName == name { - return callExpr, true - } - } - } - } - return nil, false -} - -// MatchCompLit will match an ast.CompositeLit based on the supplied type -func MatchCompLit(n ast.Node, ctx *Context, required string) *ast.CompositeLit { - if complit, ok := n.(*ast.CompositeLit); ok { - typeOf := ctx.Info.TypeOf(complit) - if typeOf.String() == required { - return complit - } - } - return nil -} - -// GetInt will read and return an integer value from an ast.BasicLit -func GetInt(n ast.Node) (int64, error) { - if node, ok := n.(*ast.BasicLit); ok && node.Kind == token.INT { - return strconv.ParseInt(node.Value, 0, 64) - } - return 0, fmt.Errorf("Unexpected AST node type: %T", n) -} - -// GetFloat will read and return a float value from an ast.BasicLit -func GetFloat(n ast.Node) (float64, error) { - if node, ok := n.(*ast.BasicLit); ok && node.Kind == token.FLOAT { - return strconv.ParseFloat(node.Value, 64) - } - return 0.0, fmt.Errorf("Unexpected AST node type: %T", n) -} - -// GetChar will read and return a char value from an ast.BasicLit -func GetChar(n ast.Node) (byte, error) { - if node, ok := n.(*ast.BasicLit); ok && node.Kind == token.CHAR { - return node.Value[0], nil - } - return 0, fmt.Errorf("Unexpected AST node type: %T", n) -} - -// GetStringRecursive will recursively walk down a tree of *ast.BinaryExpr. It will then concat the results, and return. -// Unlike the other getters, it does _not_ raise an error for unknown ast.Node types. At the base, the recursion will hit a non-BinaryExpr type, -// either BasicLit or other, so it's not an error case. It will only error if `strconv.Unquote` errors. This matters, because there's -// currently functionality that relies on error values being returned by GetString if and when it hits a non-basiclit string node type, -// hence for cases where recursion is needed, we use this separate function, so that we can still be backwards compatible. -// -// This was added to handle a SQL injection concatenation case where the injected value is infixed between two strings, not at the start or end. See example below -// -// Do note that this will omit non-string values. So for example, if you were to use this node: -// ```go -// q := "SELECT * FROM foo WHERE name = '" + os.Args[0] + "' AND 1=1" // will result in "SELECT * FROM foo WHERE ” AND 1=1" - -func GetStringRecursive(n ast.Node) (string, error) { - if node, ok := n.(*ast.BasicLit); ok && node.Kind == token.STRING { - return strconv.Unquote(node.Value) - } - - if expr, ok := n.(*ast.BinaryExpr); ok { - x, err := GetStringRecursive(expr.X) - if err != nil { - return "", err - } - - y, err := GetStringRecursive(expr.Y) - if err != nil { - return "", err - } - - return x + y, nil - } - - return "", nil -} - -// GetString will read and return a string value from an ast.BasicLit -func GetString(n ast.Node) (string, error) { - if node, ok := n.(*ast.BasicLit); ok && node.Kind == token.STRING { - return strconv.Unquote(node.Value) - } - - return "", fmt.Errorf("Unexpected AST node type: %T", n) -} - -// GetCallObject returns the object and call expression and associated -// object for a given AST node. nil, nil will be returned if the -// object cannot be resolved. -func GetCallObject(n ast.Node, ctx *Context) (*ast.CallExpr, types.Object) { - switch node := n.(type) { - case *ast.CallExpr: - switch fn := node.Fun.(type) { - case *ast.Ident: - return node, ctx.Info.Uses[fn] - case *ast.SelectorExpr: - return node, ctx.Info.Uses[fn.Sel] - } - } - return nil, nil -} - -// GetCallInfo returns the package or type and name associated with a -// call expression. -func GetCallInfo(n ast.Node, ctx *Context) (string, string, error) { - switch node := n.(type) { - case *ast.CallExpr: - switch fn := node.Fun.(type) { - case *ast.SelectorExpr: - switch expr := fn.X.(type) { - case *ast.Ident: - if expr.Obj != nil && expr.Obj.Kind == ast.Var { - t := ctx.Info.TypeOf(expr) - if t != nil { - return t.String(), fn.Sel.Name, nil - } - return "undefined", fn.Sel.Name, fmt.Errorf("missing type info") - } - return expr.Name, fn.Sel.Name, nil - case *ast.SelectorExpr: - if expr.Sel != nil { - t := ctx.Info.TypeOf(expr.Sel) - if t != nil { - return t.String(), fn.Sel.Name, nil - } - return "undefined", fn.Sel.Name, fmt.Errorf("missing type info") - } - case *ast.CallExpr: - switch call := expr.Fun.(type) { - case *ast.Ident: - if call.Name == "new" && len(expr.Args) > 0 { - t := ctx.Info.TypeOf(expr.Args[0]) - if t != nil { - return t.String(), fn.Sel.Name, nil - } - return "undefined", fn.Sel.Name, fmt.Errorf("missing type info") - } - if call.Obj != nil { - switch decl := call.Obj.Decl.(type) { - case *ast.FuncDecl: - ret := decl.Type.Results - if ret != nil && len(ret.List) > 0 { - ret1 := ret.List[0] - if ret1 != nil { - t := ctx.Info.TypeOf(ret1.Type) - if t != nil { - return t.String(), fn.Sel.Name, nil - } - return "undefined", fn.Sel.Name, fmt.Errorf("missing type info") - } - } - } - } - } - } - case *ast.Ident: - return ctx.Pkg.Name(), fn.Name, nil - } - } - - return "", "", fmt.Errorf("unable to determine call info") -} - -// GetCallStringArgsValues returns the values of strings arguments if they can be resolved -func GetCallStringArgsValues(n ast.Node, _ *Context) []string { - values := []string{} - switch node := n.(type) { - case *ast.CallExpr: - for _, arg := range node.Args { - switch param := arg.(type) { - case *ast.BasicLit: - value, err := GetString(param) - if err == nil { - values = append(values, value) - } - case *ast.Ident: - values = append(values, GetIdentStringValues(param)...) - } - } - } - return values -} - -func getIdentStringValues(ident *ast.Ident, stringFinder func(ast.Node) (string, error)) []string { - values := []string{} - obj := ident.Obj - if obj != nil { - switch decl := obj.Decl.(type) { - case *ast.ValueSpec: - for _, v := range decl.Values { - value, err := stringFinder(v) - if err == nil { - values = append(values, value) - } - } - case *ast.AssignStmt: - for _, v := range decl.Rhs { - value, err := stringFinder(v) - if err == nil { - values = append(values, value) - } - } - } - } - return values -} - -// GetIdentStringValuesRecursive returns the string of values of an Ident if they can be resolved -// The difference between this and GetIdentStringValues is that it will attempt to resolve the strings recursively, -// if it is passed a *ast.BinaryExpr. See GetStringRecursive for details -func GetIdentStringValuesRecursive(ident *ast.Ident) []string { - return getIdentStringValues(ident, GetStringRecursive) -} - -// GetIdentStringValues return the string values of an Ident if they can be resolved -func GetIdentStringValues(ident *ast.Ident) []string { - return getIdentStringValues(ident, GetString) -} - -// 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 -} - -// GetImportedNames returns the name(s)/alias(es) used for the package within -// the code. It ignores initialization-only imports. -func GetImportedNames(path string, ctx *Context) (names []string, found bool) { - importNames, imported := ctx.Imports.Imported[path] - return importNames, imported -} - -// GetImportPath resolves the full import path of an identifier based on -// the imports in the current context(including aliases). -func GetImportPath(name string, ctx *Context) (string, bool) { - for path := range ctx.Imports.Imported { - if imported, ok := GetImportedNames(path, ctx); ok { - for _, n := range imported { - if n == name { - return path, true - } - } - } - } - - return "", false -} - -// GetLocation returns the filename and line number of an ast.Node -func GetLocation(n ast.Node, ctx *Context) (string, int) { - fobj := ctx.FileSet.File(n.Pos()) - return fobj.Name(), fobj.Line(n.Pos()) -} - -// Gopath returns all GOPATHs -func Gopath() []string { - defaultGoPath := runtime.GOROOT() - if u, err := user.Current(); err == nil { - defaultGoPath = filepath.Join(u.HomeDir, "go") - } - path := Getenv("GOPATH", defaultGoPath) - paths := strings.Split(path, string(os.PathListSeparator)) - for idx, path := range paths { - if abs, err := filepath.Abs(path); err == nil { - paths[idx] = abs - } - } - return paths -} - -// Getenv returns the values of the environment variable, otherwise -// returns the default if variable is not set -func Getenv(key, userDefault string) string { - if val := os.Getenv(key); val != "" { - return val - } - return userDefault -} - -// GetPkgRelativePath returns the Go relative path derived -// form the given path -func GetPkgRelativePath(path string) (string, error) { - abspath, err := filepath.Abs(path) - if err != nil { - abspath = path - } - if strings.HasSuffix(abspath, ".go") { - abspath = filepath.Dir(abspath) - } - for _, base := range Gopath() { - projectRoot := filepath.FromSlash(fmt.Sprintf("%s/src/", base)) - if strings.HasPrefix(abspath, projectRoot) { - return strings.TrimPrefix(abspath, projectRoot), nil - } - } - return "", errors.New("no project relative path found") -} - -// GetPkgAbsPath returns the Go package absolute path derived from -// the given path -func GetPkgAbsPath(pkgPath string) (string, error) { - absPath, err := filepath.Abs(pkgPath) - if err != nil { - return "", err - } - if _, err := os.Stat(absPath); os.IsNotExist(err) { - return "", errors.New("no project absolute path found") - } - return absPath, nil -} - -// ConcatString recursively concatenates strings from a binary expression -func ConcatString(n *ast.BinaryExpr) (string, bool) { - var s string - // sub expressions are found in X object, Y object is always last BasicLit - if rightOperand, ok := n.Y.(*ast.BasicLit); ok { - if str, err := GetString(rightOperand); err == nil { - s = str + s - } - } else { - return "", false - } - if leftOperand, ok := n.X.(*ast.BinaryExpr); ok { - if recursion, ok := ConcatString(leftOperand); ok { - s = recursion + s - } - } else if leftOperand, ok := n.X.(*ast.BasicLit); ok { - if str, err := GetString(leftOperand); err == nil { - s = str + s - } - } else { - return "", false - } - return s, true -} - -// FindVarIdentities returns array of all variable identities in a given binary expression -func FindVarIdentities(n *ast.BinaryExpr, c *Context) ([]*ast.Ident, bool) { - identities := []*ast.Ident{} - // sub expressions are found in X object, Y object is always the last term - if rightOperand, ok := n.Y.(*ast.Ident); ok { - obj := c.Info.ObjectOf(rightOperand) - if _, ok := obj.(*types.Var); ok && !TryResolve(rightOperand, c) { - identities = append(identities, rightOperand) - } - } - if leftOperand, ok := n.X.(*ast.BinaryExpr); ok { - if leftIdentities, ok := FindVarIdentities(leftOperand, c); ok { - identities = append(identities, leftIdentities...) - } - } else { - if leftOperand, ok := n.X.(*ast.Ident); ok { - obj := c.Info.ObjectOf(leftOperand) - if _, ok := obj.(*types.Var); ok && !TryResolve(leftOperand, c) { - identities = append(identities, leftOperand) - } - } - } - - if len(identities) > 0 { - return identities, true - } - // if nil or error, return false - return nil, false -} - -// PackagePaths returns a slice with all packages path at given root directory -func PackagePaths(root string, excludes []*regexp.Regexp) ([]string, error) { - if strings.HasSuffix(root, "...") { - root = root[0 : len(root)-3] - } else { - return []string{root}, nil - } - paths := map[string]bool{} - err := filepath.Walk(root, func(path string, f os.FileInfo, err error) error { - if filepath.Ext(path) == ".go" { - path = filepath.Dir(path) - if isExcluded(filepath.ToSlash(path), excludes) { - return nil - } - paths[path] = true - } - return nil - }) - if err != nil { - return []string{}, err - } - - result := []string{} - for path := range paths { - result = append(result, path) - } - return result, nil -} - -// isExcluded checks if a string matches any of the exclusion regexps -func isExcluded(str string, excludes []*regexp.Regexp) bool { - if excludes == nil { - return false - } - for _, exclude := range excludes { - if exclude != nil && exclude.MatchString(str) { - return true - } - } - return false -} - -// ExcludedDirsRegExp builds the regexps for a list of excluded dirs provided as strings -func ExcludedDirsRegExp(excludedDirs []string) []*regexp.Regexp { - var exps []*regexp.Regexp - for _, excludedDir := range excludedDirs { - str := fmt.Sprintf(`([\\/])?%s([\\/])?`, strings.ReplaceAll(filepath.ToSlash(excludedDir), "/", `\/`)) - r := regexp.MustCompile(str) - exps = append(exps, r) - } - return exps -} - -// RootPath returns the absolute root path of a scan -func RootPath(root string) (string, error) { - root = strings.TrimSuffix(root, "...") - return filepath.Abs(root) -} - -// GoVersion returns parsed version of Go mod version and fallback to runtime version if not found. -func GoVersion() (int, int, int) { - if env, ok := os.LookupEnv(envGoModVersion); ok { - return parseGoVersion(strings.TrimPrefix(env, "go")) - } - - goVersion, err := goModVersion() - if err != nil { - return parseGoVersion(strings.TrimPrefix(runtime.Version(), "go")) - } - - return parseGoVersion(goVersion) -} - -type goListOutput struct { - GoVersion string `json:"GoVersion"` -} - -func goModVersion() (string, error) { - cmd := exec.Command("go", "list", "-m", "-json") - - raw, err := cmd.CombinedOutput() - if err != nil { - return "", fmt.Errorf("command go list: %w: %s", err, string(raw)) - } - - var v goListOutput - err = json.NewDecoder(bytes.NewBuffer(raw)).Decode(&v) - if err != nil { - return "", fmt.Errorf("unmarshaling error: %w: %s", err, string(raw)) - } - - return v.GoVersion, nil -} - -// parseGoVersion parses Go version. -// example: -// - 1.19rc2 -// - 1.19beta2 -// - 1.19.4 -// - 1.19 -func parseGoVersion(version string) (int, int, int) { - exp := regexp.MustCompile(`(\d+).(\d+)(?:.(\d+))?.*`) - parts := exp.FindStringSubmatch(version) - if len(parts) <= 1 { - return 0, 0, 0 - } - - major, _ := strconv.Atoi(parts[1]) - minor, _ := strconv.Atoi(parts[2]) - build, _ := strconv.Atoi(parts[3]) - - return major, minor, build -} diff --git a/vendor/github.com/securego/gosec/v2/import_tracker.go b/vendor/github.com/securego/gosec/v2/import_tracker.go deleted file mode 100644 index 0d9ebfe16..000000000 --- a/vendor/github.com/securego/gosec/v2/import_tracker.go +++ /dev/null @@ -1,78 +0,0 @@ -// 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 gosec - -import ( - "go/ast" - "go/types" - "regexp" - "strings" -) - -var versioningPackagePattern = regexp.MustCompile(`v[0-9]+$`) - -// ImportTracker is used to normalize the packages that have been imported -// by a source file. It is able to differentiate between plain imports, aliased -// imports and init only imports. -type ImportTracker struct { - // Imported is a map of Imported with their associated names/aliases. - Imported map[string][]string -} - -// NewImportTracker creates an empty Import tracker instance -func NewImportTracker() *ImportTracker { - return &ImportTracker{ - Imported: make(map[string][]string), - } -} - -// TrackFile track all the imports used by the supplied file -func (t *ImportTracker) TrackFile(file *ast.File) { - for _, imp := range file.Imports { - t.TrackImport(imp) - } -} - -// TrackPackages tracks all the imports used by the supplied packages -func (t *ImportTracker) TrackPackages(pkgs ...*types.Package) { - for _, pkg := range pkgs { - t.Imported[pkg.Path()] = []string{pkg.Name()} - } -} - -// TrackImport tracks imports. -func (t *ImportTracker) TrackImport(imported *ast.ImportSpec) { - importPath := strings.Trim(imported.Path.Value, `"`) - if imported.Name != nil { - if imported.Name.Name != "_" { - // Aliased import - t.Imported[importPath] = append(t.Imported[importPath], imported.Name.String()) - } - } else { - t.Imported[importPath] = append(t.Imported[importPath], importName(importPath)) - } -} - -func importName(importPath string) string { - parts := strings.Split(importPath, "/") - name := importPath - if len(parts) > 0 { - name = parts[len(parts)-1] - } - // If the last segment of the path is version information, consider the second to last segment as the package name. - // (e.g., `math/rand/v2` would be `rand`) - if len(parts) > 1 && versioningPackagePattern.MatchString(name) { - name = parts[len(parts)-2] - } - return name -} diff --git a/vendor/github.com/securego/gosec/v2/install.sh b/vendor/github.com/securego/gosec/v2/install.sh deleted file mode 100644 index 2b6403cb2..000000000 --- a/vendor/github.com/securego/gosec/v2/install.sh +++ /dev/null @@ -1,377 +0,0 @@ -#!/bin/sh -set -e -# Code generated by godownloader. DO NOT EDIT. -# - -usage() { - this=$1 - cat </dev/null -} -echoerr() { - echo "$@" 1>&2 -} -log_prefix() { - echo "$0" -} -_logp=6 -log_set_priority() { - _logp="$1" -} -log_priority() { - if test -z "$1"; then - echo "$_logp" - return - fi - [ "$1" -le "$_logp" ] -} -log_tag() { - case $1 in - 0) echo "emerg" ;; - 1) echo "alert" ;; - 2) echo "crit" ;; - 3) echo "err" ;; - 4) echo "warning" ;; - 5) echo "notice" ;; - 6) echo "info" ;; - 7) echo "debug" ;; - *) echo "$1" ;; - esac -} -log_debug() { - log_priority 7 || return 0 - echoerr "$(log_prefix)" "$(log_tag 7)" "$@" -} -log_info() { - log_priority 6 || return 0 - echoerr "$(log_prefix)" "$(log_tag 6)" "$@" -} -log_err() { - log_priority 3 || return 0 - echoerr "$(log_prefix)" "$(log_tag 3)" "$@" -} -log_crit() { - log_priority 2 || return 0 - echoerr "$(log_prefix)" "$(log_tag 2)" "$@" -} -uname_os() { - os=$(uname -s | tr '[:upper:]' '[:lower:]') - case "$os" in - cygwin_nt*) os="windows" ;; - mingw*) os="windows" ;; - msys_nt*) os="windows" ;; - esac - echo "$os" -} -uname_arch() { - arch=$(uname -m) - case $arch in - x86_64) arch="amd64" ;; - x86) arch="386" ;; - i686) arch="386" ;; - i386) arch="386" ;; - aarch64) arch="arm64" ;; - armv5*) arch="armv5" ;; - armv6*) arch="armv6" ;; - armv7*) arch="armv7" ;; - esac - echo ${arch} -} -uname_os_check() { - os=$(uname_os) - case "$os" in - darwin) return 0 ;; - dragonfly) return 0 ;; - freebsd) return 0 ;; - linux) return 0 ;; - android) return 0 ;; - nacl) return 0 ;; - netbsd) return 0 ;; - openbsd) return 0 ;; - plan9) return 0 ;; - solaris) return 0 ;; - windows) return 0 ;; - esac - log_crit "uname_os_check '$(uname -s)' got converted to '$os' which is not a GOOS value. Please file bug at https://github.com/client9/shlib" - return 1 -} -uname_arch_check() { - arch=$(uname_arch) - case "$arch" in - 386) return 0 ;; - amd64) return 0 ;; - arm64) return 0 ;; - armv5) return 0 ;; - armv6) return 0 ;; - armv7) return 0 ;; - ppc64) return 0 ;; - ppc64le) return 0 ;; - mips) return 0 ;; - mipsle) return 0 ;; - mips64) return 0 ;; - mips64le) return 0 ;; - s390x) return 0 ;; - amd64p32) return 0 ;; - esac - log_crit "uname_arch_check '$(uname -m)' got converted to '$arch' which is not a GOARCH value. Please file bug report at https://github.com/client9/shlib" - return 1 -} -untar() { - tarball=$1 - case "${tarball}" in - *.tar.gz | *.tgz) tar --no-same-owner -xzf "${tarball}" ;; - *.tar) tar --no-same-owner -xf "${tarball}" ;; - *.zip) unzip "${tarball}" ;; - *) - log_err "untar unknown archive format for ${tarball}" - return 1 - ;; - esac -} -http_download_curl() { - local_file=$1 - source_url=$2 - header=$3 - if [ -z "$header" ]; then - code=$(curl -w '%{http_code}' -sL -o "$local_file" "$source_url") - else - code=$(curl -w '%{http_code}' -sL -H "$header" -o "$local_file" "$source_url") - fi - if [ "$code" != "200" ]; then - log_debug "http_download_curl received HTTP status $code" - return 1 - fi - return 0 -} -http_download_wget() { - local_file=$1 - source_url=$2 - header=$3 - if [ -z "$header" ]; then - wget -q -O "$local_file" "$source_url" - else - wget -q --header "$header" -O "$local_file" "$source_url" - fi -} -http_download() { - log_debug "http_download $2" - if is_command curl; then - http_download_curl "$@" - return - elif is_command wget; then - http_download_wget "$@" - return - fi - log_crit "http_download unable to find wget or curl" - return 1 -} -http_copy() { - tmp=$(mktemp) - http_download "${tmp}" "$1" "$2" || return 1 - body=$(cat "$tmp") - rm -f "${tmp}" - echo "$body" -} -github_release() { - owner_repo=$1 - version=$2 - giturl="https://api.github.com/repos/${owner_repo}/releases/tags/${version}" - if [ -z "${version}" ]; then - giturl="https://api.github.com/repos/${owner_repo}/releases/latest" - fi - json=$(http_copy "$giturl" "Accept:application/json") - test -z "$json" && return 1 - version=$(echo "$json" | tr -s '\n' ' ' | sed 's/.*"tag_name": *"//' | sed 's/".*//') - test -z "$version" && return 1 - echo "$version" -} -hash_sha256() { - TARGET=${1:-/dev/stdin} - if is_command gsha256sum; then - hash=$(gsha256sum "$TARGET") || return 1 - echo "$hash" | cut -d ' ' -f 1 - elif is_command sha256sum; then - hash=$(sha256sum "$TARGET") || return 1 - echo "$hash" | cut -d ' ' -f 1 - elif is_command shasum; then - hash=$(shasum -a 256 "$TARGET" 2>/dev/null) || return 1 - echo "$hash" | cut -d ' ' -f 1 - elif is_command openssl; then - hash=$(openssl -dst openssl dgst -sha256 "$TARGET") || return 1 - echo "$hash" | cut -d ' ' -f a - else - log_crit "hash_sha256 unable to find command to compute sha-256 hash" - return 1 - fi -} -hash_sha256_verify() { - TARGET=$1 - checksums=$2 - if [ -z "$checksums" ]; then - log_err "hash_sha256_verify checksum file not specified in arg2" - return 1 - fi - BASENAME=${TARGET##*/} - want=$(grep "${BASENAME}" "${checksums}" 2>/dev/null | tr '\t' ' ' | cut -d ' ' -f 1) - if [ -z "$want" ]; then - log_err "hash_sha256_verify unable to find checksum for '${TARGET}' in '${checksums}'" - return 1 - fi - got=$(hash_sha256 "$TARGET") - if [ "$want" != "$got" ]; then - log_err "hash_sha256_verify checksum for '$TARGET' did not verify ${want} vs $got" - return 1 - fi -} -cat /dev/null < end { - break - } else if pos >= start && pos <= end { - code := fmt.Sprintf("%d: %s\n", pos, scanner.Text()) - buf.WriteString(code) - } - } - return buf.String(), nil -} - -func codeSnippetStartLine(node ast.Node, fobj *token.File) int64 { - s := (int64)(fobj.Line(node.Pos())) - if s-SnippetOffset > 0 { - return s - SnippetOffset - } - return s -} - -func codeSnippetEndLine(node ast.Node, fobj *token.File) int64 { - e := (int64)(fobj.Line(node.End())) - return e + SnippetOffset -} - -// New creates a new Issue -func New(fobj *token.File, node ast.Node, ruleID, desc string, severity, confidence Score) *Issue { - name := fobj.Name() - line := GetLine(fobj, node) - col := strconv.Itoa(fobj.Position(node.Pos()).Column) - - var code string - if node == nil { - code = "invalid AST node provided" - } - if file, err := os.Open(fobj.Name()); err == nil && node != nil { - defer file.Close() // #nosec - s := codeSnippetStartLine(node, fobj) - e := codeSnippetEndLine(node, fobj) - code, err = CodeSnippet(file, s, e) - if err != nil { - code = err.Error() - } - } - - return &Issue{ - File: name, - Line: line, - Col: col, - RuleID: ruleID, - What: desc, - Confidence: confidence, - Severity: severity, - Code: code, - Cwe: GetCweByRule(ruleID), - } -} - -// WithSuppressions set the suppressions of the issue -func (i *Issue) WithSuppressions(suppressions []SuppressionInfo) *Issue { - i.Suppressions = suppressions - return i -} - -// GetLine returns the line number of a given ast.Node -func GetLine(fobj *token.File, node ast.Node) string { - start, end := fobj.Line(node.Pos()), fobj.Line(node.End()) - line := strconv.Itoa(start) - if start != end { - line = fmt.Sprintf("%d-%d", start, end) - } - return line -} diff --git a/vendor/github.com/securego/gosec/v2/perf-diff.sh b/vendor/github.com/securego/gosec/v2/perf-diff.sh deleted file mode 100644 index cf3084cbf..000000000 --- a/vendor/github.com/securego/gosec/v2/perf-diff.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash - -BIN="gosec" -BUILD_DIR="/tmp/securego" - -# Scan the current folder and measure the duration. -function scan() { - local scan_cmd=$1 - s=$(date +%s%3N) - $scan_cmd -quiet ./... - e=$(date +%s%3N) - res=$(expr $e - $s) - echo $res -} - -# Build the master reference version. -mkdir -p ${BUILD_DIR} -git clone --quiet https://github.com/securego/gosec.git ${BUILD_DIR} >/dev/null -make -C ${BUILD_DIR} >/dev/null - -# Scan once with the main reference. -duration_master=$(scan "${BUILD_DIR}/${BIN}") -echo "gosec reference time: ${duration_master}ms" - -# Build the current version. -make -C . >/dev/null - -# Scan once with the current version. -duration=$(scan "./${BIN}") -echo "gosec time: ${duration}ms" - -# Compute the difference of the execution time. -diff=$(($duration - $duration_master)) -if [[ diff -lt 0 ]]; then - diff=$(($diff * -1)) -fi -echo "diff: ${diff}ms" -perf=$((100 - ($duration * 100) / $duration_master)) -echo "perf diff: ${perf}%" - -# Fail the build if there is a performance degradation of more than 10%. -if [[ $perf -lt -10 ]]; then - exit 1 -fi diff --git a/vendor/github.com/securego/gosec/v2/renovate.json b/vendor/github.com/securego/gosec/v2/renovate.json deleted file mode 100644 index 58ee1e0ea..000000000 --- a/vendor/github.com/securego/gosec/v2/renovate.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "dependencyDashboard": true, - "dependencyDashboardTitle" : "Renovate(bot) : dependency dashboard", - "vulnerabilityAlerts": { - "enabled": true - }, - "extends": [ - ":preserveSemverRanges", - "group:all", - "schedule:weekly" - ], - "lockFileMaintenance": { - "commitMessageAction": "Update", - "enabled": true, - "extends": [ - "group:all", - "schedule:weekly" - ] - }, - "postUpdateOptions": [ - "gomodTidy", - "gomodUpdateImportPaths" - ], - "separateMajorMinor": false -} diff --git a/vendor/github.com/securego/gosec/v2/report.go b/vendor/github.com/securego/gosec/v2/report.go deleted file mode 100644 index 4fdeea520..000000000 --- a/vendor/github.com/securego/gosec/v2/report.go +++ /dev/null @@ -1,28 +0,0 @@ -package gosec - -import ( - "github.com/securego/gosec/v2/issue" -) - -// ReportInfo this is report information -type ReportInfo struct { - Errors map[string][]Error `json:"Golang errors"` - Issues []*issue.Issue - Stats *Metrics - GosecVersion string -} - -// NewReportInfo instantiate a ReportInfo -func NewReportInfo(issues []*issue.Issue, metrics *Metrics, errors map[string][]Error) *ReportInfo { - return &ReportInfo{ - Errors: errors, - Issues: issues, - Stats: metrics, - } -} - -// WithVersion defines the version of gosec used to generate the report -func (r *ReportInfo) WithVersion(version string) *ReportInfo { - r.GosecVersion = version - return r -} diff --git a/vendor/github.com/securego/gosec/v2/resolve.go b/vendor/github.com/securego/gosec/v2/resolve.go deleted file mode 100644 index a201b8d32..000000000 --- a/vendor/github.com/securego/gosec/v2/resolve.go +++ /dev/null @@ -1,95 +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 gosec - -import "go/ast" - -func resolveIdent(n *ast.Ident, c *Context) bool { - if n.Obj == nil || n.Obj.Kind != ast.Var { - return true - } - if node, ok := n.Obj.Decl.(ast.Node); ok { - return TryResolve(node, c) - } - return false -} - -func resolveValueSpec(n *ast.ValueSpec, c *Context) bool { - if len(n.Values) == 0 { - return false - } - for _, value := range n.Values { - if !TryResolve(value, c) { - return false - } - } - return true -} - -func resolveAssign(n *ast.AssignStmt, c *Context) bool { - if len(n.Rhs) == 0 { - return false - } - for _, arg := range n.Rhs { - if !TryResolve(arg, c) { - return false - } - } - return true -} - -func resolveCompLit(n *ast.CompositeLit, c *Context) bool { - if len(n.Elts) == 0 { - return false - } - for _, arg := range n.Elts { - if !TryResolve(arg, c) { - return false - } - } - return true -} - -func resolveBinExpr(n *ast.BinaryExpr, c *Context) bool { - return (TryResolve(n.X, c) && TryResolve(n.Y, c)) -} - -func resolveCallExpr(_ *ast.CallExpr, _ *Context) bool { - // TODO(tkelsey): next step, full function resolution - return false -} - -// TryResolve will attempt, given a subtree starting at some AST node, to resolve -// all values contained within to a known constant. It is used to check for any -// unknown values in compound expressions. -func TryResolve(n ast.Node, c *Context) bool { - switch node := n.(type) { - case *ast.BasicLit: - return true - case *ast.CompositeLit: - return resolveCompLit(node, c) - case *ast.Ident: - return resolveIdent(node, c) - case *ast.ValueSpec: - return resolveValueSpec(node, c) - case *ast.AssignStmt: - return resolveAssign(node, c) - case *ast.CallExpr: - return resolveCallExpr(node, c) - case *ast.BinaryExpr: - return resolveBinExpr(node, c) - } - return false -} diff --git a/vendor/github.com/securego/gosec/v2/rule.go b/vendor/github.com/securego/gosec/v2/rule.go deleted file mode 100644 index 490a25da0..000000000 --- a/vendor/github.com/securego/gosec/v2/rule.go +++ /dev/null @@ -1,72 +0,0 @@ -// 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 gosec - -import ( - "go/ast" - "reflect" - - "github.com/securego/gosec/v2/issue" -) - -// The Rule interface used by all rules supported by gosec. -type Rule interface { - ID() string - Match(ast.Node, *Context) (*issue.Issue, error) -} - -// RuleBuilder is used to register a rule definition with the analyzer -type RuleBuilder func(id string, c Config) (Rule, []ast.Node) - -// A RuleSet contains a mapping of lists of rules to the type of AST node they -// should be run on and a mapping of rule ID's to whether the rule are -// suppressed. -// The analyzer will only invoke rules contained in the list associated with the -// type of AST node it is currently visiting. -type RuleSet struct { - Rules map[reflect.Type][]Rule - RuleSuppressedMap map[string]bool -} - -// NewRuleSet constructs a new RuleSet -func NewRuleSet() RuleSet { - return RuleSet{make(map[reflect.Type][]Rule), make(map[string]bool)} -} - -// Register adds a trigger for the supplied rule for the -// specified ast nodes. -func (r RuleSet) Register(rule Rule, isSuppressed bool, nodes ...ast.Node) { - for _, n := range nodes { - t := reflect.TypeOf(n) - if rules, ok := r.Rules[t]; ok { - r.Rules[t] = append(rules, rule) - } else { - r.Rules[t] = []Rule{rule} - } - } - r.RuleSuppressedMap[rule.ID()] = isSuppressed -} - -// RegisteredFor will return all rules that are registered for a -// specified ast node. -func (r RuleSet) RegisteredFor(n ast.Node) []Rule { - if rules, found := r.Rules[reflect.TypeOf(n)]; found { - return rules - } - return []Rule{} -} - -// IsRuleSuppressed will return whether the rule is suppressed. -func (r RuleSet) IsRuleSuppressed(ruleID string) bool { - return r.RuleSuppressedMap[ruleID] -} diff --git a/vendor/github.com/securego/gosec/v2/rules/archive.go b/vendor/github.com/securego/gosec/v2/rules/archive.go deleted file mode 100644 index 987047435..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/archive.go +++ /dev/null @@ -1,66 +0,0 @@ -package rules - -import ( - "go/ast" - "go/types" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/issue" -) - -type archive struct { - issue.MetaData - calls gosec.CallList - argTypes []string -} - -func (a *archive) ID() string { - return a.MetaData.ID -} - -// Match inspects AST nodes to determine if the filepath.Joins uses any argument derived from type zip.File or tar.Header -func (a *archive) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { - if node := a.calls.ContainsPkgCallExpr(n, c, false); node != nil { - for _, arg := range node.Args { - var argType types.Type - if selector, ok := arg.(*ast.SelectorExpr); ok { - argType = c.Info.TypeOf(selector.X) - } else if ident, ok := arg.(*ast.Ident); ok { - if ident.Obj != nil && ident.Obj.Kind == ast.Var { - decl := ident.Obj.Decl - if assign, ok := decl.(*ast.AssignStmt); ok { - if selector, ok := assign.Rhs[0].(*ast.SelectorExpr); ok { - argType = c.Info.TypeOf(selector.X) - } - } - } - } - - if argType != nil { - for _, t := range a.argTypes { - if argType.String() == t { - return c.NewIssue(n, a.ID(), a.What, a.Severity, a.Confidence), nil - } - } - } - } - } - return nil, nil -} - -// NewArchive creates a new rule which detects the file traversal when extracting zip/tar archives -func NewArchive(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { - calls := gosec.NewCallList() - calls.Add("path/filepath", "Join") - calls.Add("path", "Join") - return &archive{ - calls: calls, - argTypes: []string{"*archive/zip.File", "*archive/tar.Header"}, - MetaData: issue.MetaData{ - ID: id, - Severity: issue.Medium, - Confidence: issue.High, - What: "File traversal when extracting zip/tar archive", - }, - }, []ast.Node{(*ast.CallExpr)(nil)} -} diff --git a/vendor/github.com/securego/gosec/v2/rules/bind.go b/vendor/github.com/securego/gosec/v2/rules/bind.go deleted file mode 100644 index fef760c80..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/bind.go +++ /dev/null @@ -1,84 +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" - "regexp" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/issue" -) - -// Looks for net.Listen("0.0.0.0") or net.Listen(":8080") -type bindsToAllNetworkInterfaces struct { - issue.MetaData - calls gosec.CallList - pattern *regexp.Regexp -} - -func (r *bindsToAllNetworkInterfaces) ID() string { - return r.MetaData.ID -} - -func (r *bindsToAllNetworkInterfaces) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { - callExpr := r.calls.ContainsPkgCallExpr(n, c, false) - if callExpr == nil { - return nil, nil - } - if len(callExpr.Args) > 1 { - arg := callExpr.Args[1] - if bl, ok := arg.(*ast.BasicLit); ok { - if arg, err := gosec.GetString(bl); err == nil { - if r.pattern.MatchString(arg) { - return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil - } - } - } else if ident, ok := arg.(*ast.Ident); ok { - values := gosec.GetIdentStringValues(ident) - for _, value := range values { - if r.pattern.MatchString(value) { - return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil - } - } - } - } else if len(callExpr.Args) > 0 { - values := gosec.GetCallStringArgsValues(callExpr.Args[0], c) - for _, value := range values { - if r.pattern.MatchString(value) { - return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil - } - } - } - return nil, nil -} - -// NewBindsToAllNetworkInterfaces detects socket connections that are setup to -// listen on all network interfaces. -func NewBindsToAllNetworkInterfaces(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { - calls := gosec.NewCallList() - calls.Add("net", "Listen") - calls.Add("crypto/tls", "Listen") - return &bindsToAllNetworkInterfaces{ - calls: calls, - pattern: regexp.MustCompile(`^(0.0.0.0|:).*$`), - MetaData: issue.MetaData{ - ID: id, - Severity: issue.Medium, - Confidence: issue.High, - What: "Binds to all network interfaces", - }, - }, []ast.Node{(*ast.CallExpr)(nil)} -} diff --git a/vendor/github.com/securego/gosec/v2/rules/blocklist.go b/vendor/github.com/securego/gosec/v2/rules/blocklist.go deleted file mode 100644 index a4376b19a..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/blocklist.go +++ /dev/null @@ -1,109 +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" - "github.com/securego/gosec/v2/issue" -) - -type blocklistedImport struct { - issue.MetaData - Blocklisted map[string]string -} - -func unquote(original string) string { - cleaned := strings.TrimSpace(original) - cleaned = strings.TrimLeft(cleaned, `"`) - return strings.TrimRight(cleaned, `"`) -} - -func (r *blocklistedImport) ID() string { - return r.MetaData.ID -} - -func (r *blocklistedImport) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { - if node, ok := n.(*ast.ImportSpec); ok { - if description, ok := r.Blocklisted[unquote(node.Path.Value)]; ok { - return c.NewIssue(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, _ gosec.Config, blocklist map[string]string) (gosec.Rule, []ast.Node) { - return &blocklistedImport{ - MetaData: issue.MetaData{ - ID: id, - Severity: issue.Medium, - Confidence: issue.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", - }) -} - -// NewBlocklistedImportMD4 fails if MD4 is imported -func NewBlocklistedImportMD4(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { - return NewBlocklistedImports(id, conf, map[string]string{ - "golang.org/x/crypto/md4": "Blocklisted import golang.org/x/crypto/md4: deprecated and weak cryptographic primitive", - }) -} - -// NewBlocklistedImportRIPEMD160 fails if RIPEMD160 is imported -func NewBlocklistedImportRIPEMD160(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { - return NewBlocklistedImports(id, conf, map[string]string{ - "golang.org/x/crypto/ripemd160": "Blocklisted import golang.org/x/crypto/ripemd160: deprecated and weak cryptographic primitive", - }) -} diff --git a/vendor/github.com/securego/gosec/v2/rules/decompression-bomb.go b/vendor/github.com/securego/gosec/v2/rules/decompression-bomb.go deleted file mode 100644 index 7e57f1a5b..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/decompression-bomb.go +++ /dev/null @@ -1,111 +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 ( - "fmt" - "go/ast" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/issue" -) - -type decompressionBombCheck struct { - issue.MetaData - readerCalls gosec.CallList - copyCalls gosec.CallList -} - -func (d *decompressionBombCheck) ID() string { - return d.MetaData.ID -} - -func containsReaderCall(node ast.Node, ctx *gosec.Context, list gosec.CallList) bool { - if list.ContainsPkgCallExpr(node, ctx, false) != nil { - return true - } - // Resolve type info of ident (for *archive/zip.File.Open) - s, idt, _ := gosec.GetCallInfo(node, ctx) - return list.Contains(s, idt) -} - -func (d *decompressionBombCheck) Match(node ast.Node, ctx *gosec.Context) (*issue.Issue, error) { - var readerVarObj map[*ast.Object]struct{} - - // To check multiple lines, ctx.PassedValues is used to store temporary data. - if _, ok := ctx.PassedValues[d.ID()]; !ok { - readerVarObj = make(map[*ast.Object]struct{}) - ctx.PassedValues[d.ID()] = readerVarObj - } else if pv, ok := ctx.PassedValues[d.ID()].(map[*ast.Object]struct{}); ok { - readerVarObj = pv - } else { - return nil, fmt.Errorf("PassedValues[%s] of Context is not map[*ast.Object]struct{}, but %T", d.ID(), ctx.PassedValues[d.ID()]) - } - - // io.Copy is a common function. - // To reduce false positives, This rule detects code which is used for compressed data only. - switch n := node.(type) { - case *ast.AssignStmt: - for _, expr := range n.Rhs { - if callExpr, ok := expr.(*ast.CallExpr); ok && containsReaderCall(callExpr, ctx, d.readerCalls) { - if idt, ok := n.Lhs[0].(*ast.Ident); ok && idt.Name != "_" { - // Example: - // r, _ := zlib.NewReader(buf) - // Add r's Obj to readerVarObj map - readerVarObj[idt.Obj] = struct{}{} - } - } - } - case *ast.CallExpr: - if d.copyCalls.ContainsPkgCallExpr(n, ctx, false) != nil { - if idt, ok := n.Args[1].(*ast.Ident); ok { - if _, ok := readerVarObj[idt.Obj]; ok { - // Detect io.Copy(x, r) - return ctx.NewIssue(n, d.ID(), d.What, d.Severity, d.Confidence), nil - } - } - } - } - - return nil, nil -} - -// NewDecompressionBombCheck detects if there is potential DoS vulnerability via decompression bomb -func NewDecompressionBombCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { - readerCalls := gosec.NewCallList() - readerCalls.Add("compress/gzip", "NewReader") - readerCalls.AddAll("compress/zlib", "NewReader", "NewReaderDict") - readerCalls.Add("compress/bzip2", "NewReader") - readerCalls.AddAll("compress/flate", "NewReader", "NewReaderDict") - readerCalls.Add("compress/lzw", "NewReader") - readerCalls.Add("archive/tar", "NewReader") - readerCalls.Add("archive/zip", "NewReader") - readerCalls.Add("*archive/zip.File", "Open") - - copyCalls := gosec.NewCallList() - copyCalls.Add("io", "Copy") - copyCalls.Add("io", "CopyBuffer") - - return &decompressionBombCheck{ - MetaData: issue.MetaData{ - ID: id, - Severity: issue.Medium, - Confidence: issue.Medium, - What: "Potential DoS vulnerability via decompression bomb", - }, - readerCalls: readerCalls, - copyCalls: copyCalls, - }, []ast.Node{(*ast.FuncDecl)(nil), (*ast.AssignStmt)(nil), (*ast.CallExpr)(nil)} -} diff --git a/vendor/github.com/securego/gosec/v2/rules/directory-traversal.go b/vendor/github.com/securego/gosec/v2/rules/directory-traversal.go deleted file mode 100644 index 47bcb2dc4..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/directory-traversal.go +++ /dev/null @@ -1,65 +0,0 @@ -package rules - -import ( - "go/ast" - "regexp" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/issue" -) - -type traversal struct { - pattern *regexp.Regexp - issue.MetaData -} - -func (r *traversal) ID() string { - return r.MetaData.ID -} - -func (r *traversal) Match(n ast.Node, ctx *gosec.Context) (*issue.Issue, error) { - switch node := n.(type) { - case *ast.CallExpr: - return r.matchCallExpr(node, ctx) - } - return nil, nil -} - -func (r *traversal) matchCallExpr(assign *ast.CallExpr, ctx *gosec.Context) (*issue.Issue, error) { - for _, i := range assign.Args { - if basiclit, ok1 := i.(*ast.BasicLit); ok1 { - if fun, ok2 := assign.Fun.(*ast.SelectorExpr); ok2 { - if x, ok3 := fun.X.(*ast.Ident); ok3 { - str := x.Name + "." + fun.Sel.Name + "(" + basiclit.Value + ")" - if r.pattern.MatchString(str) { - return ctx.NewIssue(assign, r.ID(), r.What, r.Severity, r.Confidence), nil - } - } - } - } - } - return nil, nil -} - -// NewDirectoryTraversal attempts to find the use of http.Dir("/") -func NewDirectoryTraversal(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { - pattern := `http\.Dir\("\/"\)|http\.Dir\('\/'\)` - if val, ok := conf[id]; ok { - conf := val.(map[string]interface{}) - if configPattern, ok := conf["pattern"]; ok { - if cfgPattern, ok := configPattern.(string); ok { - pattern = cfgPattern - } - } - } - - return &traversal{ - pattern: regexp.MustCompile(pattern), - MetaData: issue.MetaData{ - ID: id, - What: "Potential directory traversal", - Confidence: issue.Medium, - Severity: issue.Medium, - }, - }, []ast.Node{(*ast.CallExpr)(nil)} -} diff --git a/vendor/github.com/securego/gosec/v2/rules/errors.go b/vendor/github.com/securego/gosec/v2/rules/errors.go deleted file mode 100644 index d31248ccb..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/errors.go +++ /dev/null @@ -1,122 +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" - "go/types" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/issue" -) - -type noErrorCheck struct { - issue.MetaData - whitelist gosec.CallList -} - -func (r *noErrorCheck) ID() string { - return r.MetaData.ID -} - -func returnsError(callExpr *ast.CallExpr, ctx *gosec.Context) int { - if tv := ctx.Info.TypeOf(callExpr); tv != nil { - switch t := tv.(type) { - case *types.Tuple: - for pos := 0; pos < t.Len(); pos++ { - variable := t.At(pos) - if variable != nil && variable.Type().String() == "error" { - return pos - } - } - case *types.Named: - if t.String() == "error" { - return 0 - } - } - } - return -1 -} - -func (r *noErrorCheck) Match(n ast.Node, ctx *gosec.Context) (*issue.Issue, error) { - switch stmt := n.(type) { - case *ast.AssignStmt: - cfg := ctx.Config - if enabled, err := cfg.IsGlobalEnabled(gosec.Audit); err == nil && enabled { - for _, expr := range stmt.Rhs { - if callExpr, ok := expr.(*ast.CallExpr); ok && r.whitelist.ContainsCallExpr(expr, ctx) == nil { - pos := returnsError(callExpr, ctx) - if pos < 0 || pos >= len(stmt.Lhs) { - return nil, nil - } - if id, ok := stmt.Lhs[pos].(*ast.Ident); ok && id.Name == "_" { - return ctx.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil - } - } - } - } - case *ast.ExprStmt: - if callExpr, ok := stmt.X.(*ast.CallExpr); ok && r.whitelist.ContainsCallExpr(stmt.X, ctx) == nil { - pos := returnsError(callExpr, ctx) - if pos >= 0 { - return ctx.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil - } - } - } - return nil, nil -} - -// NewNoErrorCheck detects if the returned error is unchecked -func NewNoErrorCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { - // TODO(gm) Come up with sensible defaults here. Or flip it to use a - // black list instead. - whitelist := gosec.NewCallList() - whitelist.AddAll("bytes.Buffer", "Write", "WriteByte", "WriteRune", "WriteString") - whitelist.AddAll("fmt", "Print", "Printf", "Println", "Fprint", "Fprintf", "Fprintln") - whitelist.AddAll("strings.Builder", "Write", "WriteByte", "WriteRune", "WriteString") - whitelist.Add("io.PipeWriter", "CloseWithError") - whitelist.Add("hash.Hash", "Write") - whitelist.Add("os", "Unsetenv") - - if configured, ok := conf[id]; ok { - if whitelisted, ok := configured.(map[string]interface{}); ok { - for pkg, funcs := range whitelisted { - if funcs, ok := funcs.([]interface{}); ok { - whitelist.AddAll(pkg, toStringSlice(funcs)...) - } - } - } - } - - return &noErrorCheck{ - MetaData: issue.MetaData{ - ID: id, - Severity: issue.Low, - Confidence: issue.High, - What: "Errors unhandled.", - }, - whitelist: whitelist, - }, []ast.Node{(*ast.AssignStmt)(nil), (*ast.ExprStmt)(nil)} -} - -func toStringSlice(values []interface{}) []string { - result := []string{} - for _, value := range values { - if value, ok := value.(string); ok { - result = append(result, value) - } - } - return result -} diff --git a/vendor/github.com/securego/gosec/v2/rules/fileperms.go b/vendor/github.com/securego/gosec/v2/rules/fileperms.go deleted file mode 100644 index eb1fa2eee..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/fileperms.go +++ /dev/null @@ -1,176 +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 ( - "fmt" - "go/ast" - "strconv" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/issue" -) - -type filePermissions struct { - issue.MetaData - mode int64 - pkgs []string - calls []string -} - -// ID returns the ID of the rule. -func (r *filePermissions) ID() string { - return r.MetaData.ID -} - -func getConfiguredMode(conf map[string]interface{}, configKey string, defaultMode int64) int64 { - mode := defaultMode - if value, ok := conf[configKey]; ok { - switch value := value.(type) { - case int64: - mode = value - case string: - if m, e := strconv.ParseInt(value, 0, 64); e != nil { - mode = defaultMode - } else { - mode = m - } - } - } - return mode -} - -func modeIsSubset(subset int64, superset int64) bool { - return (subset | superset) == superset -} - -// Match checks if the rule is matched. -func (r *filePermissions) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { - for _, pkg := range r.pkgs { - if callexpr, matched := gosec.MatchCallByPackage(n, c, pkg, r.calls...); matched { - modeArg := callexpr.Args[len(callexpr.Args)-1] - if mode, err := gosec.GetInt(modeArg); err == nil && !modeIsSubset(mode, r.mode) || isOsPerm(modeArg) { - return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil - } - } - } - return nil, nil -} - -// isOsPerm check if the provide ast node contains a os.PermMode symbol -func isOsPerm(n ast.Node) bool { - if node, ok := n.(*ast.SelectorExpr); ok { - if identX, ok := node.X.(*ast.Ident); ok { - if identX.Name == "os" && node.Sel != nil && node.Sel.Name == "ModePerm" { - return true - } - } - } - return false -} - -// NewWritePerms creates a rule to detect file Writes with bad permissions. -func NewWritePerms(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { - mode := getConfiguredMode(conf, id, 0o600) - return &filePermissions{ - mode: mode, - pkgs: []string{"io/ioutil", "os"}, - calls: []string{"WriteFile"}, - MetaData: issue.MetaData{ - ID: id, - Severity: issue.Medium, - Confidence: issue.High, - What: fmt.Sprintf("Expect WriteFile permissions to be %#o or less", mode), - }, - }, []ast.Node{(*ast.CallExpr)(nil)} -} - -// NewFilePerms creates a rule to detect file creation with a more permissive than configured -// permission mask. -func NewFilePerms(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { - mode := getConfiguredMode(conf, id, 0o600) - return &filePermissions{ - mode: mode, - pkgs: []string{"os"}, - calls: []string{"OpenFile", "Chmod"}, - MetaData: issue.MetaData{ - ID: id, - Severity: issue.Medium, - Confidence: issue.High, - What: fmt.Sprintf("Expect file permissions to be %#o or less", mode), - }, - }, []ast.Node{(*ast.CallExpr)(nil)} -} - -// NewMkdirPerms creates a rule to detect directory creation with more permissive than -// configured permission mask. -func NewMkdirPerms(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { - mode := getConfiguredMode(conf, id, 0o750) - return &filePermissions{ - mode: mode, - pkgs: []string{"os"}, - calls: []string{"Mkdir", "MkdirAll"}, - MetaData: issue.MetaData{ - ID: id, - Severity: issue.Medium, - Confidence: issue.High, - What: fmt.Sprintf("Expect directory permissions to be %#o or less", mode), - }, - }, []ast.Node{(*ast.CallExpr)(nil)} -} - -type osCreatePermissions struct { - issue.MetaData - mode int64 - pkgs []string - calls []string -} - -const defaultOsCreateMode = 0o666 - -// ID returns the ID of the rule. -func (r *osCreatePermissions) ID() string { - return r.MetaData.ID -} - -// Match checks if the rule is matched. -func (r *osCreatePermissions) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { - for _, pkg := range r.pkgs { - if _, matched := gosec.MatchCallByPackage(n, c, pkg, r.calls...); matched { - if !modeIsSubset(defaultOsCreateMode, r.mode) { - return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil - } - } - } - return nil, nil -} - -// NewOsCreatePerms reates a rule to detect file creation with a more permissive than configured -// permission mask. -func NewOsCreatePerms(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { - mode := getConfiguredMode(conf, id, 0o666) - return &osCreatePermissions{ - mode: mode, - pkgs: []string{"os"}, - calls: []string{"Create"}, - MetaData: issue.MetaData{ - ID: id, - Severity: issue.Medium, - Confidence: issue.High, - What: fmt.Sprintf("Expect file permissions to be %#o or less but os.Create used with default permissions %#o", - mode, defaultOsCreateMode), - }, - }, []ast.Node{(*ast.CallExpr)(nil)} -} diff --git a/vendor/github.com/securego/gosec/v2/rules/hardcoded_credentials.go b/vendor/github.com/securego/gosec/v2/rules/hardcoded_credentials.go deleted file mode 100644 index c10d18b30..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/hardcoded_credentials.go +++ /dev/null @@ -1,394 +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 ( - "fmt" - "go/ast" - "go/token" - "regexp" - "strconv" - - zxcvbn "github.com/ccojocar/zxcvbn-go" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/issue" -) - -type secretPattern struct { - name string - regexp *regexp.Regexp -} - -var secretsPatterns = [...]secretPattern{ - { - name: "RSA private key", - regexp: regexp.MustCompile(`-----BEGIN RSA PRIVATE KEY-----`), - }, - { - name: "SSH (DSA) private key", - regexp: regexp.MustCompile(`-----BEGIN DSA PRIVATE KEY-----`), - }, - { - name: "SSH (EC) private key", - regexp: regexp.MustCompile(`-----BEGIN EC PRIVATE KEY-----`), - }, - { - name: "PGP private key block", - regexp: regexp.MustCompile(`-----BEGIN PGP PRIVATE KEY BLOCK-----`), - }, - { - name: "Slack Token", - regexp: regexp.MustCompile(`xox[pborsa]-[0-9]{12}-[0-9]{12}-[0-9]{12}-[a-z0-9]{32}`), - }, - { - name: "AWS API Key", - regexp: regexp.MustCompile(`AKIA[0-9A-Z]{16}`), - }, - { - name: "Amazon MWS Auth Token", - regexp: regexp.MustCompile(`amzn\.mws\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}`), - }, - { - name: "AWS AppSync GraphQL Key", - regexp: regexp.MustCompile(`da2-[a-z0-9]{26}`), - }, - { - name: "GitHub personal access token", - regexp: regexp.MustCompile(`ghp_[a-zA-Z0-9]{36}`), - }, - { - name: "GitHub fine-grained access token", - regexp: regexp.MustCompile(`github_pat_[a-zA-Z0-9]{22}_[a-zA-Z0-9]{59}`), - }, - { - name: "GitHub action temporary token", - regexp: regexp.MustCompile(`ghs_[a-zA-Z0-9]{36}`), - }, - { - name: "Google API Key", - regexp: regexp.MustCompile(`AIza[0-9A-Za-z\-_]{35}`), - }, - { - name: "Google Cloud Platform API Key", - regexp: regexp.MustCompile(`AIza[0-9A-Za-z\-_]{35}`), - }, - { - name: "Google Cloud Platform OAuth", - regexp: regexp.MustCompile(`[0-9]+-[0-9A-Za-z_]{32}\.apps\.googleusercontent\.com`), - }, - { - name: "Google Drive API Key", - regexp: regexp.MustCompile(`AIza[0-9A-Za-z\-_]{35}`), - }, - { - name: "Google Drive OAuth", - regexp: regexp.MustCompile(`[0-9]+-[0-9A-Za-z_]{32}\.apps\.googleusercontent\.com`), - }, - { - name: "Google (GCP) Service-account", - regexp: regexp.MustCompile(`"type": "service_account"`), - }, - { - name: "Google Gmail API Key", - regexp: regexp.MustCompile(`AIza[0-9A-Za-z\-_]{35}`), - }, - { - name: "Google Gmail OAuth", - regexp: regexp.MustCompile(`[0-9]+-[0-9A-Za-z_]{32}\.apps\.googleusercontent\.com`), - }, - { - name: "Google OAuth Access Token", - regexp: regexp.MustCompile(`ya29\.[0-9A-Za-z\-_]+`), - }, - { - name: "Google YouTube API Key", - regexp: regexp.MustCompile(`AIza[0-9A-Za-z\-_]{35}`), - }, - { - name: "Google YouTube OAuth", - regexp: regexp.MustCompile(`[0-9]+-[0-9A-Za-z_]{32}\.apps\.googleusercontent\.com`), - }, - { - name: "Generic API Key", - regexp: regexp.MustCompile(`[aA][pP][iI]_?[kK][eE][yY].*[''|"][0-9a-zA-Z]{32,45}[''|"]`), - }, - { - name: "Generic Secret", - regexp: regexp.MustCompile(`[sS][eE][cC][rR][eE][tT].*[''|"][0-9a-zA-Z]{32,45}[''|"]`), - }, - { - name: "Heroku API Key", - regexp: regexp.MustCompile(`[hH][eE][rR][oO][kK][uU].*[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}`), - }, - { - name: "MailChimp API Key", - regexp: regexp.MustCompile(`[0-9a-f]{32}-us[0-9]{1,2}`), - }, - { - name: "Mailgun API Key", - regexp: regexp.MustCompile(`key-[0-9a-zA-Z]{32}`), - }, - { - name: "Password in URL", - regexp: regexp.MustCompile(`[a-zA-Z]{3,10}://[^/\\s:@]{3,20}:[^/\\s:@]{3,20}@.{1,100}["'\\s]`), - }, - { - name: "Slack Webhook", - regexp: regexp.MustCompile(`https://hooks\.slack\.com/services/T[a-zA-Z0-9_]{8}/B[a-zA-Z0-9_]{8}/[a-zA-Z0-9_]{24}`), - }, - { - name: "Stripe API Key", - regexp: regexp.MustCompile(`sk_live_[0-9a-zA-Z]{24}`), - }, - { - name: "Stripe Restricted API Key", - regexp: regexp.MustCompile(`rk_live_[0-9a-zA-Z]{24}`), - }, - { - name: "Square Access Token", - regexp: regexp.MustCompile(`sq0atp-[0-9A-Za-z\-_]{22}`), - }, - { - name: "Square OAuth Secret", - regexp: regexp.MustCompile(`sq0csp-[0-9A-Za-z\-_]{43}`), - }, - { - name: "Telegram Bot API Key", - regexp: regexp.MustCompile(`[0-9]+:AA[0-9A-Za-z\-_]{33}`), - }, - { - name: "Twilio API Key", - regexp: regexp.MustCompile(`SK[0-9a-fA-F]{32}`), - }, - { - name: "Twitter Access Token", - regexp: regexp.MustCompile(`[tT][wW][iI][tT][tT][eE][rR].*[1-9][0-9]+-[0-9a-zA-Z]{40}`), - }, - { - name: "Twitter OAuth", - regexp: regexp.MustCompile(`[tT][wW][iI][tT][tT][eE][rR].*[''|"][0-9a-zA-Z]{35,44}[''|"]`), - }, -} - -type credentials struct { - issue.MetaData - pattern *regexp.Regexp - entropyThreshold float64 - perCharThreshold float64 - truncate int - ignoreEntropy bool -} - -func (r *credentials) ID() string { - return r.MetaData.ID -} - -func truncate(s string, n int) string { - if n > len(s) { - return s - } - return s[:n] -} - -func (r *credentials) isHighEntropyString(str string) bool { - s := truncate(str, r.truncate) - info := zxcvbn.PasswordStrength(s, []string{}) - entropyPerChar := info.Entropy / float64(len(s)) - return (info.Entropy >= r.entropyThreshold || - (info.Entropy >= (r.entropyThreshold/2) && - entropyPerChar >= r.perCharThreshold)) -} - -func (r *credentials) isSecretPattern(str string) (bool, string) { - for _, pattern := range secretsPatterns { - if pattern.regexp.MatchString(str) { - return true, pattern.name - } - } - return false, "" -} - -func (r *credentials) Match(n ast.Node, ctx *gosec.Context) (*issue.Issue, error) { - switch node := n.(type) { - case *ast.AssignStmt: - return r.matchAssign(node, ctx) - case *ast.ValueSpec: - return r.matchValueSpec(node, ctx) - case *ast.BinaryExpr: - return r.matchEqualityCheck(node, ctx) - } - return nil, nil -} - -func (r *credentials) matchAssign(assign *ast.AssignStmt, ctx *gosec.Context) (*issue.Issue, error) { - for _, i := range assign.Lhs { - if ident, ok := i.(*ast.Ident); ok { - // First check LHS to find anything being assigned to variables whose name appears to be a cred - if r.pattern.MatchString(ident.Name) { - for _, e := range assign.Rhs { - if val, err := gosec.GetString(e); err == nil { - if r.ignoreEntropy || (!r.ignoreEntropy && r.isHighEntropyString(val)) { - return ctx.NewIssue(assign, r.ID(), r.What, r.Severity, r.Confidence), nil - } - } - } - } - - // Now that no names were matched, match the RHS to see if the actual values being assigned are creds - for _, e := range assign.Rhs { - val, err := gosec.GetString(e) - if err != nil { - continue - } - - if r.ignoreEntropy || r.isHighEntropyString(val) { - if ok, patternName := r.isSecretPattern(val); ok { - return ctx.NewIssue(assign, r.ID(), fmt.Sprintf("%s: %s", r.What, patternName), r.Severity, r.Confidence), nil - } - } - } - } - } - return nil, nil -} - -func (r *credentials) matchValueSpec(valueSpec *ast.ValueSpec, ctx *gosec.Context) (*issue.Issue, error) { - // Running match against the variable name(s) first. Will catch any creds whose var name matches the pattern, - // then will go back over to check the values themselves. - for index, ident := range valueSpec.Names { - if r.pattern.MatchString(ident.Name) && valueSpec.Values != nil { - // const foo, bar = "same value" - if len(valueSpec.Values) <= index { - index = len(valueSpec.Values) - 1 - } - if val, err := gosec.GetString(valueSpec.Values[index]); err == nil { - if r.ignoreEntropy || (!r.ignoreEntropy && r.isHighEntropyString(val)) { - return ctx.NewIssue(valueSpec, r.ID(), r.What, r.Severity, r.Confidence), nil - } - } - } - } - - // Now that no variable names have been matched, match the actual values to find any creds - for _, ident := range valueSpec.Values { - if val, err := gosec.GetString(ident); err == nil { - if r.ignoreEntropy || r.isHighEntropyString(val) { - if ok, patternName := r.isSecretPattern(val); ok { - return ctx.NewIssue(valueSpec, r.ID(), fmt.Sprintf("%s: %s", r.What, patternName), r.Severity, r.Confidence), nil - } - } - } - } - - return nil, nil -} - -func (r *credentials) matchEqualityCheck(binaryExpr *ast.BinaryExpr, ctx *gosec.Context) (*issue.Issue, error) { - if binaryExpr.Op == token.EQL || binaryExpr.Op == token.NEQ { - ident, ok := binaryExpr.X.(*ast.Ident) - if !ok { - ident, _ = binaryExpr.Y.(*ast.Ident) - } - - if ident != nil && r.pattern.MatchString(ident.Name) { - valueNode := binaryExpr.Y - if !ok { - valueNode = binaryExpr.X - } - if val, err := gosec.GetString(valueNode); err == nil { - if r.ignoreEntropy || (!r.ignoreEntropy && r.isHighEntropyString(val)) { - return ctx.NewIssue(binaryExpr, r.ID(), r.What, r.Severity, r.Confidence), nil - } - } - } - - // Now that the variable names have been checked, and no matches were found, make sure that - // either the left or right operands is a string literal so we can match the value. - identStrConst, ok := binaryExpr.X.(*ast.BasicLit) - if !ok { - identStrConst, ok = binaryExpr.Y.(*ast.BasicLit) - } - - if ok && identStrConst.Kind == token.STRING { - s, _ := gosec.GetString(identStrConst) - if r.ignoreEntropy || r.isHighEntropyString(s) { - if ok, patternName := r.isSecretPattern(s); ok { - return ctx.NewIssue(binaryExpr, r.ID(), fmt.Sprintf("%s: %s", r.What, patternName), r.Severity, r.Confidence), nil - } - } - } - } - return nil, nil -} - -// NewHardcodedCredentials attempts to find high entropy string constants being -// assigned to variables that appear to be related to credentials. -func NewHardcodedCredentials(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { - pattern := `(?i)passwd|pass|password|pwd|secret|token|pw|apiKey|bearer|cred` - entropyThreshold := 80.0 - perCharThreshold := 3.0 - ignoreEntropy := false - truncateString := 16 - if val, ok := conf[id]; ok { - conf := val.(map[string]interface{}) - if configPattern, ok := conf["pattern"]; ok { - if cfgPattern, ok := configPattern.(string); ok { - pattern = cfgPattern - } - } - - if configIgnoreEntropy, ok := conf["ignore_entropy"]; ok { - if cfgIgnoreEntropy, ok := configIgnoreEntropy.(bool); ok { - ignoreEntropy = cfgIgnoreEntropy - } - } - if configEntropyThreshold, ok := conf["entropy_threshold"]; ok { - if cfgEntropyThreshold, ok := configEntropyThreshold.(string); ok { - if parsedNum, err := strconv.ParseFloat(cfgEntropyThreshold, 64); err == nil { - entropyThreshold = parsedNum - } - } - } - if configCharThreshold, ok := conf["per_char_threshold"]; ok { - if cfgCharThreshold, ok := configCharThreshold.(string); ok { - if parsedNum, err := strconv.ParseFloat(cfgCharThreshold, 64); err == nil { - perCharThreshold = parsedNum - } - } - } - if configTruncate, ok := conf["truncate"]; ok { - if cfgTruncate, ok := configTruncate.(string); ok { - if parsedInt, err := strconv.Atoi(cfgTruncate); err == nil { - truncateString = parsedInt - } - } - } - } - - return &credentials{ - pattern: regexp.MustCompile(pattern), - entropyThreshold: entropyThreshold, - perCharThreshold: perCharThreshold, - ignoreEntropy: ignoreEntropy, - truncate: truncateString, - MetaData: issue.MetaData{ - ID: id, - What: "Potential hardcoded credentials", - Confidence: issue.Low, - Severity: issue.High, - }, - }, []ast.Node{(*ast.AssignStmt)(nil), (*ast.ValueSpec)(nil), (*ast.BinaryExpr)(nil)} -} diff --git a/vendor/github.com/securego/gosec/v2/rules/http_serve.go b/vendor/github.com/securego/gosec/v2/rules/http_serve.go deleted file mode 100644 index 525ed4ebc..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/http_serve.go +++ /dev/null @@ -1,39 +0,0 @@ -package rules - -import ( - "go/ast" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/issue" -) - -type httpServeWithoutTimeouts struct { - issue.MetaData - pkg string - calls []string -} - -func (r *httpServeWithoutTimeouts) ID() string { - return r.MetaData.ID -} - -func (r *httpServeWithoutTimeouts) Match(n ast.Node, c *gosec.Context) (gi *issue.Issue, err error) { - if _, matches := gosec.MatchCallByPackage(n, c, r.pkg, r.calls...); matches { - return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil - } - return nil, nil -} - -// NewHTTPServeWithoutTimeouts detects use of net/http serve functions that have no support for setting timeouts. -func NewHTTPServeWithoutTimeouts(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { - return &httpServeWithoutTimeouts{ - pkg: "net/http", - calls: []string{"ListenAndServe", "ListenAndServeTLS", "Serve", "ServeTLS"}, - MetaData: issue.MetaData{ - ID: id, - What: "Use of net/http serve function that has no support for setting timeouts", - Severity: issue.Medium, - Confidence: issue.High, - }, - }, []ast.Node{(*ast.CallExpr)(nil)} -} diff --git a/vendor/github.com/securego/gosec/v2/rules/implicit_aliasing.go b/vendor/github.com/securego/gosec/v2/rules/implicit_aliasing.go deleted file mode 100644 index 75de4ed8c..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/implicit_aliasing.go +++ /dev/null @@ -1,148 +0,0 @@ -package rules - -import ( - "go/ast" - "go/token" - "go/types" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/issue" -) - -type implicitAliasing struct { - issue.MetaData - aliases map[*ast.Object]struct{} - rightBrace token.Pos - acceptableAlias []*ast.UnaryExpr -} - -func (r *implicitAliasing) ID() string { - return r.MetaData.ID -} - -func containsUnary(exprs []*ast.UnaryExpr, expr *ast.UnaryExpr) bool { - for _, e := range exprs { - if e == expr { - return true - } - } - return false -} - -func getIdentExpr(expr ast.Expr) (*ast.Ident, bool) { - return doGetIdentExpr(expr, false) -} - -func doGetIdentExpr(expr ast.Expr, hasSelector bool) (*ast.Ident, bool) { - switch node := expr.(type) { - case *ast.Ident: - return node, hasSelector - case *ast.SelectorExpr: - return doGetIdentExpr(node.X, true) - case *ast.UnaryExpr: - return doGetIdentExpr(node.X, hasSelector) - default: - return nil, false - } -} - -func (r *implicitAliasing) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { - // This rule does not apply for Go 1.22, see https://tip.golang.org/doc/go1.22#language. - major, minor, _ := gosec.GoVersion() - if major >= 1 && minor >= 22 { - return nil, nil - } - - switch node := n.(type) { - case *ast.RangeStmt: - // 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 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 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 - // scope - if node.Pos() > r.rightBrace { - r.aliases = make(map[*ast.Object]struct{}) - r.acceptableAlias = make([]*ast.UnaryExpr, 0) - } - - // Short circuit logic to skip checking aliases if we have nothing to check against. - if len(r.aliases) == 0 { - return nil, nil - } - - // If this unary is at the top level of a return statement then it is okay-- - // see *ast.ReturnStmt comment below. - if containsUnary(r.acceptableAlias, node) { - return nil, nil - } - - // If we find a unary op of & (reference) of an object within r.aliases, complain. - if identExpr, hasSelector := getIdentExpr(node); identExpr != nil && node.Op.String() == "&" { - if _, contains := r.aliases[identExpr.Obj]; contains { - _, isPointer := c.Info.TypeOf(identExpr).(*types.Pointer) - - if !hasSelector || !isPointer { - return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil - } - } - } - case *ast.ReturnStmt: - // Returning a rangeStmt yielded value is acceptable since only one value will be returned - for _, item := range node.Results { - if unary, ok := item.(*ast.UnaryExpr); ok && unary.Op.String() == "&" { - r.acceptableAlias = append(r.acceptableAlias, unary) - } - } - } - - return nil, nil -} - -// NewImplicitAliasing detects implicit memory aliasing of type: for blah := SomeCall() {... SomeOtherCall(&blah) ...} -func NewImplicitAliasing(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { - return &implicitAliasing{ - aliases: make(map[*ast.Object]struct{}), - rightBrace: token.NoPos, - acceptableAlias: make([]*ast.UnaryExpr, 0), - MetaData: issue.MetaData{ - ID: id, - Severity: issue.Medium, - Confidence: issue.Medium, - What: "Implicit memory aliasing in for loop.", - }, - }, []ast.Node{(*ast.RangeStmt)(nil), (*ast.UnaryExpr)(nil), (*ast.ReturnStmt)(nil)} -} - -/* -This rule is prone to flag false positives. - -Within GoSec, the rule is just an AST match-- there are a handful of other -implementation strategies which might lend more nuance to the rule at the -cost of allowing false negatives. - -From a tooling side, I'd rather have this rule flag false positives than -potentially have some false negatives-- especially if the sentiment of this -rule (as I understand it, and Go) is that referencing a rangeStmt-yielded -value is kinda strange and does not have a strongly justified use case. - -Which is to say-- a false positive _should_ just be changed. -*/ diff --git a/vendor/github.com/securego/gosec/v2/rules/integer_overflow.go b/vendor/github.com/securego/gosec/v2/rules/integer_overflow.go deleted file mode 100644 index 1d5790664..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/integer_overflow.go +++ /dev/null @@ -1,90 +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 ( - "fmt" - "go/ast" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/issue" -) - -type integerOverflowCheck struct { - issue.MetaData - calls gosec.CallList -} - -func (i *integerOverflowCheck) ID() string { - return i.MetaData.ID -} - -func (i *integerOverflowCheck) Match(node ast.Node, ctx *gosec.Context) (*issue.Issue, error) { - var atoiVarObj map[*ast.Object]ast.Node - - // To check multiple lines, ctx.PassedValues is used to store temporary data. - if _, ok := ctx.PassedValues[i.ID()]; !ok { - atoiVarObj = make(map[*ast.Object]ast.Node) - ctx.PassedValues[i.ID()] = atoiVarObj - } else if pv, ok := ctx.PassedValues[i.ID()].(map[*ast.Object]ast.Node); ok { - atoiVarObj = pv - } else { - return nil, fmt.Errorf("PassedValues[%s] of Context is not map[*ast.Object]ast.Node, but %T", i.ID(), ctx.PassedValues[i.ID()]) - } - - // strconv.Atoi is a common function. - // To reduce false positives, This rule detects code which is converted to int32/int16 only. - switch n := node.(type) { - case *ast.AssignStmt: - for _, expr := range n.Rhs { - if callExpr, ok := expr.(*ast.CallExpr); ok && i.calls.ContainsPkgCallExpr(callExpr, ctx, false) != nil { - if idt, ok := n.Lhs[0].(*ast.Ident); ok && idt.Name != "_" { - // Example: - // v, _ := strconv.Atoi("1111") - // Add v's Obj to atoiVarObj map - atoiVarObj[idt.Obj] = n - } - } - } - case *ast.CallExpr: - if fun, ok := n.Fun.(*ast.Ident); ok { - if fun.Name == "int32" || fun.Name == "int16" { - if idt, ok := n.Args[0].(*ast.Ident); ok { - if _, ok := atoiVarObj[idt.Obj]; ok { - // Detect int32(v) and int16(v) - return ctx.NewIssue(n, i.ID(), i.What, i.Severity, i.Confidence), nil - } - } - } - } - } - - return nil, nil -} - -// NewIntegerOverflowCheck detects if there is potential Integer OverFlow -func NewIntegerOverflowCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { - calls := gosec.NewCallList() - calls.Add("strconv", "Atoi") - return &integerOverflowCheck{ - MetaData: issue.MetaData{ - ID: id, - Severity: issue.High, - Confidence: issue.Medium, - What: "Potential Integer overflow made by strconv.Atoi result conversion to int16/32", - }, - calls: calls, - }, []ast.Node{(*ast.FuncDecl)(nil), (*ast.AssignStmt)(nil), (*ast.CallExpr)(nil)} -} diff --git a/vendor/github.com/securego/gosec/v2/rules/math_big_rat.go b/vendor/github.com/securego/gosec/v2/rules/math_big_rat.go deleted file mode 100644 index 1aac1fa20..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/math_big_rat.go +++ /dev/null @@ -1,45 +0,0 @@ -package rules - -import ( - "go/ast" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/issue" -) - -type usingOldMathBig struct { - issue.MetaData - calls gosec.CallList -} - -func (r *usingOldMathBig) ID() string { - return r.MetaData.ID -} - -func (r *usingOldMathBig) Match(node ast.Node, ctx *gosec.Context) (gi *issue.Issue, err error) { - if callExpr := r.calls.ContainsPkgCallExpr(node, ctx, false); callExpr == nil { - return nil, nil - } - - confidence := issue.Low - major, minor, build := gosec.GoVersion() - if major == 1 && (minor == 16 && build < 14 || minor == 17 && build < 7) { - confidence = issue.Medium - } - - return ctx.NewIssue(node, r.ID(), r.What, r.Severity, confidence), nil -} - -// NewUsingOldMathBig rule detects the use of Rat.SetString from math/big. -func NewUsingOldMathBig(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { - calls := gosec.NewCallList() - calls.Add("math/big.Rat", "SetString") - return &usingOldMathBig{ - calls: calls, - MetaData: issue.MetaData{ - ID: id, - What: "Potential uncontrolled memory consumption in Rat.SetString (CVE-2022-23772)", - Severity: issue.High, - }, - }, []ast.Node{(*ast.CallExpr)(nil)} -} diff --git a/vendor/github.com/securego/gosec/v2/rules/pprof.go b/vendor/github.com/securego/gosec/v2/rules/pprof.go deleted file mode 100644 index 68498dd5e..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/pprof.go +++ /dev/null @@ -1,43 +0,0 @@ -package rules - -import ( - "go/ast" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/issue" -) - -type pprofCheck struct { - issue.MetaData - importPath string - importName string -} - -// ID returns the ID of the check -func (p *pprofCheck) ID() string { - return p.MetaData.ID -} - -// Match checks for pprof imports -func (p *pprofCheck) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { - if node, ok := n.(*ast.ImportSpec); ok { - if p.importPath == unquote(node.Path.Value) && node.Name != nil && p.importName == node.Name.Name { - return c.NewIssue(node, p.ID(), p.What, p.Severity, p.Confidence), nil - } - } - return nil, nil -} - -// NewPprofCheck detects when the profiling endpoint is automatically exposed -func NewPprofCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { - return &pprofCheck{ - MetaData: issue.MetaData{ - ID: id, - Severity: issue.High, - Confidence: issue.High, - What: "Profiling endpoint is automatically exposed on /debug/pprof", - }, - importPath: "net/http/pprof", - importName: "_", - }, []ast.Node{(*ast.ImportSpec)(nil)} -} diff --git a/vendor/github.com/securego/gosec/v2/rules/rand.go b/vendor/github.com/securego/gosec/v2/rules/rand.go deleted file mode 100644 index fe34ca9c3..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/rand.go +++ /dev/null @@ -1,63 +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" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/issue" -) - -type weakRand struct { - issue.MetaData - blocklist map[string][]string -} - -func (w *weakRand) ID() string { - return w.MetaData.ID -} - -func (w *weakRand) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { - for pkg, funcs := range w.blocklist { - if _, matched := gosec.MatchCallByPackage(n, c, pkg, funcs...); matched { - return c.NewIssue(n, w.ID(), w.What, w.Severity, w.Confidence), nil - } - } - - return nil, nil -} - -// NewWeakRandCheck detects the use of random number generator that isn't cryptographically secure -func NewWeakRandCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { - calls := make(map[string][]string) - calls["math/rand"] = []string{ - "New", "Read", "Float32", "Float64", "Int", "Int31", "Int31n", - "Int63", "Int63n", "Intn", "NormFloat64", "Uint32", "Uint64", - } - calls["math/rand/v2"] = []string{ - "New", "Float32", "Float64", "Int", "Int32", "Int32N", - "Int64", "Int64N", "IntN", "N", "NormFloat64", "Uint32", "Uint32N", "Uint64", "Uint64N", "UintN", - } - return &weakRand{ - blocklist: calls, - MetaData: issue.MetaData{ - ID: id, - Severity: issue.High, - Confidence: issue.Medium, - What: "Use of weak random number generator (math/rand or math/rand/v2 instead of crypto/rand)", - }, - }, []ast.Node{(*ast.CallExpr)(nil)} -} diff --git a/vendor/github.com/securego/gosec/v2/rules/readfile.go b/vendor/github.com/securego/gosec/v2/rules/readfile.go deleted file mode 100644 index da6b9c965..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/readfile.go +++ /dev/null @@ -1,153 +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" - "go/types" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/issue" -) - -type readfile struct { - issue.MetaData - gosec.CallList - pathJoin gosec.CallList - clean gosec.CallList - cleanedVar map[any]ast.Node -} - -// ID returns the identifier for this rule -func (r *readfile) ID() string { - return r.MetaData.ID -} - -// isJoinFunc checks if there is a filepath.Join or other join function -func (r *readfile) isJoinFunc(n ast.Node, c *gosec.Context) bool { - if call := r.pathJoin.ContainsPkgCallExpr(n, c, false); call != nil { - for _, arg := range call.Args { - // edge case: check if one of the args is a BinaryExpr - if binExp, ok := arg.(*ast.BinaryExpr); ok { - // iterate and resolve all found identities from the BinaryExpr - if _, ok := gosec.FindVarIdentities(binExp, c); ok { - return true - } - } - - // try and resolve identity - if ident, ok := arg.(*ast.Ident); ok { - obj := c.Info.ObjectOf(ident) - if _, ok := obj.(*types.Var); ok && !gosec.TryResolve(ident, c) { - return true - } - } - } - } - return false -} - -// isFilepathClean checks if there is a filepath.Clean for given variable -func (r *readfile) isFilepathClean(n *ast.Ident, c *gosec.Context) bool { - if _, ok := r.cleanedVar[n.Obj.Decl]; ok { - return true - } - if n.Obj.Kind != ast.Var { - return false - } - if node, ok := n.Obj.Decl.(*ast.AssignStmt); ok { - if call, ok := node.Rhs[0].(*ast.CallExpr); ok { - if clean := r.clean.ContainsPkgCallExpr(call, c, false); clean != nil { - return true - } - } - } - return false -} - -// trackFilepathClean tracks back the declaration of variable from filepath.Clean argument -func (r *readfile) trackFilepathClean(n ast.Node) { - if clean, ok := n.(*ast.CallExpr); ok && len(clean.Args) > 0 { - if ident, ok := clean.Args[0].(*ast.Ident); ok { - // ident.Obj may be nil if the referenced declaration is in another file. It also may be incorrect. - // if it is nil, do not follow it. - if ident.Obj != nil { - r.cleanedVar[ident.Obj.Decl] = n - } - } - } -} - -// Match inspects AST nodes to determine if the match the methods `os.Open` or `ioutil.ReadFile` -func (r *readfile) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { - if node := r.clean.ContainsPkgCallExpr(n, c, false); node != nil { - r.trackFilepathClean(n) - return nil, nil - } else if node := r.ContainsPkgCallExpr(n, c, false); node != nil { - for _, arg := range node.Args { - // handles path joining functions in Arg - // eg. os.Open(filepath.Join("/tmp/", file)) - if callExpr, ok := arg.(*ast.CallExpr); ok { - if r.isJoinFunc(callExpr, c) { - return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil - } - } - // handles binary string concatenation eg. ioutil.Readfile("/tmp/" + file + "/blob") - if binExp, ok := arg.(*ast.BinaryExpr); ok { - // resolve all found identities from the BinaryExpr - if _, ok := gosec.FindVarIdentities(binExp, c); ok { - return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil - } - } - - if ident, ok := arg.(*ast.Ident); ok { - obj := c.Info.ObjectOf(ident) - if _, ok := obj.(*types.Var); ok && - !gosec.TryResolve(ident, c) && - !r.isFilepathClean(ident, c) { - return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil - } - } - } - } - return nil, nil -} - -// NewReadFile detects cases where we read files -func NewReadFile(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { - rule := &readfile{ - pathJoin: gosec.NewCallList(), - clean: gosec.NewCallList(), - CallList: gosec.NewCallList(), - MetaData: issue.MetaData{ - ID: id, - What: "Potential file inclusion via variable", - Severity: issue.Medium, - Confidence: issue.High, - }, - cleanedVar: map[any]ast.Node{}, - } - rule.pathJoin.Add("path/filepath", "Join") - rule.pathJoin.Add("path", "Join") - rule.clean.Add("path/filepath", "Clean") - rule.clean.Add("path/filepath", "Rel") - rule.clean.Add("path/filepath", "EvalSymlinks") - rule.Add("io/ioutil", "ReadFile") - rule.Add("os", "ReadFile") - rule.Add("os", "Open") - rule.Add("os", "OpenFile") - rule.Add("os", "Create") - return rule, []ast.Node{(*ast.CallExpr)(nil)} -} diff --git a/vendor/github.com/securego/gosec/v2/rules/rsa.go b/vendor/github.com/securego/gosec/v2/rules/rsa.go deleted file mode 100644 index 331e7fc80..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/rsa.go +++ /dev/null @@ -1,59 +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 ( - "fmt" - "go/ast" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/issue" -) - -type weakKeyStrength struct { - issue.MetaData - calls gosec.CallList - bits int -} - -func (w *weakKeyStrength) ID() string { - return w.MetaData.ID -} - -func (w *weakKeyStrength) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { - if callExpr := w.calls.ContainsPkgCallExpr(n, c, false); callExpr != nil { - if bits, err := gosec.GetInt(callExpr.Args[1]); err == nil && bits < (int64)(w.bits) { - return c.NewIssue(n, w.ID(), w.What, w.Severity, w.Confidence), nil - } - } - return nil, nil -} - -// NewWeakKeyStrength builds a rule that detects RSA keys < 2048 bits -func NewWeakKeyStrength(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { - calls := gosec.NewCallList() - calls.Add("crypto/rsa", "GenerateKey") - bits := 2048 - return &weakKeyStrength{ - calls: calls, - bits: bits, - MetaData: issue.MetaData{ - ID: id, - Severity: issue.Medium, - Confidence: issue.High, - What: fmt.Sprintf("RSA keys should be at least %d bits", bits), - }, - }, []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 deleted file mode 100644 index 13f29f71a..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/rulelist.go +++ /dev/null @@ -1,134 +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 "github.com/securego/gosec/v2" - -// RuleDefinition contains the description of a rule and a mechanism to -// create it. -type RuleDefinition struct { - ID string - Description string - Create gosec.RuleBuilder -} - -// RuleList contains a mapping of rule ID's to rule definitions and a mapping -// of rule ID's to whether rules are suppressed. -type RuleList struct { - Rules map[string]RuleDefinition - RuleSuppressed map[string]bool -} - -// RulesInfo returns all the create methods and the rule suppressed map for a -// given list -func (rl RuleList) RulesInfo() (map[string]gosec.RuleBuilder, map[string]bool) { - builders := make(map[string]gosec.RuleBuilder) - for _, def := range rl.Rules { - builders[def.ID] = def.Create - } - return builders, rl.RuleSuppressed -} - -// RuleFilter can be used to include or exclude a rule depending on the return -// value of the function -type RuleFilter func(string) bool - -// NewRuleFilter is a closure that will include/exclude the rule ID's based on -// the supplied boolean value. -func NewRuleFilter(action bool, ruleIDs ...string) RuleFilter { - rulelist := make(map[string]bool) - for _, rule := range ruleIDs { - rulelist[rule] = true - } - return func(rule string) bool { - if _, found := rulelist[rule]; found { - return action - } - return !action - } -} - -// Generate the list of rules to use -func Generate(trackSuppressions bool, filters ...RuleFilter) RuleList { - rules := []RuleDefinition{ - // misc - {"G101", "Look for hardcoded credentials", NewHardcodedCredentials}, - {"G102", "Bind to all interfaces", NewBindsToAllNetworkInterfaces}, - {"G103", "Audit the use of unsafe block", NewUsingUnsafe}, - {"G104", "Audit errors not checked", NewNoErrorCheck}, - {"G106", "Audit the use of ssh.InsecureIgnoreHostKey function", NewSSHHostKey}, - {"G107", "Url provided to HTTP request as taint input", NewSSRFCheck}, - {"G108", "Profiling endpoint is automatically exposed", NewPprofCheck}, - {"G109", "Converting strconv.Atoi result to int32/int16", NewIntegerOverflowCheck}, - {"G110", "Detect io.Copy instead of io.CopyN when decompression", NewDecompressionBombCheck}, - {"G111", "Detect http.Dir('/') as a potential risk", NewDirectoryTraversal}, - {"G112", "Detect ReadHeaderTimeout not configured as a potential risk", NewSlowloris}, - {"G113", "Usage of Rat.SetString in math/big with an overflow", NewUsingOldMathBig}, - {"G114", "Use of net/http serve function that has no support for setting timeouts", NewHTTPServeWithoutTimeouts}, - - // injection - {"G201", "SQL query construction using format string", NewSQLStrFormat}, - {"G202", "SQL query construction using string concatenation", NewSQLStrConcat}, - {"G203", "Use of unescaped data in HTML templates", NewTemplateCheck}, - {"G204", "Audit use of command execution", NewSubproc}, - - // filesystem - {"G301", "Poor file permissions used when creating a directory", NewMkdirPerms}, - {"G302", "Poor file permissions used when creation file or using chmod", NewFilePerms}, - {"G303", "Creating tempfile using a predictable path", NewBadTempFile}, - {"G304", "File path provided as taint input", NewReadFile}, - {"G305", "File path traversal when extracting zip archive", NewArchive}, - {"G306", "Poor file permissions used when writing to a file", NewWritePerms}, - {"G307", "Poor file permissions used when creating a file with os.Create", NewOsCreatePerms}, - - // crypto - {"G401", "Detect the usage of MD5 or SHA1", NewUsesWeakCryptographyHash}, - {"G402", "Look for bad TLS connection settings", NewIntermediateTLSCheck}, - {"G403", "Ensure minimum RSA key length of 2048 bits", NewWeakKeyStrength}, - {"G404", "Insecure random number source (rand)", NewWeakRandCheck}, - {"G405", "Detect the usage of DES or RC4", NewUsesWeakCryptographyEncryption}, - {"G406", "Detect the usage of deprecated MD4 or RIPEMD160", NewUsesWeakDeprecatedCryptographyHash}, - - // 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}, - {"G506", "Import blocklist: golang.org/x/crypto/md4", NewBlocklistedImportMD4}, - {"G507", "Import blocklist: golang.org/x/crypto/ripemd160", NewBlocklistedImportRIPEMD160}, - - // memory safety - {"G601", "Implicit memory aliasing in RangeStmt", NewImplicitAliasing}, - } - - ruleMap := make(map[string]RuleDefinition) - ruleSuppressedMap := make(map[string]bool) - -RULES: - for _, rule := range rules { - ruleSuppressedMap[rule.ID] = false - for _, filter := range filters { - if filter(rule.ID) { - ruleSuppressedMap[rule.ID] = true - if !trackSuppressions { - continue RULES - } - } - } - ruleMap[rule.ID] = rule - } - return RuleList{ruleMap, ruleSuppressedMap} -} diff --git a/vendor/github.com/securego/gosec/v2/rules/slowloris.go b/vendor/github.com/securego/gosec/v2/rules/slowloris.go deleted file mode 100644 index 70db73f5f..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/slowloris.go +++ /dev/null @@ -1,71 +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" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/issue" -) - -type slowloris struct { - issue.MetaData -} - -func (r *slowloris) ID() string { - return r.MetaData.ID -} - -func containsReadHeaderTimeout(node *ast.CompositeLit) bool { - if node == nil { - return false - } - for _, elt := range node.Elts { - if kv, ok := elt.(*ast.KeyValueExpr); ok { - if ident, ok := kv.Key.(*ast.Ident); ok { - if ident.Name == "ReadHeaderTimeout" || ident.Name == "ReadTimeout" { - return true - } - } - } - } - return false -} - -func (r *slowloris) Match(n ast.Node, ctx *gosec.Context) (*issue.Issue, error) { - switch node := n.(type) { - case *ast.CompositeLit: - actualType := ctx.Info.TypeOf(node.Type) - if actualType != nil && actualType.String() == "net/http.Server" { - if !containsReadHeaderTimeout(node) { - return ctx.NewIssue(node, r.ID(), r.What, r.Severity, r.Confidence), nil - } - } - } - return nil, nil -} - -// NewSlowloris attempts to find the http.Server struct and check if the ReadHeaderTimeout is configured. -func NewSlowloris(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { - return &slowloris{ - MetaData: issue.MetaData{ - ID: id, - What: "Potential Slowloris Attack because ReadHeaderTimeout is not configured in the http.Server", - Confidence: issue.Low, - Severity: issue.Medium, - }, - }, []ast.Node{(*ast.CompositeLit)(nil)} -} diff --git a/vendor/github.com/securego/gosec/v2/rules/sql.go b/vendor/github.com/securego/gosec/v2/rules/sql.go deleted file mode 100644 index 61222bfdb..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/sql.go +++ /dev/null @@ -1,405 +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 ( - "fmt" - "go/ast" - "regexp" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/issue" -) - -type sqlStatement struct { - issue.MetaData - gosec.CallList - - // Contains a list of patterns which must all match for the rule to match. - patterns []*regexp.Regexp -} - -var sqlCallIdents = map[string]map[string]int{ - "*database/sql.DB": { - "Exec": 0, - "ExecContext": 1, - "Query": 0, - "QueryContext": 1, - "QueryRow": 0, - "QueryRowContext": 1, - "Prepare": 0, - "PrepareContext": 1, - }, - "*database/sql.Tx": { - "Exec": 0, - "ExecContext": 1, - "Query": 0, - "QueryContext": 1, - "QueryRow": 0, - "QueryRowContext": 1, - "Prepare": 0, - "PrepareContext": 1, - }, -} - -// findQueryArg locates the argument taking raw SQL -func findQueryArg(call *ast.CallExpr, ctx *gosec.Context) (ast.Expr, error) { - typeName, fnName, err := gosec.GetCallInfo(call, ctx) - if err != nil { - return nil, err - } - i := -1 - if ni, ok := sqlCallIdents[typeName]; ok { - if i, ok = ni[fnName]; !ok { - i = -1 - } - } - if i == -1 { - return nil, fmt.Errorf("SQL argument index not found for %s.%s", typeName, fnName) - } - if i >= len(call.Args) { - return nil, nil - } - query := call.Args[i] - return query, nil -} - -func (s *sqlStatement) ID() string { - return s.MetaData.ID -} - -// See if the string matches the patterns for the statement. -func (s *sqlStatement) MatchPatterns(str string) bool { - for _, pattern := range s.patterns { - if !pattern.MatchString(str) { - return false - } - } - return true -} - -type sqlStrConcat struct { - sqlStatement -} - -func (s *sqlStrConcat) ID() string { - return s.MetaData.ID -} - -// findInjectionInBranch walks diwb a set if expressions, and will create new issues if it finds SQL injections -// This method assumes you've already verified that the branch contains SQL syntax -func (s *sqlStrConcat) findInjectionInBranch(ctx *gosec.Context, branch []ast.Expr) *ast.BinaryExpr { - for _, node := range branch { - be, ok := node.(*ast.BinaryExpr) - if !ok { - continue - } - - operands := gosec.GetBinaryExprOperands(be) - - for _, op := range operands { - if _, ok := op.(*ast.BasicLit); ok { - continue - } - - if ident, ok := op.(*ast.Ident); ok && s.checkObject(ident, ctx) { - continue - } - - return be - } - } - return nil -} - -// see if we can figure out what it is -func (s *sqlStrConcat) checkObject(n *ast.Ident, c *gosec.Context) bool { - if n.Obj != nil { - return n.Obj.Kind != ast.Var && n.Obj.Kind != ast.Fun - } - - // Try to resolve unresolved identifiers using other files in same package - for _, file := range c.PkgFiles { - if node, ok := file.Scope.Objects[n.String()]; ok { - return node.Kind != ast.Var && node.Kind != ast.Fun - } - } - return false -} - -// checkQuery verifies if the query parameters is a string concatenation -func (s *sqlStrConcat) checkQuery(call *ast.CallExpr, ctx *gosec.Context) (*issue.Issue, error) { - query, err := findQueryArg(call, ctx) - if err != nil { - return nil, err - } - - 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 - } - } - for _, op := range operands[1:] { - if _, ok := op.(*ast.BasicLit); ok { - continue - } - if op, ok := op.(*ast.Ident); ok && s.checkObject(op, ctx) { - continue - } - return ctx.NewIssue(be, s.ID(), s.What, s.Severity, s.Confidence), nil - } - } - } - - // Handle the case where an injection occurs as an infixed string concatenation, ie "SELECT * FROM foo WHERE name = '" + os.Args[0] + "' AND 1=1" - if id, ok := query.(*ast.Ident); ok { - var match bool - for _, str := range gosec.GetIdentStringValuesRecursive(id) { - if s.MatchPatterns(str) { - match = true - break - } - } - - if !match { - return nil, nil - } - - switch decl := id.Obj.Decl.(type) { - case *ast.AssignStmt: - if injection := s.findInjectionInBranch(ctx, decl.Rhs); injection != nil { - return ctx.NewIssue(injection, 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) (*issue.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, _ gosec.Config) (gosec.Rule, []ast.Node) { - rule := &sqlStrConcat{ - sqlStatement: sqlStatement{ - patterns: []*regexp.Regexp{ - regexp.MustCompile("(?i)(SELECT|DELETE|INSERT|UPDATE|INTO|FROM|WHERE)( |\n|\r|\t)"), - }, - MetaData: issue.MetaData{ - ID: id, - Severity: issue.Medium, - Confidence: issue.High, - What: "SQL string concatenation", - }, - CallList: gosec.NewCallList(), - }, - } - - for s, si := range sqlCallIdents { - for i := range si { - rule.Add(s, i) - } - } - return rule, []ast.Node{(*ast.AssignStmt)(nil), (*ast.ExprStmt)(nil)} -} - -type sqlStrFormat struct { - gosec.CallList - sqlStatement - fmtCalls gosec.CallList - noIssue gosec.CallList - noIssueQuoted gosec.CallList -} - -// see if we can figure out what it is -func (s *sqlStrFormat) constObject(e ast.Expr, c *gosec.Context) bool { - n, ok := e.(*ast.Ident) - if !ok { - return false - } - - if n.Obj != nil { - return n.Obj.Kind == ast.Con - } - - // Try to resolve unresolved identifiers using other files in same package - for _, file := range c.PkgFiles { - if node, ok := file.Scope.Objects[n.String()]; ok { - return node.Kind == ast.Con - } - } - return false -} - -func (s *sqlStrFormat) checkQuery(call *ast.CallExpr, ctx *gosec.Context) (*issue.Issue, error) { - query, err := findQueryArg(call, ctx) - if err != nil { - return nil, err - } - - 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 := s.checkFormatting(expr, ctx) - if issue != nil { - return issue, err - } - } - } - } - - return nil, nil -} - -func (s *sqlStrFormat) checkFormatting(n ast.Node, ctx *gosec.Context) *issue.Issue { - // argIndex changes the function argument which gets matched to the regex - argIndex := 0 - 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" { - // if os.Stderr or os.Stdout is in Arg[0], mark as no issue - if arg, ok := node.Args[0].(*ast.SelectorExpr); ok { - if ident, ok := arg.X.(*ast.Ident); ok { - if s.noIssue.Contains(ident.Name, arg.Sel.Name) { - return nil - } - } - } - // the function is Fprintf so set argIndex = 1 - argIndex = 1 - } - } - - // no formatter - if len(node.Args) == 0 { - return nil - } - - var formatter string - - // concats callexpr arg strings together if needed before regex evaluation - if argExpr, ok := node.Args[argIndex].(*ast.BinaryExpr); ok { - if fullStr, ok := gosec.ConcatString(argExpr); ok { - formatter = fullStr - } - } else if arg, e := gosec.GetString(node.Args[argIndex]); e == nil { - formatter = arg - } - if len(formatter) <= 0 { - return nil - } - - // If all formatter args are quoted or constant, then the SQL construction is safe - if argIndex+1 < len(node.Args) { - allSafe := true - for _, arg := range node.Args[argIndex+1:] { - if n := s.noIssueQuoted.ContainsPkgCallExpr(arg, ctx, true); n == nil && !s.constObject(arg, ctx) { - allSafe = false - break - } - } - if allSafe { - return nil - } - } - if s.MatchPatterns(formatter) { - return ctx.NewIssue(n, s.ID(), s.What, s.Severity, s.Confidence) - } - } - return 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) (*issue.Issue, error) { - switch stmt := n.(type) { - case *ast.AssignStmt: - for _, expr := range stmt.Rhs { - if call, ok := expr.(*ast.CallExpr); ok { - selector, ok := call.Fun.(*ast.SelectorExpr) - if !ok { - continue - } - sqlQueryCall, ok := selector.X.(*ast.CallExpr) - if ok && s.ContainsCallExpr(sqlQueryCall, ctx) != nil { - issue, err := s.checkQuery(sqlQueryCall, ctx) - if err == nil && issue != nil { - return issue, err - } - } - } - 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 -} - -// NewSQLStrFormat looks for cases where we're building SQL query strings using format strings -func NewSQLStrFormat(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { - rule := &sqlStrFormat{ - CallList: gosec.NewCallList(), - fmtCalls: gosec.NewCallList(), - noIssue: gosec.NewCallList(), - noIssueQuoted: gosec.NewCallList(), - sqlStatement: sqlStatement{ - patterns: []*regexp.Regexp{ - regexp.MustCompile("(?i)(SELECT|DELETE|INSERT|UPDATE|INTO|FROM|WHERE)( |\n|\r|\t)"), - regexp.MustCompile("%[^bdoxXfFp]"), - }, - MetaData: issue.MetaData{ - ID: id, - Severity: issue.Medium, - Confidence: issue.High, - What: "SQL string formatting", - }, - }, - } - for s, si := range sqlCallIdents { - for i := range si { - rule.Add(s, i) - } - } - 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.AssignStmt)(nil), (*ast.ExprStmt)(nil)} -} diff --git a/vendor/github.com/securego/gosec/v2/rules/ssh.go b/vendor/github.com/securego/gosec/v2/rules/ssh.go deleted file mode 100644 index e2ba5a3f4..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/ssh.go +++ /dev/null @@ -1,39 +0,0 @@ -package rules - -import ( - "go/ast" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/issue" -) - -type sshHostKey struct { - issue.MetaData - pkg string - calls []string -} - -func (r *sshHostKey) ID() string { - return r.MetaData.ID -} - -func (r *sshHostKey) Match(n ast.Node, c *gosec.Context) (gi *issue.Issue, err error) { - if _, matches := gosec.MatchCallByPackage(n, c, r.pkg, r.calls...); matches { - return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil - } - return nil, nil -} - -// NewSSHHostKey rule detects the use of insecure ssh HostKeyCallback. -func NewSSHHostKey(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { - return &sshHostKey{ - pkg: "golang.org/x/crypto/ssh", - calls: []string{"InsecureIgnoreHostKey"}, - MetaData: issue.MetaData{ - ID: id, - What: "Use of ssh InsecureIgnoreHostKey should be audited", - Severity: issue.Medium, - Confidence: issue.High, - }, - }, []ast.Node{(*ast.CallExpr)(nil)} -} diff --git a/vendor/github.com/securego/gosec/v2/rules/ssrf.go b/vendor/github.com/securego/gosec/v2/rules/ssrf.go deleted file mode 100644 index dbf01081b..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/ssrf.go +++ /dev/null @@ -1,67 +0,0 @@ -package rules - -import ( - "go/ast" - "go/types" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/issue" -) - -type ssrf struct { - issue.MetaData - gosec.CallList -} - -// ID returns the identifier for this rule -func (r *ssrf) ID() string { - return r.MetaData.ID -} - -// ResolveVar tries to resolve the first argument of a call expression -// The first argument is the url -func (r *ssrf) ResolveVar(n *ast.CallExpr, c *gosec.Context) bool { - if len(n.Args) > 0 { - arg := n.Args[0] - if ident, ok := arg.(*ast.Ident); ok { - obj := c.Info.ObjectOf(ident) - if _, ok := obj.(*types.Var); ok { - scope := c.Pkg.Scope() - if scope != nil && scope.Lookup(ident.Name) != nil { - // a URL defined in a variable at package scope can be changed at any time - return true - } - if !gosec.TryResolve(ident, c) { - return true - } - } - } - } - return false -} - -// Match inspects AST nodes to determine if certain net/http methods are called with variable input -func (r *ssrf) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { - // Call expression is using http package directly - if node := r.ContainsPkgCallExpr(n, c, false); node != nil { - if r.ResolveVar(node, c) { - return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil - } - } - return nil, nil -} - -// NewSSRFCheck detects cases where HTTP requests are sent -func NewSSRFCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { - rule := &ssrf{ - CallList: gosec.NewCallList(), - MetaData: issue.MetaData{ - ID: id, - What: "Potential HTTP request made with variable url", - Severity: issue.Medium, - Confidence: issue.Medium, - }, - } - rule.AddAll("net/http", "Do", "Get", "Head", "Post", "PostForm", "RoundTrip") - return rule, []ast.Node{(*ast.CallExpr)(nil)} -} diff --git a/vendor/github.com/securego/gosec/v2/rules/subproc.go b/vendor/github.com/securego/gosec/v2/rules/subproc.go deleted file mode 100644 index 1e2cedaa5..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/subproc.go +++ /dev/null @@ -1,123 +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" - "go/types" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/issue" -) - -type subprocess struct { - issue.MetaData - gosec.CallList -} - -func (r *subprocess) ID() string { - return r.MetaData.ID -} - -// TODO(gm) The only real potential for command injection with a Go project -// is something like this: -// -// syscall.Exec("/bin/sh", []string{"-c", tainted}) -// -// E.g. Input is correctly escaped but the execution context being used -// is unsafe. For example: -// -// syscall.Exec("echo", "foobar" + tainted) -func (r *subprocess) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { - if node := r.ContainsPkgCallExpr(n, c, false); node != nil { - args := node.Args - if r.isContext(n, c) { - args = args[1:] - } - for _, arg := range args { - if ident, ok := arg.(*ast.Ident); ok { - obj := c.Info.ObjectOf(ident) - - // need to cast and check whether it is for a variable ? - _, variable := obj.(*types.Var) - - // .. indeed it is a variable then processing is different than a normal - // field assignment - if variable { - // skip the check when the declaration is not available - if ident.Obj == nil { - continue - } - switch ident.Obj.Decl.(type) { - case *ast.AssignStmt: - _, assignment := ident.Obj.Decl.(*ast.AssignStmt) - if variable && assignment { - if !gosec.TryResolve(ident, c) { - return c.NewIssue(n, r.ID(), "Subprocess launched with variable", issue.Medium, issue.High), nil - } - } - case *ast.Field: - _, field := ident.Obj.Decl.(*ast.Field) - if variable && field { - // check if the variable exist in the scope - vv, vvok := obj.(*types.Var) - - if vvok && vv.Parent().Lookup(ident.Name) == nil { - return c.NewIssue(n, r.ID(), "Subprocess launched with variable", issue.Medium, issue.High), nil - } - } - case *ast.ValueSpec: - _, valueSpec := ident.Obj.Decl.(*ast.ValueSpec) - if variable && valueSpec { - if !gosec.TryResolve(ident, c) { - return c.NewIssue(n, r.ID(), "Subprocess launched with variable", issue.Medium, issue.High), nil - } - } - } - } - } else if !gosec.TryResolve(arg, c) { - // the arg is not a constant or a variable but instead a function call or os.Args[i] - return c.NewIssue(n, r.ID(), "Subprocess launched with a potential tainted input or cmd arguments", issue.Medium, issue.High), nil - } - } - } - return nil, nil -} - -// isContext checks whether or not the node is a CommandContext call or not -// This is required in order to skip the first argument from the check. -func (r *subprocess) isContext(n ast.Node, ctx *gosec.Context) bool { - selector, indent, err := gosec.GetCallInfo(n, ctx) - if err != nil { - return false - } - if selector == "exec" && indent == "CommandContext" { - return true - } - return false -} - -// NewSubproc detects cases where we are forking out to an external process -func NewSubproc(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { - rule := &subprocess{issue.MetaData{ID: id}, gosec.NewCallList()} - rule.Add("os/exec", "Command") - rule.Add("os/exec", "CommandContext") - rule.Add("syscall", "Exec") - rule.Add("syscall", "ForkExec") - rule.Add("syscall", "StartProcess") - rule.Add("golang.org/x/sys/execabs", "Command") - rule.Add("golang.org/x/sys/execabs", "CommandContext") - return rule, []ast.Node{(*ast.CallExpr)(nil)} -} diff --git a/vendor/github.com/securego/gosec/v2/rules/tempfiles.go b/vendor/github.com/securego/gosec/v2/rules/tempfiles.go deleted file mode 100644 index 6fef52a2c..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/tempfiles.go +++ /dev/null @@ -1,88 +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" - "regexp" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/issue" -) - -type badTempFile struct { - issue.MetaData - calls gosec.CallList - args *regexp.Regexp - argCalls gosec.CallList - nestedCalls gosec.CallList -} - -func (t *badTempFile) ID() string { - return t.MetaData.ID -} - -func (t *badTempFile) findTempDirArgs(n ast.Node, c *gosec.Context, suspect ast.Node) *issue.Issue { - if s, e := gosec.GetString(suspect); e == nil { - if t.args.MatchString(s) { - return c.NewIssue(n, t.ID(), t.What, t.Severity, t.Confidence) - } - return nil - } - if ce := t.argCalls.ContainsPkgCallExpr(suspect, c, false); ce != nil { - return c.NewIssue(n, t.ID(), t.What, t.Severity, t.Confidence) - } - if be, ok := suspect.(*ast.BinaryExpr); ok { - if ops := gosec.GetBinaryExprOperands(be); len(ops) != 0 { - return t.findTempDirArgs(n, c, ops[0]) - } - return nil - } - if ce := t.nestedCalls.ContainsPkgCallExpr(suspect, c, false); ce != nil { - return t.findTempDirArgs(n, c, ce.Args[0]) - } - return nil -} - -func (t *badTempFile) Match(n ast.Node, c *gosec.Context) (gi *issue.Issue, err error) { - if node := t.calls.ContainsPkgCallExpr(n, c, false); node != nil { - return t.findTempDirArgs(n, c, node.Args[0]), nil - } - return nil, nil -} - -// NewBadTempFile detects direct writes to predictable path in temporary directory -func NewBadTempFile(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { - calls := gosec.NewCallList() - calls.Add("io/ioutil", "WriteFile") - calls.AddAll("os", "Create", "WriteFile") - argCalls := gosec.NewCallList() - argCalls.Add("os", "TempDir") - nestedCalls := gosec.NewCallList() - nestedCalls.Add("path", "Join") - nestedCalls.Add("path/filepath", "Join") - return &badTempFile{ - calls: calls, - args: regexp.MustCompile(`^(/(usr|var))?/tmp(/.*)?$`), - argCalls: argCalls, - nestedCalls: nestedCalls, - MetaData: issue.MetaData{ - ID: id, - Severity: issue.Medium, - Confidence: issue.High, - What: "File creation in shared tmp directory without using ioutil.Tempfile", - }, - }, []ast.Node{(*ast.CallExpr)(nil)} -} diff --git a/vendor/github.com/securego/gosec/v2/rules/templates.go b/vendor/github.com/securego/gosec/v2/rules/templates.go deleted file mode 100644 index 3d5f9a977..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/templates.go +++ /dev/null @@ -1,64 +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" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/issue" -) - -type templateCheck struct { - issue.MetaData - calls gosec.CallList -} - -func (t *templateCheck) ID() string { - return t.MetaData.ID -} - -func (t *templateCheck) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { - if node := t.calls.ContainsPkgCallExpr(n, c, false); node != nil { - for _, arg := range node.Args { - if _, ok := arg.(*ast.BasicLit); !ok { // basic lits are safe - return c.NewIssue(n, t.ID(), t.What, t.Severity, t.Confidence), nil - } - } - } - return nil, nil -} - -// NewTemplateCheck constructs the template check rule. This rule is used to -// find use of templates where HTML/JS escaping is not being used -func NewTemplateCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { - calls := gosec.NewCallList() - calls.Add("html/template", "CSS") - calls.Add("html/template", "HTML") - calls.Add("html/template", "HTMLAttr") - calls.Add("html/template", "JS") - calls.Add("html/template", "JSStr") - calls.Add("html/template", "Srcset") - calls.Add("html/template", "URL") - return &templateCheck{ - calls: calls, - MetaData: issue.MetaData{ - ID: id, - Severity: issue.Medium, - Confidence: issue.Low, - What: "The used method does not auto-escape HTML. This can potentially lead to 'Cross-site Scripting' vulnerabilities, in case the attacker controls the input.", - }, - }, []ast.Node{(*ast.CallExpr)(nil)} -} diff --git a/vendor/github.com/securego/gosec/v2/rules/tls.go b/vendor/github.com/securego/gosec/v2/rules/tls.go deleted file mode 100644 index 65a0b5a33..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/tls.go +++ /dev/null @@ -1,239 +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. - -//go:generate tlsconfig - -package rules - -import ( - "crypto/tls" - "fmt" - "go/ast" - "go/types" - "strconv" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/issue" -) - -type insecureConfigTLS struct { - issue.MetaData - MinVersion int64 - MaxVersion int64 - requiredType string - goodCiphers []string - actualMinVersion int64 - actualMaxVersion int64 -} - -func (t *insecureConfigTLS) ID() string { - return t.MetaData.ID -} - -func stringInSlice(a string, list []string) bool { - for _, b := range list { - if b == a { - return true - } - } - return false -} - -func (t *insecureConfigTLS) processTLSCipherSuites(n ast.Node, c *gosec.Context) *issue.Issue { - if ciphers, ok := n.(*ast.CompositeLit); ok { - for _, cipher := range ciphers.Elts { - if ident, ok := cipher.(*ast.SelectorExpr); ok { - if !stringInSlice(ident.Sel.Name, t.goodCiphers) { - err := fmt.Sprintf("TLS Bad Cipher Suite: %s", ident.Sel.Name) - return c.NewIssue(ident, t.ID(), err, issue.High, issue.High) - } - } - } - } - return nil -} - -func (t *insecureConfigTLS) processTLSConf(n ast.Node, c *gosec.Context) *issue.Issue { - if kve, ok := n.(*ast.KeyValueExpr); ok { - issue := t.processTLSConfVal(kve.Key, kve.Value, c) - if issue != nil { - return issue - } - } else if assign, ok := n.(*ast.AssignStmt); ok { - if len(assign.Lhs) < 1 || len(assign.Rhs) < 1 { - return nil - } - if selector, ok := assign.Lhs[0].(*ast.SelectorExpr); ok { - issue := t.processTLSConfVal(selector.Sel, assign.Rhs[0], c) - if issue != nil { - return issue - } - } - } - return nil -} - -func (t *insecureConfigTLS) processTLSConfVal(key ast.Expr, value ast.Expr, c *gosec.Context) *issue.Issue { - if ident, ok := key.(*ast.Ident); ok { - switch ident.Name { - case "InsecureSkipVerify": - if node, ok := value.(*ast.Ident); ok { - if node.Name != "false" { - return c.NewIssue(value, t.ID(), "TLS InsecureSkipVerify set true.", issue.High, issue.High) - } - } else { - // TODO(tk): symbol tab look up to get the actual value - return c.NewIssue(value, t.ID(), "TLS InsecureSkipVerify may be true.", issue.High, issue.Low) - } - - case "PreferServerCipherSuites": - if node, ok := value.(*ast.Ident); ok { - if node.Name == "false" { - return c.NewIssue(value, t.ID(), "TLS PreferServerCipherSuites set false.", issue.Medium, issue.High) - } - } else { - // TODO(tk): symbol tab look up to get the actual value - return c.NewIssue(value, t.ID(), "TLS PreferServerCipherSuites may be false.", issue.Medium, issue.Low) - } - - case "MinVersion": - if d, ok := value.(*ast.Ident); ok { - obj := d.Obj - if obj == nil { - for _, f := range c.PkgFiles { - obj = f.Scope.Lookup(d.Name) - if obj != nil { - break - } - } - } - if vs, ok := obj.Decl.(*ast.ValueSpec); ok && len(vs.Values) > 0 { - if s, ok := vs.Values[0].(*ast.SelectorExpr); ok { - x := s.X.(*ast.Ident).Name - sel := s.Sel.Name - - for _, imp := range c.Pkg.Imports() { - if imp.Name() == x { - tObj := imp.Scope().Lookup(sel) - if cst, ok := tObj.(*types.Const); ok { - // ..got the value check if this can be translated - if minVersion, err := strconv.ParseInt(cst.Val().String(), 0, 64); err == nil { - t.actualMinVersion = minVersion - } - } - } - } - } - if ival, ierr := gosec.GetInt(vs.Values[0]); ierr == nil { - t.actualMinVersion = ival - } - } - } else if ival, ierr := gosec.GetInt(value); ierr == nil { - t.actualMinVersion = ival - } else { - if se, ok := value.(*ast.SelectorExpr); ok { - if pkg, ok := se.X.(*ast.Ident); ok { - if ip, ok := gosec.GetImportPath(pkg.Name, c); ok && ip == "crypto/tls" { - t.actualMinVersion = t.mapVersion(se.Sel.Name) - } - } - } - } - - case "MaxVersion": - if ival, ierr := gosec.GetInt(value); ierr == nil { - t.actualMaxVersion = ival - } else { - if se, ok := value.(*ast.SelectorExpr); ok { - if pkg, ok := se.X.(*ast.Ident); ok { - if ip, ok := gosec.GetImportPath(pkg.Name, c); ok && ip == "crypto/tls" { - t.actualMaxVersion = t.mapVersion(se.Sel.Name) - } - } - } - } - - case "CipherSuites": - if ret := t.processTLSCipherSuites(value, c); ret != nil { - return ret - } - - } - } - return nil -} - -func (t *insecureConfigTLS) mapVersion(version string) int64 { - var v int64 - 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) *issue.Issue { - if t.actualMaxVersion == 0 && t.actualMinVersion >= t.MinVersion { - // no warning is generated since the min version is greater than the secure min version - return nil - } - if t.actualMinVersion < t.MinVersion { - return c.NewIssue(n, t.ID(), "TLS MinVersion too low.", issue.High, issue.High) - } - if t.actualMaxVersion < t.MaxVersion { - return c.NewIssue(n, t.ID(), "TLS MaxVersion too low.", issue.High, issue.High) - } - return nil -} - -func (t *insecureConfigTLS) resetVersion() { - t.actualMaxVersion = 0 - t.actualMinVersion = 0 -} - -func (t *insecureConfigTLS) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { - if complit, ok := n.(*ast.CompositeLit); ok && complit.Type != nil { - actualType := c.Info.TypeOf(complit.Type) - if actualType != nil && actualType.String() == t.requiredType { - for _, elt := range complit.Elts { - issue := t.processTLSConf(elt, c) - if issue != nil { - return issue, nil - } - } - issue := t.checkVersion(complit, c) - t.resetVersion() - return issue, nil - } - } else { - if assign, ok := n.(*ast.AssignStmt); ok && len(assign.Lhs) > 0 { - if selector, ok := assign.Lhs[0].(*ast.SelectorExpr); ok { - actualType := c.Info.TypeOf(selector.X) - if actualType != nil && actualType.String() == t.requiredType { - issue := t.processTLSConf(assign, c) - if issue != nil { - return issue, nil - } - } - } - } - } - return nil, nil -} diff --git a/vendor/github.com/securego/gosec/v2/rules/tls_config.go b/vendor/github.com/securego/gosec/v2/rules/tls_config.go deleted file mode 100644 index cbbdf7983..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/tls_config.go +++ /dev/null @@ -1,93 +0,0 @@ -package rules - -import ( - "go/ast" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/issue" -) - -// NewModernTLSCheck creates a check for Modern TLS ciphers -// DO NOT EDIT - generated by tlsconfig tool -func NewModernTLSCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { - return &insecureConfigTLS{ - MetaData: issue.MetaData{ID: id}, - requiredType: "crypto/tls.Config", - MinVersion: 0x0304, - MaxVersion: 0x0304, - goodCiphers: []string{ - "TLS_AES_128_GCM_SHA256", - "TLS_AES_256_GCM_SHA384", - "TLS_CHACHA20_POLY1305_SHA256", - }, - }, []ast.Node{(*ast.CompositeLit)(nil), (*ast.AssignStmt)(nil)} -} - -// NewIntermediateTLSCheck creates a check for Intermediate TLS ciphers -// DO NOT EDIT - generated by tlsconfig tool -func NewIntermediateTLSCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { - return &insecureConfigTLS{ - MetaData: issue.MetaData{ID: id}, - requiredType: "crypto/tls.Config", - MinVersion: 0x0303, - MaxVersion: 0x0304, - goodCiphers: []string{ - "TLS_AES_128_GCM_SHA256", - "TLS_AES_256_GCM_SHA384", - "TLS_CHACHA20_POLY1305_SHA256", - "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", - "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", - "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", - "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", - "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", - "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", - "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", - "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", - "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", - }, - }, []ast.Node{(*ast.CompositeLit)(nil), (*ast.AssignStmt)(nil)} -} - -// NewOldTLSCheck creates a check for Old TLS ciphers -// DO NOT EDIT - generated by tlsconfig tool -func NewOldTLSCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { - return &insecureConfigTLS{ - MetaData: issue.MetaData{ID: id}, - requiredType: "crypto/tls.Config", - MinVersion: 0x0301, - MaxVersion: 0x0304, - goodCiphers: []string{ - "TLS_AES_128_GCM_SHA256", - "TLS_AES_256_GCM_SHA384", - "TLS_CHACHA20_POLY1305_SHA256", - "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", - "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", - "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", - "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", - "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", - "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", - "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", - "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", - "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", - "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", - "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", - "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", - "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", - "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", - "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", - "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", - "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", - "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", - "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", - "TLS_RSA_WITH_AES_128_GCM_SHA256", - "TLS_RSA_WITH_AES_256_GCM_SHA384", - "TLS_RSA_WITH_AES_128_CBC_SHA256", - "TLS_RSA_WITH_AES_256_CBC_SHA256", - "TLS_RSA_WITH_AES_128_CBC_SHA", - "TLS_RSA_WITH_AES_256_CBC_SHA", - "TLS_RSA_WITH_3DES_EDE_CBC_SHA", - }, - }, []ast.Node{(*ast.CompositeLit)(nil), (*ast.AssignStmt)(nil)} -} diff --git a/vendor/github.com/securego/gosec/v2/rules/unsafe.go b/vendor/github.com/securego/gosec/v2/rules/unsafe.go deleted file mode 100644 index 2e2adca7c..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/unsafe.go +++ /dev/null @@ -1,54 +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" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/issue" -) - -type usingUnsafe struct { - issue.MetaData - pkg string - calls []string -} - -func (r *usingUnsafe) ID() string { - return r.MetaData.ID -} - -func (r *usingUnsafe) Match(n ast.Node, c *gosec.Context) (gi *issue.Issue, err error) { - if _, matches := gosec.MatchCallByPackage(n, c, r.pkg, r.calls...); matches { - return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil - } - return nil, nil -} - -// NewUsingUnsafe rule detects the use of the unsafe package. This is only -// really useful for auditing purposes. -func NewUsingUnsafe(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { - return &usingUnsafe{ - pkg: "unsafe", - calls: []string{"Pointer", "String", "StringData", "Slice", "SliceData"}, - MetaData: issue.MetaData{ - ID: id, - What: "Use of unsafe calls should be audited", - Severity: issue.Low, - Confidence: issue.High, - }, - }, []ast.Node{(*ast.CallExpr)(nil)} -} diff --git a/vendor/github.com/securego/gosec/v2/rules/weakcrypto.go b/vendor/github.com/securego/gosec/v2/rules/weakcrypto.go deleted file mode 100644 index 143f67d4e..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/weakcrypto.go +++ /dev/null @@ -1,57 +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" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/issue" -) - -type usesWeakCryptographyEncryption struct { - issue.MetaData - blocklist map[string][]string -} - -func (r *usesWeakCryptographyEncryption) ID() string { - return r.MetaData.ID -} - -func (r *usesWeakCryptographyEncryption) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { - for pkg, funcs := range r.blocklist { - if _, matched := gosec.MatchCallByPackage(n, c, pkg, funcs...); matched { - return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil - } - } - return nil, nil -} - -// NewUsesWeakCryptographyEncryption detects uses of des.*, rc4.* -func NewUsesWeakCryptographyEncryption(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { - calls := make(map[string][]string) - calls["crypto/des"] = []string{"NewCipher", "NewTripleDESCipher"} - calls["crypto/rc4"] = []string{"NewCipher"} - rule := &usesWeakCryptographyEncryption{ - blocklist: calls, - MetaData: issue.MetaData{ - ID: id, - Severity: issue.Medium, - Confidence: issue.High, - What: "Use of weak cryptographic primitive", - }, - } - return rule, []ast.Node{(*ast.CallExpr)(nil)} -} diff --git a/vendor/github.com/securego/gosec/v2/rules/weakcryptohash.go b/vendor/github.com/securego/gosec/v2/rules/weakcryptohash.go deleted file mode 100644 index 298555de1..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/weakcryptohash.go +++ /dev/null @@ -1,55 +0,0 @@ -// 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" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/issue" -) - -type usesWeakCryptographyHash struct { - issue.MetaData - blocklist map[string][]string -} - -func (r *usesWeakCryptographyHash) ID() string { - return r.MetaData.ID -} - -func (r *usesWeakCryptographyHash) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { - for pkg, funcs := range r.blocklist { - if _, matched := gosec.MatchCallByPackage(n, c, pkg, funcs...); matched { - return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil - } - } - return nil, nil -} - -// NewUsesWeakCryptographyHash detects uses of md5.*, sha1.* -func NewUsesWeakCryptographyHash(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { - calls := make(map[string][]string) - calls["crypto/md5"] = []string{"New", "Sum"} - calls["crypto/sha1"] = []string{"New", "Sum"} - rule := &usesWeakCryptographyHash{ - blocklist: calls, - MetaData: issue.MetaData{ - ID: id, - Severity: issue.Medium, - Confidence: issue.High, - What: "Use of weak cryptographic primitive", - }, - } - return rule, []ast.Node{(*ast.CallExpr)(nil)} -} diff --git a/vendor/github.com/securego/gosec/v2/rules/weakdepricatedcryptohash.go b/vendor/github.com/securego/gosec/v2/rules/weakdepricatedcryptohash.go deleted file mode 100644 index 68297355c..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/weakdepricatedcryptohash.go +++ /dev/null @@ -1,57 +0,0 @@ -// (c) Copyright 2024 Mercedes-Benz Tech Innovation GmbH -// -// 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" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/issue" -) - -type usesWeakDeprecatedCryptographyHash struct { - issue.MetaData - blocklist map[string][]string -} - -func (r *usesWeakDeprecatedCryptographyHash) ID() string { - return r.MetaData.ID -} - -func (r *usesWeakDeprecatedCryptographyHash) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { - for pkg, funcs := range r.blocklist { - if _, matched := gosec.MatchCallByPackage(n, c, pkg, funcs...); matched { - return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil - } - } - return nil, nil -} - -// NewUsesWeakCryptographyHash detects uses of md4.New, ripemd160.New -func NewUsesWeakDeprecatedCryptographyHash(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { - calls := make(map[string][]string) - calls["golang.org/x/crypto/md4"] = []string{"New"} - calls["golang.org/x/crypto/ripemd160"] = []string{"New"} - rule := &usesWeakDeprecatedCryptographyHash{ - blocklist: calls, - MetaData: issue.MetaData{ - ID: id, - Severity: issue.Medium, - Confidence: issue.High, - What: "Use of deprecated weak cryptographic primitive", - }, - } - return rule, []ast.Node{(*ast.CallExpr)(nil)} -} -- cgit mrf-deployment