mirror of
https://github.com/DNSCrypt/dnscrypt-proxy.git
synced 2025-04-05 14:17:36 +03:00
Update deps
This commit is contained in:
parent
f033bb3034
commit
5a091c6da4
1997 changed files with 368830 additions and 2045 deletions
35
vendor/github.com/securego/gosec/v2/.gitignore
generated
vendored
Normal file
35
vendor/github.com/securego/gosec/v2/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
# 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
|
13
vendor/github.com/securego/gosec/v2/.golangci.yml
generated
vendored
Normal file
13
vendor/github.com/securego/gosec/v2/.golangci.yml
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
linters:
|
||||
enable:
|
||||
- megacheck
|
||||
- govet
|
||||
- unparam
|
||||
- unconvert
|
||||
- misspell
|
||||
- gofmt
|
||||
- golint
|
||||
- gosec
|
||||
- nakedret
|
||||
- dogsled
|
||||
- depguard
|
21
vendor/github.com/securego/gosec/v2/.goreleaser.yml
generated
vendored
Normal file
21
vendor/github.com/securego/gosec/v2/.goreleaser.yml
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
project_name: gosec
|
||||
|
||||
release:
|
||||
github:
|
||||
owner: securego
|
||||
name: gosec
|
||||
|
||||
builds:
|
||||
- main : ./cmd/gosec/
|
||||
binary: gosec
|
||||
goos:
|
||||
- darwin
|
||||
- linux
|
||||
- windows
|
||||
goarch:
|
||||
- amd64
|
||||
- arm64
|
||||
ldflags: -X main.Version={{.Version}} -X main.GitTag={{.Tag}} -X main.BuildDate={{.Date}}
|
||||
env:
|
||||
- CGO_ENABLED=0
|
15
vendor/github.com/securego/gosec/v2/Dockerfile
generated
vendored
Normal file
15
vendor/github.com/securego/gosec/v2/Dockerfile
generated
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
ARG GO_VERSION
|
||||
FROM golang:${GO_VERSION}-alpine AS builder
|
||||
RUN apk add --update --no-cache ca-certificates make git curl gcc libc-dev
|
||||
RUN mkdir -p /build
|
||||
WORKDIR /build
|
||||
COPY . /build/
|
||||
RUN go mod download
|
||||
RUN make build-linux
|
||||
|
||||
FROM golang:${GO_VERSION}-alpine
|
||||
RUN apk add --update --no-cache ca-certificates bash git gcc libc-dev
|
||||
ENV GO111MODULE on
|
||||
COPY --from=builder /build/gosec /bin/gosec
|
||||
COPY entrypoint.sh /bin/entrypoint.sh
|
||||
ENTRYPOINT ["/bin/entrypoint.sh"]
|
154
vendor/github.com/securego/gosec/v2/LICENSE.txt
generated
vendored
Normal file
154
vendor/github.com/securego/gosec/v2/LICENSE.txt
generated
vendored
Normal file
|
@ -0,0 +1,154 @@
|
|||
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
|
71
vendor/github.com/securego/gosec/v2/Makefile
generated
vendored
Normal file
71
vendor/github.com/securego/gosec/v2/Makefile
generated
vendored
Normal file
|
@ -0,0 +1,71 @@
|
|||
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
|
||||
BUILDFLAGS := '-w -s'
|
||||
CGO_ENABLED = 0
|
||||
GO := GO111MODULE=on go
|
||||
GO_NOMOD :=GO111MODULE=off go
|
||||
GOPATH ?= $(shell $(GO) env GOPATH)
|
||||
GOBIN ?= $(GOPATH)/bin
|
||||
GOLINT ?= $(GOBIN)/golint
|
||||
GOSEC ?= $(GOBIN)/gosec
|
||||
GINKGO ?= $(GOBIN)/ginkgo
|
||||
GO_VERSION = 1.15
|
||||
|
||||
default:
|
||||
$(MAKE) build
|
||||
|
||||
install-test-deps:
|
||||
$(GO_NOMOD) get -u github.com/onsi/ginkgo/ginkgo
|
||||
$(GO_NOMOD) get -u golang.org/x/crypto/ssh
|
||||
$(GO_NOMOD) get -u github.com/lib/pq
|
||||
|
||||
test: install-test-deps build fmt lint sec
|
||||
$(GINKGO) -r -v
|
||||
|
||||
fmt:
|
||||
@echo "FORMATTING"
|
||||
@FORMATTED=`$(GO) fmt ./...`
|
||||
@([[ ! -z "$(FORMATTED)" ]] && printf "Fixed unformatted files:\n$(FORMATTED)") || true
|
||||
|
||||
lint:
|
||||
@echo "LINTING"
|
||||
$(GO_NOMOD) get -u golang.org/x/lint/golint
|
||||
$(GOLINT) -set_exit_status ./...
|
||||
@echo "VETTING"
|
||||
$(GO) vet ./...
|
||||
|
||||
sec:
|
||||
@echo "SECURITY SCANNING"
|
||||
./$(BIN) ./...
|
||||
|
||||
test-coverage: install-test-deps
|
||||
go test -race -v -count=1 -coverprofile=coverage.out ./...
|
||||
|
||||
build:
|
||||
go build -o $(BIN) ./cmd/gosec/
|
||||
|
||||
clean:
|
||||
rm -rf build vendor dist coverage.txt
|
||||
rm -f release image $(BIN)
|
||||
|
||||
release:
|
||||
@echo "Releasing the gosec binary..."
|
||||
goreleaser release
|
||||
|
||||
build-linux:
|
||||
CGO_ENABLED=$(CGO_ENABLED) GOOS=linux GOARCH=amd64 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
|
||||
|
||||
.PHONY: test build clean release image image-push
|
401
vendor/github.com/securego/gosec/v2/README.md
generated
vendored
Normal file
401
vendor/github.com/securego/gosec/v2/README.md
generated
vendored
Normal file
|
@ -0,0 +1,401 @@
|
|||
|
||||
# gosec - Golang Security Checker
|
||||
|
||||
Inspects source code for security problems by scanning the Go AST.
|
||||
|
||||
<img src="https://securego.io/img/gosec.png" width="320">
|
||||
|
||||
## 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
|
||||
|
||||
[](https://bestpractices.coreinfrastructure.org/projects/3218)
|
||||
[](https://github.com/securego/gosec/actions?query=workflows%3ACI)
|
||||
[](https://codecov.io/gh/securego/gosec)
|
||||
[](https://goreportcard.com/report/github.com/securego/gosec)
|
||||
[](https://godoc.org/github.com/securego/gosec)
|
||||
[](https://securego.io/)
|
||||
[](https://github.com/securego/gosec/releases)
|
||||
[](https://hub.docker.com/r/securego/gosec/tags)
|
||||
[](http://securego.herokuapp.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 "<check sum from the check sum file> 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@v2
|
||||
- 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@v2
|
||||
- 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@v1
|
||||
with:
|
||||
# Path to SARIF file relative to the root of the repository
|
||||
sarif_file: results.sarif
|
||||
```
|
||||
|
||||
### Local Installation
|
||||
|
||||
```bash
|
||||
go get -u github.com/securego/gosec/v2/cmd/gosec
|
||||
```
|
||||
|
||||
## 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
|
||||
- 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: Deferring a method which returns an error
|
||||
- G401: Detect the usage of DES, RC4, 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)
|
||||
- G501: Import blocklist: crypto/md5
|
||||
- G502: Import blocklist: crypto/des
|
||||
- G503: Import blocklist: crypto/rc4
|
||||
- G504: Import blocklist: net/http/cgi
|
||||
- G505: Import blocklist: crypto/sha1
|
||||
- G601: Implicit memory aliasing of items from a range statement
|
||||
|
||||
### Retired rules
|
||||
|
||||
- G105: Audit the use of math/big.Int.Exp - [CVE is fixed](https://github.com/golang/go/issues/15184)
|
||||
|
||||
### 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.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": {
|
||||
"io/ioutil": ["WriteFile"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can also configure the hard-coded credentials rule `G101` with additional patters, 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"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 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 ./...
|
||||
```
|
||||
|
||||
### 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 `#nosec` comment.
|
||||
|
||||
The annotation causes gosec to stop processing any further nodes within the
|
||||
AST so can apply to a whole block or more granularly to a single expression.
|
||||
|
||||
```go
|
||||
|
||||
import "md5" // #nosec
|
||||
|
||||
|
||||
func main(){
|
||||
|
||||
/* #nosec */
|
||||
if x > y {
|
||||
h := md5.New() // this will also be ignored
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
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`
|
||||
|
||||
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 ./...
|
||||
```
|
||||
|
||||
### 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 -tag 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 additionnal properties. The rest can be removed.
|
||||
The URI,ID, UUID, GUID were renamed so it fits the Golang 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.
|
||||
|
||||
### 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 /<PROJECT>/ -v <YOUR PROJECT PATH>/<PROJECT>:/<PROJECT> securego/gosec /<PROJECT>/...
|
||||
```
|
||||
|
||||
**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.
|
28
vendor/github.com/securego/gosec/v2/USERS.md
generated
vendored
Normal file
28
vendor/github.com/securego/gosec/v2/USERS.md
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
# 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/)
|
||||
|
||||
## 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)
|
19
vendor/github.com/securego/gosec/v2/action.yml
generated
vendored
Normal file
19
vendor/github.com/securego/gosec/v2/action.yml
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
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'
|
||||
args:
|
||||
- ${{ inputs.args }}
|
||||
|
||||
branding:
|
||||
icon: 'shield'
|
||||
color: 'blue'
|
376
vendor/github.com/securego/gosec/v2/analyzer.go
generated
vendored
Normal file
376
vendor/github.com/securego/gosec/v2/analyzer.go
generated
vendored
Normal file
|
@ -0,0 +1,376 @@
|
|||
// (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"
|
||||
|
||||
"golang.org/x/tools/go/packages"
|
||||
)
|
||||
|
||||
// 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
|
||||
|
||||
// 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 withe 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
|
||||
Config Config
|
||||
Imports *ImportTracker
|
||||
Ignores []map[string]bool
|
||||
PassedValues map[string]interface{}
|
||||
}
|
||||
|
||||
// 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
|
||||
stats *Metrics
|
||||
errors map[string][]Error // keys are file paths; values are the golang errors in those files
|
||||
tests bool
|
||||
}
|
||||
|
||||
// NewAnalyzer builds a new analyzer.
|
||||
func NewAnalyzer(conf Config, tests bool, logger *log.Logger) *Analyzer {
|
||||
ignoreNoSec := false
|
||||
if enabled, err := conf.IsGlobalEnabled(Nosec); err == nil {
|
||||
ignoreNoSec = enabled
|
||||
}
|
||||
if logger == nil {
|
||||
logger = log.New(os.Stderr, "[gosec]", log.LstdFlags)
|
||||
}
|
||||
return &Analyzer{
|
||||
ignoreNosec: ignoreNoSec,
|
||||
ruleset: make(RuleSet),
|
||||
context: &Context{},
|
||||
config: conf,
|
||||
logger: logger,
|
||||
issues: make([]*Issue, 0, 16),
|
||||
stats: &Metrics{},
|
||||
errors: make(map[string][]Error),
|
||||
tests: tests,
|
||||
}
|
||||
}
|
||||
|
||||
// SetConfig upates 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) {
|
||||
for id, def := range ruleDefinitions {
|
||||
r, nodes := def(id, gosec.config)
|
||||
gosec.ruleset.Register(r, nodes...)
|
||||
}
|
||||
}
|
||||
|
||||
// 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,
|
||||
}
|
||||
|
||||
for _, pkgPath := range packagePaths {
|
||||
pkgs, err := gosec.load(pkgPath, config)
|
||||
if err != nil {
|
||||
gosec.AppendError(pkgPath, err)
|
||||
}
|
||||
for _, pkg := range pkgs {
|
||||
if pkg.Name != "" {
|
||||
err := gosec.ParseErrors(pkg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("parsing errors in pkg %q: %v", pkg.Name, err)
|
||||
}
|
||||
gosec.Check(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.
|
||||
buildD.BuildTags = conf.BuildFlags
|
||||
basePackage, err := buildD.ImportDir(pkgPath, build.ImportComment)
|
||||
if err != nil {
|
||||
return []*packages.Package{}, fmt.Errorf("importing dir %q: %v", pkgPath, err)
|
||||
}
|
||||
|
||||
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 := []string{}
|
||||
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.
|
||||
conf.BuildFlags = nil
|
||||
pkgs, err := packages.Load(conf, packageFiles...)
|
||||
if err != nil {
|
||||
return []*packages.Package{}, fmt.Errorf("loading files from package %q: %v", pkgPath, err)
|
||||
}
|
||||
return pkgs, nil
|
||||
}
|
||||
|
||||
// Check runs analysis on the given package
|
||||
func (gosec *Analyzer) Check(pkg *packages.Package) {
|
||||
gosec.logger.Println("Checking package:", pkg.Name)
|
||||
for _, file := range pkg.Syntax {
|
||||
checkedFile := pkg.Fset.File(file.Pos()).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
|
||||
}
|
||||
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.Imports.TrackFile(file)
|
||||
gosec.context.PassedValues = make(map[string]interface{})
|
||||
ast.Walk(gosec, file)
|
||||
gosec.stats.NumFiles++
|
||||
gosec.stats.NumLines += pkg.Fset.File(file.Pos()).LineCount()
|
||||
}
|
||||
}
|
||||
|
||||
// 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: %v", err)
|
||||
}
|
||||
}
|
||||
var column int
|
||||
if len(parts) > 2 {
|
||||
if column, err = strconv.Atoi(parts[2]); err != nil {
|
||||
return fmt.Errorf("parsing column: %v", 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 := []Error{}
|
||||
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) ([]string, bool) {
|
||||
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 := "#nosec"
|
||||
noSecAlternativeTag, err := gosec.config.GetGlobal(NoSecAlternative)
|
||||
if err != nil {
|
||||
noSecAlternativeTag = noSecDefaultTag
|
||||
}
|
||||
|
||||
for _, group := range groups {
|
||||
|
||||
foundDefaultTag := strings.Contains(group.Text(), noSecDefaultTag)
|
||||
foundAlternativeTag := strings.Contains(group.Text(), noSecAlternativeTag)
|
||||
|
||||
if foundDefaultTag || foundAlternativeTag {
|
||||
gosec.stats.NumNosec++
|
||||
|
||||
// Pull out the specific rules that are listed to be ignored.
|
||||
re := regexp.MustCompile(`(G\d{3})`)
|
||||
matches := re.FindAllStringSubmatch(group.Text(), -1)
|
||||
|
||||
// If no specific rules were given, ignore everything.
|
||||
if len(matches) == 0 {
|
||||
return nil, true
|
||||
}
|
||||
|
||||
// Find the rule IDs to ignore.
|
||||
var ignores []string
|
||||
for _, v := range matches {
|
||||
ignores = append(ignores, v[1])
|
||||
}
|
||||
return ignores, false
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// If we've reached the end of this branch, pop off the ignores stack.
|
||||
if n == nil {
|
||||
if len(gosec.context.Ignores) > 0 {
|
||||
gosec.context.Ignores = gosec.context.Ignores[1:]
|
||||
}
|
||||
return gosec
|
||||
}
|
||||
|
||||
// Get any new rule exclusions.
|
||||
ignoredRules, ignoreAll := gosec.ignore(n)
|
||||
if ignoreAll {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Now create the union of exclusions.
|
||||
ignores := map[string]bool{}
|
||||
if len(gosec.context.Ignores) > 0 {
|
||||
for k, v := range gosec.context.Ignores[0] {
|
||||
ignores[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
for _, v := range ignoredRules {
|
||||
ignores[v] = true
|
||||
}
|
||||
|
||||
// Push the new set onto the stack.
|
||||
gosec.context.Ignores = append([]map[string]bool{ignores}, gosec.context.Ignores...)
|
||||
|
||||
// Track aliased and initialization imports
|
||||
gosec.context.Imports.TrackImport(n)
|
||||
|
||||
for _, rule := range gosec.ruleset.RegisteredFor(n) {
|
||||
if _, ok := ignores[rule.ID()]; ok {
|
||||
continue
|
||||
}
|
||||
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)
|
||||
}
|
||||
if issue != nil {
|
||||
gosec.issues = append(gosec.issues, issue)
|
||||
gosec.stats.NumFound++
|
||||
}
|
||||
}
|
||||
return gosec
|
||||
}
|
||||
|
||||
// Report returns the current issues discovered and the metrics about the scan
|
||||
func (gosec *Analyzer) Report() ([]*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, 0, 16)
|
||||
gosec.stats = &Metrics{}
|
||||
gosec.ruleset = NewRuleSet()
|
||||
}
|
109
vendor/github.com/securego/gosec/v2/call_list.go
generated
vendored
Normal file
109
vendor/github.com/securego/gosec/v2/call_list.go
generated
vendored
Normal file
|
@ -0,0 +1,109 @@
|
|||
//
|
||||
// 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
|
||||
}
|
||||
|
||||
// Use only explicit path (optionally strip vendor path prefix) to reduce conflicts
|
||||
path, ok := GetImportPath(selector, ctx)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
if stripVendor {
|
||||
if vendorIdx := strings.Index(path, vendorPath); vendorIdx >= 0 {
|
||||
path = path[vendorIdx+len(vendorPath):]
|
||||
}
|
||||
}
|
||||
if !c.Contains(path, 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)
|
||||
}
|
125
vendor/github.com/securego/gosec/v2/config.go
generated
vendored
Normal file
125
vendor/github.com/securego/gosec/v2/config.go
generated
vendored
Normal file
|
@ -0,0 +1,125 @@
|
|||
package gosec
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
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"
|
||||
// Audit global option which indicates that gosec runs in audit mode
|
||||
Audit GlobalOption = "audit"
|
||||
// NoSecAlternative global option alternative for #nosec directive
|
||||
NoSecAlternative GlobalOption = "#nosec"
|
||||
)
|
||||
|
||||
// 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 := ioutil.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
|
||||
}
|
136
vendor/github.com/securego/gosec/v2/cwe/data.go
generated
vendored
Normal file
136
vendor/github.com/securego/gosec/v2/cwe/data.go
generated
vendored
Normal file
|
@ -0,0 +1,136 @@
|
|||
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"
|
||||
)
|
||||
|
||||
var (
|
||||
data = map[string]*Weakness{}
|
||||
|
||||
weaknesses = []*Weakness{
|
||||
{
|
||||
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')",
|
||||
},
|
||||
{
|
||||
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",
|
||||
},
|
||||
{
|
||||
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",
|
||||
},
|
||||
{
|
||||
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')",
|
||||
},
|
||||
{
|
||||
ID: "242",
|
||||
Description: "The program calls a function that can never be guaranteed to work safely.",
|
||||
Name: "Use of Inherently Dangerous Function",
|
||||
},
|
||||
{
|
||||
ID: "276",
|
||||
Description: "During installation, installed file permissions are set to allow anyone to modify those files.",
|
||||
Name: "Incorrect Default Permissions",
|
||||
},
|
||||
{
|
||||
ID: "295",
|
||||
Description: "The software does not validate, or incorrectly validates, a certificate.",
|
||||
Name: "Improper Certificate Validation",
|
||||
},
|
||||
{
|
||||
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",
|
||||
},
|
||||
{
|
||||
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",
|
||||
},
|
||||
{
|
||||
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",
|
||||
},
|
||||
{
|
||||
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",
|
||||
},
|
||||
{
|
||||
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)",
|
||||
},
|
||||
{
|
||||
ID: "377",
|
||||
Description: "Creating and using insecure temporary files can leave application and system data vulnerable to attack.",
|
||||
Name: "Insecure Temporary File",
|
||||
},
|
||||
{
|
||||
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)",
|
||||
},
|
||||
{
|
||||
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",
|
||||
},
|
||||
{
|
||||
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')",
|
||||
},
|
||||
{
|
||||
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')",
|
||||
},
|
||||
{
|
||||
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",
|
||||
},
|
||||
{
|
||||
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')",
|
||||
},
|
||||
{
|
||||
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')",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
for _, weakness := range weaknesses {
|
||||
data[weakness.ID] = weakness
|
||||
}
|
||||
}
|
||||
|
||||
//Get Retrieves a CWE weakness by it's id
|
||||
func Get(id string) *Weakness {
|
||||
weakness, ok := data[id]
|
||||
if ok && weakness != nil {
|
||||
return weakness
|
||||
}
|
||||
return nil
|
||||
}
|
44
vendor/github.com/securego/gosec/v2/cwe/types.go
generated
vendored
Normal file
44
vendor/github.com/securego/gosec/v2/cwe/types.go
generated
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
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 {
|
||||
return fmt.Sprintf("%s-%s", Acronym, w.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(),
|
||||
})
|
||||
}
|
||||
|
||||
//InformationURI link to the published CWE PDF
|
||||
func InformationURI() string {
|
||||
return fmt.Sprintf("https://cwe.mitre.org/data/published/cwe_v%s.pdf/", Version)
|
||||
}
|
||||
|
||||
//DownloadURI link to the zipped XML of the CWE list
|
||||
func DownloadURI() string {
|
||||
return fmt.Sprintf("https://cwe.mitre.org/data/xml/cwec_v%s.xml.zip", Version)
|
||||
}
|
7
vendor/github.com/securego/gosec/v2/entrypoint.sh
generated
vendored
Normal file
7
vendor/github.com/securego/gosec/v2/entrypoint.sh
generated
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Expand the arguments into an array of strings. This is requires because the GitHub action
|
||||
# provides all arguments concatenated as a single string.
|
||||
ARGS=("$@")
|
||||
|
||||
/bin/gosec ${ARGS[*]}
|
33
vendor/github.com/securego/gosec/v2/errors.go
generated
vendored
Normal file
33
vendor/github.com/securego/gosec/v2/errors.go
generated
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
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,
|
||||
}
|
||||
}
|
||||
|
||||
// sortErros sorts the golang erros 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
|
||||
})
|
||||
}
|
||||
}
|
18
vendor/github.com/securego/gosec/v2/go.mod
generated
vendored
Normal file
18
vendor/github.com/securego/gosec/v2/go.mod
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
module github.com/securego/gosec/v2
|
||||
|
||||
require (
|
||||
github.com/google/uuid v1.1.1
|
||||
github.com/gookit/color v1.4.2
|
||||
github.com/lib/pq v1.9.0
|
||||
github.com/mozilla/tls-observatory v0.0.0-20210209181001-cf43108d6880
|
||||
github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354
|
||||
github.com/onsi/ginkgo v1.16.1
|
||||
github.com/onsi/gomega v1.11.0
|
||||
golang.org/x/mod v0.4.1 // indirect
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect
|
||||
golang.org/x/text v0.3.5
|
||||
golang.org/x/tools v0.1.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
||||
go 1.16
|
688
vendor/github.com/securego/gosec/v2/go.sum
generated
vendored
Normal file
688
vendor/github.com/securego/gosec/v2/go.sum
generated
vendored
Normal file
|
@ -0,0 +1,688 @@
|
|||
bitbucket.org/creachadair/shell v0.0.6/go.mod h1:8Qqi/cYk7vPnsOePHroKXDJYmb5x7ENhtiFtfZq8K+M=
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.60.0/go.mod h1:yw2G51M9IfRboUH61Us8GqCeF1PzPblB823Mn2q2eAU=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
||||
cloud.google.com/go/pubsub v1.5.0/go.mod h1:ZEwJccE3z93Z2HWvstpri00jOg7oO4UZDtKhwDwqF0w=
|
||||
cloud.google.com/go/spanner v1.7.0/go.mod h1:sd3K2gZ9Fd0vMPLXzeCrF6fq4i63Q7aTLW/lBIfBkIk=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||
github.com/Masterminds/sprig v2.15.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
|
||||
github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q=
|
||||
github.com/aokoli/goutils v1.0.1/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.36.30/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.0.14/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/fullstorydev/grpcurl v1.6.0/go.mod h1:ZQ+ayqbKMJNhzLmbpCiurTVlaK2M/3nqZCxaQ2Ze/sM=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-redis/redis v6.15.8+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg=
|
||||
github.com/google/certificate-transparency-go v1.1.1/go.mod h1:FDKqPvSXawb2ecErVRrD+nfy23RCzyl7eqVCEmlT1Zs=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200507031123-427632fa3b1c/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/trillian v1.3.11/go.mod h1:0tPraVHrSDkA3BO6vKX67zgLXs6SsOAbHEivX+9mPgw=
|
||||
github.com/google/uuid v0.0.0-20161128191214-064e2069ce9c/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/gookit/color v1.4.2 h1:tXy44JFSFkKnELV6WaMo/lLfu/meqITX3iAV52do7lk=
|
||||
github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ=
|
||||
github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU=
|
||||
github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo=
|
||||
github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.4/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jhump/protoreflect v1.6.1/go.mod h1:RZQ/lnuN+zqeRVpQigTwO6o0AJUkxbnSnpuG7toUTG4=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/juju/ratelimit v1.0.1/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/letsencrypt/pkcs11key/v4 v4.0.0/go.mod h1:EFUvBDay26dErnNb70Nd0/VW3tJiIbETBPTl9ATXQag=
|
||||
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.9.0 h1:L8nSXQQzAYByakOFMTwpjRoHsMJklur4Gi59b6VivR8=
|
||||
github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||
github.com/mozilla/scribe v0.0.0-20180711195314-fb71baf557c1/go.mod h1:FIczTrinKo8VaLxe6PWTPEXRXDIHz2QAwiaBaP5/4a8=
|
||||
github.com/mozilla/tls-observatory v0.0.0-20210209181001-cf43108d6880 h1:DXaIt8v4XXkFoVZXkG/PjLS5Rz3I2yoflOQrnuGgJeA=
|
||||
github.com/mozilla/tls-observatory v0.0.0-20210209181001-cf43108d6880/go.mod h1:FUqVoUPHSEdDR0MnFM3Dh8AU0pZHLXUD127SAJGER/s=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-proto-validators v0.0.0-20180403085117-0950a7990007/go.mod h1:m2XC9Qq0AlmmVksL6FktJCdTYyLk7V3fKyp0sl1yWQo=
|
||||
github.com/mwitkow/go-proto-validators v0.2.0/go.mod h1:ZfA1hW+UH/2ZHOWvQ3HnQaU0DtnpXu850MZiy+YUgcc=
|
||||
github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 h1:4kuARK6Y6FxaNu/BnU2OAaLF86eTVhP2hjTB6iMvItA=
|
||||
github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8=
|
||||
github.com/nishanths/predeclared v0.0.0-20190419143655-18a43bb90ffc/go.mod h1:62PewwiQTlm/7Rj+cxVYqZvDIUc+JjZq6GHAC1fsObQ=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.16.1 h1:foqVmeWDD6yYpK+Yz3fHyNIxFYNxswxqNFjSKe+vI54=
|
||||
github.com/onsi/ginkgo v1.16.1/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.11.0 h1:+CqWgvj0OZycCaqclBD1pxKHAU+tOkHmQIWvDHq2aug=
|
||||
github.com/onsi/gomega v1.11.0/go.mod h1:azGKhqFUon9Vuj0YmTfLSmx0FUwqXYSTl5re8lQLTUg=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/pseudomuto/protoc-gen-doc v1.3.2/go.mod h1:y5+P6n3iGrbKG+9O04V5ld71in3v/bX88wUwgt+U8EA=
|
||||
github.com/pseudomuto/protokit v0.2.0/go.mod h1:2PdH30hxVHsup8KpBTOXTBeMVhJZVio3Q8ViKSAXT0Q=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v0.0.0-20170130113145-4d4bfba8f1d1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/viki-org/dnscache v0.0.0-20130720023526-c70c1f23c5d8/go.mod h1:dniwbG03GafCjFohMDmz6Zc6oCuiqgH6tGNyXTkHzXE=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8=
|
||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=
|
||||
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
|
||||
github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||
go.etcd.io/etcd v0.0.0-20200513171258-e048e166ab9c/go.mod h1:xCI7ZzBfRuGgBXyXO6yfWfDmlWd35khcWpUa4L0xI/k=
|
||||
go.mozilla.org/mozlog v0.0.0-20170222151521-4bb13139d403/go.mod h1:jHoPAGnDrCy6kaI2tAze5Prf0Nr0w/oNkROt2lw3n3o=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||
golang.org/x/crypto v0.0.0-20180501155221-613d6eafa307/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44 h1:Bli41pIlzTzf3KEY06n+xnzK/BESIg2ze4Pgfh/aI8c=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200626171337-aa94e735be7f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200630154851-b2d8b0336632/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200706234117-b22de6825cf7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.10.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20181107211654-5fc9ac540362/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200626011028-ee7919e894b5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200707001353-8e8330bf89df/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.29.0/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.6/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
455
vendor/github.com/securego/gosec/v2/helpers.go
generated
vendored
Normal file
455
vendor/github.com/securego/gosec/v2/helpers.go
generated
vendored
Normal file
|
@ -0,0 +1,455 @@
|
|||
// (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 (
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/token"
|
||||
"go/types"
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 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) {
|
||||
importedName, found := GetImportedName(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
|
||||
}
|
||||
if packageName == importedName {
|
||||
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)
|
||||
}
|
||||
|
||||
// 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" {
|
||||
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, ctx *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
|
||||
}
|
||||
|
||||
// GetIdentStringValues return the string values of an Ident if they can be resolved
|
||||
func GetIdentStringValues(ident *ast.Ident) []string {
|
||||
values := []string{}
|
||||
obj := ident.Obj
|
||||
if obj != nil {
|
||||
switch decl := obj.Decl.(type) {
|
||||
case *ast.ValueSpec:
|
||||
for _, v := range decl.Values {
|
||||
value, err := GetString(v)
|
||||
if err == nil {
|
||||
values = append(values, value)
|
||||
}
|
||||
}
|
||||
case *ast.AssignStmt:
|
||||
for _, v := range decl.Rhs {
|
||||
value, err := GetString(v)
|
||||
if err == nil {
|
||||
values = append(values, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
// GetBinaryExprOperands returns all operands of a binary expression by traversing
|
||||
// the expression tree
|
||||
func GetBinaryExprOperands(be *ast.BinaryExpr) []ast.Node {
|
||||
var traverse func(be *ast.BinaryExpr)
|
||||
result := []ast.Node{}
|
||||
traverse = func(be *ast.BinaryExpr) {
|
||||
if lhs, ok := be.X.(*ast.BinaryExpr); ok {
|
||||
traverse(lhs)
|
||||
} else {
|
||||
result = append(result, be.X)
|
||||
}
|
||||
if rhs, ok := be.Y.(*ast.BinaryExpr); ok {
|
||||
traverse(rhs)
|
||||
} else {
|
||||
result = append(result, be.Y)
|
||||
}
|
||||
}
|
||||
traverse(be)
|
||||
return result
|
||||
}
|
||||
|
||||
// GetImportedName returns the name used for the package within the
|
||||
// code. It will resolve aliases and ignores initialization only imports.
|
||||
func GetImportedName(path string, ctx *Context) (string, bool) {
|
||||
importName, imported := ctx.Imports.Imported[path]
|
||||
if !imported {
|
||||
return "", false
|
||||
}
|
||||
|
||||
if _, initonly := ctx.Imports.InitOnly[path]; initonly {
|
||||
return "", false
|
||||
}
|
||||
|
||||
if alias, ok := ctx.Imports.Aliased[path]; ok {
|
||||
importName = alias
|
||||
}
|
||||
return importName, true
|
||||
}
|
||||
|
||||
// GetImportPath resolves the full import path of an identifier based on
|
||||
// the imports in the current context.
|
||||
func GetImportPath(name string, ctx *Context) (string, bool) {
|
||||
for path := range ctx.Imports.Imported {
|
||||
if imported, ok := GetImportedName(path, ctx); ok && imported == 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 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(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([\\/])?`, 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) {
|
||||
if strings.HasSuffix(root, "...") {
|
||||
root = root[0 : len(root)-3]
|
||||
}
|
||||
return filepath.Abs(root)
|
||||
}
|
75
vendor/github.com/securego/gosec/v2/import_tracker.go
generated
vendored
Normal file
75
vendor/github.com/securego/gosec/v2/import_tracker.go
generated
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
// 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"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 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 map[string]string
|
||||
Aliased map[string]string
|
||||
InitOnly map[string]bool
|
||||
}
|
||||
|
||||
// NewImportTracker creates an empty Import tracker instance
|
||||
func NewImportTracker() *ImportTracker {
|
||||
return &ImportTracker{
|
||||
make(map[string]string),
|
||||
make(map[string]string),
|
||||
make(map[string]bool),
|
||||
}
|
||||
}
|
||||
|
||||
// TrackFile track all the imports used by the supplied file
|
||||
func (t *ImportTracker) TrackFile(file *ast.File) {
|
||||
for _, imp := range file.Imports {
|
||||
path := strings.Trim(imp.Path.Value, `"`)
|
||||
parts := strings.Split(path, "/")
|
||||
if len(parts) > 0 {
|
||||
name := parts[len(parts)-1]
|
||||
t.Imported[path] = name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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()] = pkg.Name()
|
||||
}
|
||||
}
|
||||
|
||||
// TrackImport tracks imports and handles the 'unsafe' import
|
||||
func (t *ImportTracker) TrackImport(n ast.Node) {
|
||||
if imported, ok := n.(*ast.ImportSpec); ok {
|
||||
path := strings.Trim(imported.Path.Value, `"`)
|
||||
if imported.Name != nil {
|
||||
if imported.Name.Name == "_" {
|
||||
// Initialization only import
|
||||
t.InitOnly[path] = true
|
||||
} else {
|
||||
// Aliased import
|
||||
t.Aliased[path] = imported.Name.Name
|
||||
}
|
||||
}
|
||||
if path == "unsafe" {
|
||||
t.Imported[path] = path
|
||||
}
|
||||
}
|
||||
}
|
372
vendor/github.com/securego/gosec/v2/install.sh
generated
vendored
Normal file
372
vendor/github.com/securego/gosec/v2/install.sh
generated
vendored
Normal file
|
@ -0,0 +1,372 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
# Code generated by godownloader on 2020-03-02T13:35:13Z. DO NOT EDIT.
|
||||
#
|
||||
|
||||
usage() {
|
||||
this=$1
|
||||
cat <<EOF
|
||||
$this: download go binaries for securego/gosec
|
||||
|
||||
Usage: $this [-b] bindir [-d] [tag]
|
||||
-b sets bindir or installation directory, Defaults to ./bin
|
||||
-d turns on debug logging
|
||||
[tag] is a tag from
|
||||
https://github.com/securego/gosec/releases
|
||||
If tag is missing, then the latest will be used.
|
||||
|
||||
Generated by godownloader
|
||||
https://github.com/goreleaser/godownloader
|
||||
|
||||
EOF
|
||||
exit 2
|
||||
}
|
||||
|
||||
parse_args() {
|
||||
#BINDIR is ./bin unless set be ENV
|
||||
# over-ridden by flag below
|
||||
|
||||
BINDIR=${BINDIR:-./bin}
|
||||
while getopts "b:dh?x" arg; do
|
||||
case "$arg" in
|
||||
b) BINDIR="$OPTARG" ;;
|
||||
d) log_set_priority 10 ;;
|
||||
h | \?) usage "$0" ;;
|
||||
x) set -x ;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND - 1))
|
||||
TAG=$1
|
||||
}
|
||||
# this function wraps all the destructive operations
|
||||
# if a curl|bash cuts off the end of the script due to
|
||||
# network, either nothing will happen or will syntax error
|
||||
# out preventing half-done work
|
||||
execute() {
|
||||
tmpdir=$(mktemp -d)
|
||||
log_debug "downloading files into ${tmpdir}"
|
||||
http_download "${tmpdir}/${TARBALL}" "${TARBALL_URL}"
|
||||
http_download "${tmpdir}/${CHECKSUM}" "${CHECKSUM_URL}"
|
||||
hash_sha256_verify "${tmpdir}/${TARBALL}" "${tmpdir}/${CHECKSUM}"
|
||||
srcdir="${tmpdir}"
|
||||
(cd "${tmpdir}" && untar "${TARBALL}")
|
||||
test ! -d "${BINDIR}" && install -d "${BINDIR}"
|
||||
for binexe in $BINARIES; do
|
||||
if [ "$OS" = "windows" ]; then
|
||||
binexe="${binexe}.exe"
|
||||
fi
|
||||
install "${srcdir}/${binexe}" "${BINDIR}/"
|
||||
log_info "installed ${BINDIR}/${binexe}"
|
||||
done
|
||||
rm -rf "${tmpdir}"
|
||||
}
|
||||
get_binaries() {
|
||||
case "$PLATFORM" in
|
||||
darwin/amd64) BINARIES="gosec" ;;
|
||||
linux/amd64) BINARIES="gosec" ;;
|
||||
windows/amd64) BINARIES="gosec" ;;
|
||||
*)
|
||||
log_crit "platform $PLATFORM is not supported. Make sure this script is up-to-date and file request at https://github.com/${PREFIX}/issues/new"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
tag_to_version() {
|
||||
if [ -z "${TAG}" ]; then
|
||||
log_info "checking GitHub for latest tag"
|
||||
else
|
||||
log_info "checking GitHub for tag '${TAG}'"
|
||||
fi
|
||||
REALTAG=$(github_release "$OWNER/$REPO" "${TAG}") && true
|
||||
if test -z "$REALTAG"; then
|
||||
log_crit "unable to find '${TAG}' - use 'latest' or see https://github.com/${PREFIX}/releases for details"
|
||||
exit 1
|
||||
fi
|
||||
# if version starts with 'v', remove it
|
||||
TAG="$REALTAG"
|
||||
VERSION=${TAG#v}
|
||||
}
|
||||
adjust_format() {
|
||||
# change format (tar.gz or zip) based on OS
|
||||
true
|
||||
}
|
||||
adjust_os() {
|
||||
# adjust archive name based on OS
|
||||
true
|
||||
}
|
||||
adjust_arch() {
|
||||
# adjust archive name based on ARCH
|
||||
true
|
||||
}
|
||||
|
||||
cat /dev/null <<EOF
|
||||
------------------------------------------------------------------------
|
||||
https://github.com/client9/shlib - portable posix shell functions
|
||||
Public domain - http://unlicense.org
|
||||
https://github.com/client9/shlib/blob/master/LICENSE.md
|
||||
but credit (and pull requests) appreciated.
|
||||
------------------------------------------------------------------------
|
||||
EOF
|
||||
is_command() {
|
||||
command -v "$1" >/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
|
||||
test -z "$version" && version="latest"
|
||||
giturl="https://github.com/${owner_repo}/releases/${version}"
|
||||
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 <<EOF
|
||||
------------------------------------------------------------------------
|
||||
End of functions from https://github.com/client9/shlib
|
||||
------------------------------------------------------------------------
|
||||
EOF
|
||||
|
||||
PROJECT_NAME="gosec"
|
||||
OWNER=securego
|
||||
REPO="gosec"
|
||||
BINARY=gosec
|
||||
FORMAT=tar.gz
|
||||
OS=$(uname_os)
|
||||
ARCH=$(uname_arch)
|
||||
PREFIX="$OWNER/$REPO"
|
||||
|
||||
# use in logging routines
|
||||
log_prefix() {
|
||||
echo "$PREFIX"
|
||||
}
|
||||
PLATFORM="${OS}/${ARCH}"
|
||||
GITHUB_DOWNLOAD=https://github.com/${OWNER}/${REPO}/releases/download
|
||||
|
||||
uname_os_check "$OS"
|
||||
uname_arch_check "$ARCH"
|
||||
|
||||
parse_args "$@"
|
||||
|
||||
get_binaries
|
||||
|
||||
tag_to_version
|
||||
|
||||
adjust_format
|
||||
|
||||
adjust_os
|
||||
|
||||
adjust_arch
|
||||
|
||||
log_info "found version: ${VERSION} for ${TAG}/${OS}/${ARCH}"
|
||||
|
||||
NAME=${PROJECT_NAME}_${VERSION}_${OS}_${ARCH}
|
||||
TARBALL=${NAME}.${FORMAT}
|
||||
TARBALL_URL=${GITHUB_DOWNLOAD}/${TAG}/${TARBALL}
|
||||
CHECKSUM=${PROJECT_NAME}_${VERSION}_checksums.txt
|
||||
CHECKSUM_URL=${GITHUB_DOWNLOAD}/${TAG}/${CHECKSUM}
|
||||
|
||||
|
||||
execute
|
200
vendor/github.com/securego/gosec/v2/issue.go
generated
vendored
Normal file
200
vendor/github.com/securego/gosec/v2/issue.go
generated
vendored
Normal file
|
@ -0,0 +1,200 @@
|
|||
// (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 (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/securego/gosec/v2/cwe"
|
||||
"go/ast"
|
||||
"go/token"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Score type used by severity and confidence values
|
||||
type Score int
|
||||
|
||||
const (
|
||||
// Low severity or confidence
|
||||
Low Score = iota
|
||||
// Medium severity or confidence
|
||||
Medium
|
||||
// High severity or confidence
|
||||
High
|
||||
)
|
||||
|
||||
// SnippetOffset defines the number of lines captured before
|
||||
// the beginning and after the end of a code snippet
|
||||
const SnippetOffset = 1
|
||||
|
||||
// GetCweByRule retrieves a cwe weakness for a given RuleID
|
||||
func GetCweByRule(id string) *cwe.Weakness {
|
||||
cweID, ok := ruleToCWE[id]
|
||||
if ok && cweID != "" {
|
||||
return cwe.Get(cweID)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ruleToCWE maps gosec rules to CWEs
|
||||
var ruleToCWE = map[string]string{
|
||||
"G101": "798",
|
||||
"G102": "200",
|
||||
"G103": "242",
|
||||
"G104": "703",
|
||||
"G106": "322",
|
||||
"G107": "88",
|
||||
"G108": "200",
|
||||
"G109": "190",
|
||||
"G110": "409",
|
||||
"G201": "89",
|
||||
"G202": "89",
|
||||
"G203": "79",
|
||||
"G204": "78",
|
||||
"G301": "276",
|
||||
"G302": "276",
|
||||
"G303": "377",
|
||||
"G304": "22",
|
||||
"G305": "22",
|
||||
"G306": "276",
|
||||
"G307": "703",
|
||||
"G401": "326",
|
||||
"G402": "295",
|
||||
"G403": "310",
|
||||
"G404": "338",
|
||||
"G501": "327",
|
||||
"G502": "327",
|
||||
"G503": "327",
|
||||
"G504": "327",
|
||||
"G505": "327",
|
||||
"G601": "118",
|
||||
}
|
||||
|
||||
// Issue is returned by a gosec rule if it discovers an issue with the scanned code.
|
||||
type Issue struct {
|
||||
Severity Score `json:"severity"` // issue severity (how problematic it is)
|
||||
Confidence Score `json:"confidence"` // issue confidence (how sure we are we found it)
|
||||
Cwe *cwe.Weakness `json:"cwe"` // Cwe associated with RuleID
|
||||
RuleID string `json:"rule_id"` // Human readable explanation
|
||||
What string `json:"details"` // Human readable explanation
|
||||
File string `json:"file"` // File name we found it in
|
||||
Code string `json:"code"` // Impacted code line
|
||||
Line string `json:"line"` // Line number in file
|
||||
Col string `json:"column"` // Column number in line
|
||||
}
|
||||
|
||||
// FileLocation point out the file path and line number in file
|
||||
func (i Issue) FileLocation() string {
|
||||
return fmt.Sprintf("%s:%s", i.File, i.Line)
|
||||
}
|
||||
|
||||
// MetaData is embedded in all gosec rules. The Severity, Confidence and What message
|
||||
// will be passed through to reported issues.
|
||||
type MetaData struct {
|
||||
ID string
|
||||
Severity Score
|
||||
Confidence Score
|
||||
What string
|
||||
}
|
||||
|
||||
// MarshalJSON is used convert a Score object into a JSON representation
|
||||
func (c Score) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(c.String())
|
||||
}
|
||||
|
||||
// String converts a Score into a string
|
||||
func (c Score) String() string {
|
||||
switch c {
|
||||
case High:
|
||||
return "HIGH"
|
||||
case Medium:
|
||||
return "MEDIUM"
|
||||
case Low:
|
||||
return "LOW"
|
||||
}
|
||||
return "UNDEFINED"
|
||||
}
|
||||
|
||||
// codeSnippet extracts a code snippet based on the ast reference
|
||||
func codeSnippet(file *os.File, start int64, end int64, n ast.Node) (string, error) {
|
||||
if n == nil {
|
||||
return "", fmt.Errorf("invalid AST node provided")
|
||||
}
|
||||
var pos int64
|
||||
var buf bytes.Buffer
|
||||
scanner := bufio.NewScanner(file)
|
||||
scanner.Split(bufio.ScanLines)
|
||||
for scanner.Scan() {
|
||||
pos++
|
||||
if pos > end {
|
||||
break
|
||||
} else if pos >= start && pos <= end {
|
||||
code := fmt.Sprintf("%d: %s\n", pos, scanner.Text())
|
||||
buf.WriteString(code)
|
||||
}
|
||||
}
|
||||
return buf.String(), nil
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// NewIssue creates a new Issue
|
||||
func NewIssue(ctx *Context, node ast.Node, ruleID, desc string, severity Score, confidence Score) *Issue {
|
||||
fobj := ctx.FileSet.File(node.Pos())
|
||||
name := fobj.Name()
|
||||
start, end := fobj.Line(node.Pos()), fobj.Line(node.End())
|
||||
line := strconv.Itoa(start)
|
||||
if start != end {
|
||||
line = fmt.Sprintf("%d-%d", start, end)
|
||||
}
|
||||
col := strconv.Itoa(fobj.Position(node.Pos()).Column)
|
||||
|
||||
var code string
|
||||
if file, err := os.Open(fobj.Name()); err == nil {
|
||||
defer file.Close() // #nosec
|
||||
s := codeSnippetStartLine(node, fobj)
|
||||
e := codeSnippetEndLine(node, fobj)
|
||||
code, err = codeSnippet(file, s, e, node)
|
||||
if err != nil {
|
||||
code = err.Error()
|
||||
}
|
||||
}
|
||||
|
||||
return &Issue{
|
||||
File: name,
|
||||
Line: line,
|
||||
Col: col,
|
||||
RuleID: ruleID,
|
||||
What: desc,
|
||||
Confidence: confidence,
|
||||
Severity: severity,
|
||||
Code: code,
|
||||
Cwe: GetCweByRule(ruleID),
|
||||
}
|
||||
}
|
7
vendor/github.com/securego/gosec/v2/renovate.json
generated
vendored
Normal file
7
vendor/github.com/securego/gosec/v2/renovate.json
generated
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"extends": [
|
||||
"config:semverAllMonthly",
|
||||
":enableVulnerabilityAlertsWithLabel(vulnerablity)",
|
||||
":docker"
|
||||
]
|
||||
}
|
24
vendor/github.com/securego/gosec/v2/report.go
generated
vendored
Normal file
24
vendor/github.com/securego/gosec/v2/report.go
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
package gosec
|
||||
|
||||
// ReportInfo this is report information
|
||||
type ReportInfo struct {
|
||||
Errors map[string][]Error `json:"Golang errors"`
|
||||
Issues []*Issue
|
||||
Stats *Metrics
|
||||
GosecVersion string
|
||||
}
|
||||
|
||||
// NewReportInfo instantiate a ReportInfo
|
||||
func NewReportInfo(issues []*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
|
||||
}
|
95
vendor/github.com/securego/gosec/v2/resolve.go
generated
vendored
Normal file
95
vendor/github.com/securego/gosec/v2/resolve.go
generated
vendored
Normal file
|
@ -0,0 +1,95 @@
|
|||
// (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(n *ast.CallExpr, c *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
|
||||
}
|
59
vendor/github.com/securego/gosec/v2/rule.go
generated
vendored
Normal file
59
vendor/github.com/securego/gosec/v2/rule.go
generated
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
// 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"
|
||||
)
|
||||
|
||||
// The Rule interface used by all rules supported by gosec.
|
||||
type Rule interface {
|
||||
ID() string
|
||||
Match(ast.Node, *Context) (*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 maps lists of rules to the type of AST node they should be run on.
|
||||
// The analyzer will only invoke rules contained in the list associated with the
|
||||
// type of AST node it is currently visiting.
|
||||
type RuleSet map[reflect.Type][]Rule
|
||||
|
||||
// NewRuleSet constructs a new RuleSet
|
||||
func NewRuleSet() RuleSet {
|
||||
return make(RuleSet)
|
||||
}
|
||||
|
||||
// Register adds a trigger for the supplied rule for the the
|
||||
// specified ast nodes.
|
||||
func (r RuleSet) Register(rule Rule, nodes ...ast.Node) {
|
||||
for _, n := range nodes {
|
||||
t := reflect.TypeOf(n)
|
||||
if rules, ok := r[t]; ok {
|
||||
r[t] = append(rules, rule)
|
||||
} else {
|
||||
r[t] = []Rule{rule}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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[reflect.TypeOf(n)]; found {
|
||||
return rules
|
||||
}
|
||||
return []Rule{}
|
||||
}
|
65
vendor/github.com/securego/gosec/v2/rules/archive.go
generated
vendored
Normal file
65
vendor/github.com/securego/gosec/v2/rules/archive.go
generated
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
package rules
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
"go/types"
|
||||
|
||||
"github.com/securego/gosec/v2"
|
||||
)
|
||||
|
||||
type archive struct {
|
||||
gosec.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) (*gosec.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 gosec.NewIssue(c, 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, conf 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: gosec.MetaData{
|
||||
ID: id,
|
||||
Severity: gosec.Medium,
|
||||
Confidence: gosec.High,
|
||||
What: "File traversal when extracting zip/tar archive",
|
||||
},
|
||||
}, []ast.Node{(*ast.CallExpr)(nil)}
|
||||
}
|
69
vendor/github.com/securego/gosec/v2/rules/bad_defer.go
generated
vendored
Normal file
69
vendor/github.com/securego/gosec/v2/rules/bad_defer.go
generated
vendored
Normal file
|
@ -0,0 +1,69 @@
|
|||
package rules
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"strings"
|
||||
|
||||
"github.com/securego/gosec/v2"
|
||||
)
|
||||
|
||||
type deferType struct {
|
||||
typ string
|
||||
methods []string
|
||||
}
|
||||
|
||||
type badDefer struct {
|
||||
gosec.MetaData
|
||||
types []deferType
|
||||
}
|
||||
|
||||
func (r *badDefer) ID() string {
|
||||
return r.MetaData.ID
|
||||
}
|
||||
|
||||
func normalize(typ string) string {
|
||||
return strings.TrimPrefix(typ, "*")
|
||||
}
|
||||
|
||||
func contains(methods []string, method string) bool {
|
||||
for _, m := range methods {
|
||||
if m == method {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (r *badDefer) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) {
|
||||
if deferStmt, ok := n.(*ast.DeferStmt); ok {
|
||||
for _, deferTyp := range r.types {
|
||||
if typ, method, err := gosec.GetCallInfo(deferStmt.Call, c); err == nil {
|
||||
if normalize(typ) == deferTyp.typ && contains(deferTyp.methods, method) {
|
||||
return gosec.NewIssue(c, n, r.ID(), fmt.Sprintf(r.What, method, typ), r.Severity, r.Confidence), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// NewDeferredClosing detects unsafe defer of error returning methods
|
||||
func NewDeferredClosing(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
return &badDefer{
|
||||
types: []deferType{
|
||||
{
|
||||
typ: "os.File",
|
||||
methods: []string{"Close"},
|
||||
},
|
||||
},
|
||||
MetaData: gosec.MetaData{
|
||||
ID: id,
|
||||
Severity: gosec.Medium,
|
||||
Confidence: gosec.High,
|
||||
What: "Deferring unsafe method %q on type %q",
|
||||
},
|
||||
}, []ast.Node{(*ast.DeferStmt)(nil)}
|
||||
}
|
83
vendor/github.com/securego/gosec/v2/rules/bind.go
generated
vendored
Normal file
83
vendor/github.com/securego/gosec/v2/rules/bind.go
generated
vendored
Normal file
|
@ -0,0 +1,83 @@
|
|||
// (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"
|
||||
)
|
||||
|
||||
// Looks for net.Listen("0.0.0.0") or net.Listen(":8080")
|
||||
type bindsToAllNetworkInterfaces struct {
|
||||
gosec.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) (*gosec.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 gosec.NewIssue(c, 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 gosec.NewIssue(c, 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 gosec.NewIssue(c, 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, conf 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: gosec.MetaData{
|
||||
ID: id,
|
||||
Severity: gosec.Medium,
|
||||
Confidence: gosec.High,
|
||||
What: "Binds to all network interfaces",
|
||||
},
|
||||
}, []ast.Node{(*ast.CallExpr)(nil)}
|
||||
}
|
94
vendor/github.com/securego/gosec/v2/rules/blocklist.go
generated
vendored
Normal file
94
vendor/github.com/securego/gosec/v2/rules/blocklist.go
generated
vendored
Normal file
|
@ -0,0 +1,94 @@
|
|||
// (c) Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package rules
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
"strings"
|
||||
|
||||
"github.com/securego/gosec/v2"
|
||||
)
|
||||
|
||||
type blocklistedImport struct {
|
||||
gosec.MetaData
|
||||
Blocklisted map[string]string
|
||||
}
|
||||
|
||||
func unquote(original string) string {
|
||||
copy := strings.TrimSpace(original)
|
||||
copy = strings.TrimLeft(copy, `"`)
|
||||
return strings.TrimRight(copy, `"`)
|
||||
}
|
||||
|
||||
func (r *blocklistedImport) ID() string {
|
||||
return r.MetaData.ID
|
||||
}
|
||||
|
||||
func (r *blocklistedImport) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) {
|
||||
if node, ok := n.(*ast.ImportSpec); ok {
|
||||
if description, ok := r.Blocklisted[unquote(node.Path.Value)]; ok {
|
||||
return gosec.NewIssue(c, node, r.ID(), description, r.Severity, r.Confidence), nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// NewBlocklistedImports reports when a blocklisted import is being used.
|
||||
// Typically when a deprecated technology is being used.
|
||||
func NewBlocklistedImports(id string, conf gosec.Config, blocklist map[string]string) (gosec.Rule, []ast.Node) {
|
||||
return &blocklistedImport{
|
||||
MetaData: gosec.MetaData{
|
||||
ID: id,
|
||||
Severity: gosec.Medium,
|
||||
Confidence: gosec.High,
|
||||
},
|
||||
Blocklisted: blocklist,
|
||||
}, []ast.Node{(*ast.ImportSpec)(nil)}
|
||||
}
|
||||
|
||||
// NewBlocklistedImportMD5 fails if MD5 is imported
|
||||
func NewBlocklistedImportMD5(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
return NewBlocklistedImports(id, conf, map[string]string{
|
||||
"crypto/md5": "Blocklisted import crypto/md5: weak cryptographic primitive",
|
||||
})
|
||||
}
|
||||
|
||||
// NewBlocklistedImportDES fails if DES is imported
|
||||
func NewBlocklistedImportDES(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
return NewBlocklistedImports(id, conf, map[string]string{
|
||||
"crypto/des": "Blocklisted import crypto/des: weak cryptographic primitive",
|
||||
})
|
||||
}
|
||||
|
||||
// NewBlocklistedImportRC4 fails if DES is imported
|
||||
func NewBlocklistedImportRC4(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
return NewBlocklistedImports(id, conf, map[string]string{
|
||||
"crypto/rc4": "Blocklisted import crypto/rc4: weak cryptographic primitive",
|
||||
})
|
||||
}
|
||||
|
||||
// NewBlocklistedImportCGI fails if CGI is imported
|
||||
func NewBlocklistedImportCGI(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
return NewBlocklistedImports(id, conf, map[string]string{
|
||||
"net/http/cgi": "Blocklisted import net/http/cgi: Go versions < 1.6.3 are vulnerable to Httpoxy attack: (CVE-2016-5386)",
|
||||
})
|
||||
}
|
||||
|
||||
// NewBlocklistedImportSHA1 fails if SHA1 is imported
|
||||
func NewBlocklistedImportSHA1(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
return NewBlocklistedImports(id, conf, map[string]string{
|
||||
"crypto/sha1": "Blocklisted import crypto/sha1: weak cryptographic primitive",
|
||||
})
|
||||
}
|
110
vendor/github.com/securego/gosec/v2/rules/decompression-bomb.go
generated
vendored
Normal file
110
vendor/github.com/securego/gosec/v2/rules/decompression-bomb.go
generated
vendored
Normal file
|
@ -0,0 +1,110 @@
|
|||
// (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"
|
||||
)
|
||||
|
||||
type decompressionBombCheck struct {
|
||||
gosec.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) (*gosec.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 gosec.NewIssue(ctx, 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, conf 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: gosec.MetaData{
|
||||
ID: id,
|
||||
Severity: gosec.Medium,
|
||||
Confidence: gosec.Medium,
|
||||
What: "Potential DoS vulnerability via decompression bomb",
|
||||
},
|
||||
readerCalls: readerCalls,
|
||||
copyCalls: copyCalls,
|
||||
}, []ast.Node{(*ast.FuncDecl)(nil), (*ast.AssignStmt)(nil), (*ast.CallExpr)(nil)}
|
||||
}
|
119
vendor/github.com/securego/gosec/v2/rules/errors.go
generated
vendored
Normal file
119
vendor/github.com/securego/gosec/v2/rules/errors.go
generated
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
// (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"
|
||||
)
|
||||
|
||||
type noErrorCheck struct {
|
||||
gosec.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) (*gosec.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 gosec.NewIssue(ctx, 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 gosec.NewIssue(ctx, 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")
|
||||
|
||||
if configured, ok := conf["G104"]; 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: gosec.MetaData{
|
||||
ID: id,
|
||||
Severity: gosec.Low,
|
||||
Confidence: gosec.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
|
||||
}
|
113
vendor/github.com/securego/gosec/v2/rules/fileperms.go
generated
vendored
Normal file
113
vendor/github.com/securego/gosec/v2/rules/fileperms.go
generated
vendored
Normal file
|
@ -0,0 +1,113 @@
|
|||
// (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"
|
||||
)
|
||||
|
||||
type filePermissions struct {
|
||||
gosec.MetaData
|
||||
mode int64
|
||||
pkgs []string
|
||||
calls []string
|
||||
}
|
||||
|
||||
func (r *filePermissions) ID() string {
|
||||
return r.MetaData.ID
|
||||
}
|
||||
|
||||
func getConfiguredMode(conf map[string]interface{}, configKey string, defaultMode int64) int64 {
|
||||
var 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 (r *filePermissions) Match(n ast.Node, c *gosec.Context) (*gosec.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 && mode > r.mode {
|
||||
return gosec.NewIssue(c, n, r.ID(), r.What, r.Severity, r.Confidence), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// 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, "G306", 0600)
|
||||
return &filePermissions{
|
||||
mode: mode,
|
||||
pkgs: []string{"io/ioutil", "os"},
|
||||
calls: []string{"WriteFile"},
|
||||
MetaData: gosec.MetaData{
|
||||
ID: id,
|
||||
Severity: gosec.Medium,
|
||||
Confidence: gosec.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, "G302", 0600)
|
||||
return &filePermissions{
|
||||
mode: mode,
|
||||
pkgs: []string{"os"},
|
||||
calls: []string{"OpenFile", "Chmod"},
|
||||
MetaData: gosec.MetaData{
|
||||
ID: id,
|
||||
Severity: gosec.Medium,
|
||||
Confidence: gosec.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, "G301", 0750)
|
||||
return &filePermissions{
|
||||
mode: mode,
|
||||
pkgs: []string{"os"},
|
||||
calls: []string{"Mkdir", "MkdirAll"},
|
||||
MetaData: gosec.MetaData{
|
||||
ID: id,
|
||||
Severity: gosec.Medium,
|
||||
Confidence: gosec.High,
|
||||
What: fmt.Sprintf("Expect directory permissions to be %#o or less", mode),
|
||||
},
|
||||
}, []ast.Node{(*ast.CallExpr)(nil)}
|
||||
}
|
173
vendor/github.com/securego/gosec/v2/rules/hardcoded_credentials.go
generated
vendored
Normal file
173
vendor/github.com/securego/gosec/v2/rules/hardcoded_credentials.go
generated
vendored
Normal file
|
@ -0,0 +1,173 @@
|
|||
// (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/token"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
zxcvbn "github.com/nbutton23/zxcvbn-go"
|
||||
"github.com/securego/gosec/v2"
|
||||
)
|
||||
|
||||
type credentials struct {
|
||||
gosec.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) Match(n ast.Node, ctx *gosec.Context) (*gosec.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) (*gosec.Issue, error) {
|
||||
for _, i := range assign.Lhs {
|
||||
if ident, ok := i.(*ast.Ident); ok {
|
||||
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 gosec.NewIssue(ctx, assign, r.ID(), r.What, r.Severity, r.Confidence), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (r *credentials) matchValueSpec(valueSpec *ast.ValueSpec, ctx *gosec.Context) (*gosec.Issue, error) {
|
||||
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 gosec.NewIssue(ctx, valueSpec, r.ID(), r.What, r.Severity, r.Confidence), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (r *credentials) matchEqualityCheck(binaryExpr *ast.BinaryExpr, ctx *gosec.Context) (*gosec.Issue, error) {
|
||||
if binaryExpr.Op == token.EQL || binaryExpr.Op == token.NEQ {
|
||||
if ident, ok := binaryExpr.X.(*ast.Ident); ok {
|
||||
if r.pattern.MatchString(ident.Name) {
|
||||
if val, err := gosec.GetString(binaryExpr.Y); err == nil {
|
||||
if r.ignoreEntropy || (!r.ignoreEntropy && r.isHighEntropyString(val)) {
|
||||
return gosec.NewIssue(ctx, binaryExpr, r.ID(), r.What, 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`
|
||||
entropyThreshold := 80.0
|
||||
perCharThreshold := 3.0
|
||||
ignoreEntropy := false
|
||||
var truncateString = 16
|
||||
if val, ok := conf["G101"]; 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: gosec.MetaData{
|
||||
ID: id,
|
||||
What: "Potential hardcoded credentials",
|
||||
Confidence: gosec.Low,
|
||||
Severity: gosec.High,
|
||||
},
|
||||
}, []ast.Node{(*ast.AssignStmt)(nil), (*ast.ValueSpec)(nil), (*ast.BinaryExpr)(nil)}
|
||||
}
|
119
vendor/github.com/securego/gosec/v2/rules/implicit_aliasing.go
generated
vendored
Normal file
119
vendor/github.com/securego/gosec/v2/rules/implicit_aliasing.go
generated
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
package rules
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
"go/token"
|
||||
|
||||
"github.com/securego/gosec/v2"
|
||||
)
|
||||
|
||||
type implicitAliasing struct {
|
||||
gosec.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 (r *implicitAliasing) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) {
|
||||
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 ident, ok := node.X.(*ast.Ident); ok && node.Op.String() == "&" {
|
||||
if _, contains := r.aliases[ident.Obj]; contains {
|
||||
return gosec.NewIssue(c, 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, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
return &implicitAliasing{
|
||||
aliases: make(map[*ast.Object]struct{}),
|
||||
rightBrace: token.NoPos,
|
||||
acceptableAlias: make([]*ast.UnaryExpr, 0),
|
||||
MetaData: gosec.MetaData{
|
||||
ID: id,
|
||||
Severity: gosec.Medium,
|
||||
Confidence: gosec.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.
|
||||
*/
|
89
vendor/github.com/securego/gosec/v2/rules/integer_overflow.go
generated
vendored
Normal file
89
vendor/github.com/securego/gosec/v2/rules/integer_overflow.go
generated
vendored
Normal file
|
@ -0,0 +1,89 @@
|
|||
// (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"
|
||||
)
|
||||
|
||||
type integerOverflowCheck struct {
|
||||
gosec.MetaData
|
||||
calls gosec.CallList
|
||||
}
|
||||
|
||||
func (i *integerOverflowCheck) ID() string {
|
||||
return i.MetaData.ID
|
||||
}
|
||||
|
||||
func (i *integerOverflowCheck) Match(node ast.Node, ctx *gosec.Context) (*gosec.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 n, ok := atoiVarObj[idt.Obj]; ok {
|
||||
// Detect int32(v) and int16(v)
|
||||
return gosec.NewIssue(ctx, 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, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
calls := gosec.NewCallList()
|
||||
calls.Add("strconv", "Atoi")
|
||||
return &integerOverflowCheck{
|
||||
MetaData: gosec.MetaData{
|
||||
ID: id,
|
||||
Severity: gosec.High,
|
||||
Confidence: gosec.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)}
|
||||
}
|
42
vendor/github.com/securego/gosec/v2/rules/pprof.go
generated
vendored
Normal file
42
vendor/github.com/securego/gosec/v2/rules/pprof.go
generated
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
package rules
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
|
||||
"github.com/securego/gosec/v2"
|
||||
)
|
||||
|
||||
type pprofCheck struct {
|
||||
gosec.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) (*gosec.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 gosec.NewIssue(c, 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, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
return &pprofCheck{
|
||||
MetaData: gosec.MetaData{
|
||||
ID: id,
|
||||
Severity: gosec.High,
|
||||
Confidence: gosec.High,
|
||||
What: "Profiling endpoint is automatically exposed on /debug/pprof",
|
||||
},
|
||||
importPath: "net/http/pprof",
|
||||
importName: "_",
|
||||
}, []ast.Node{(*ast.ImportSpec)(nil)}
|
||||
}
|
56
vendor/github.com/securego/gosec/v2/rules/rand.go
generated
vendored
Normal file
56
vendor/github.com/securego/gosec/v2/rules/rand.go
generated
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
// (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"
|
||||
)
|
||||
|
||||
type weakRand struct {
|
||||
gosec.MetaData
|
||||
funcNames []string
|
||||
packagePath string
|
||||
}
|
||||
|
||||
func (w *weakRand) ID() string {
|
||||
return w.MetaData.ID
|
||||
}
|
||||
|
||||
func (w *weakRand) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) {
|
||||
for _, funcName := range w.funcNames {
|
||||
if _, matched := gosec.MatchCallByPackage(n, c, w.packagePath, funcName); matched {
|
||||
return gosec.NewIssue(c, 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, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
return &weakRand{
|
||||
funcNames: []string{"New", "Read", "Float32", "Float64", "Int", "Int31",
|
||||
"Int31n", "Int63", "Int63n", "Intn", "NormalFloat64", "Uint32", "Uint64"},
|
||||
packagePath: "math/rand",
|
||||
MetaData: gosec.MetaData{
|
||||
ID: id,
|
||||
Severity: gosec.High,
|
||||
Confidence: gosec.Medium,
|
||||
What: "Use of weak random number generator (math/rand instead of crypto/rand)",
|
||||
},
|
||||
}, []ast.Node{(*ast.CallExpr)(nil)}
|
||||
}
|
128
vendor/github.com/securego/gosec/v2/rules/readfile.go
generated
vendored
Normal file
128
vendor/github.com/securego/gosec/v2/rules/readfile.go
generated
vendored
Normal file
|
@ -0,0 +1,128 @@
|
|||
// (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"
|
||||
)
|
||||
|
||||
type readfile struct {
|
||||
gosec.MetaData
|
||||
gosec.CallList
|
||||
pathJoin gosec.CallList
|
||||
clean gosec.CallList
|
||||
}
|
||||
|
||||
// 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 before assigning to a variable
|
||||
func (r *readfile) isFilepathClean(n *ast.Ident, c *gosec.Context) bool {
|
||||
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
|
||||
}
|
||||
|
||||
// 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) (*gosec.Issue, error) {
|
||||
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 gosec.NewIssue(c, 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 gosec.NewIssue(c, 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 gosec.NewIssue(c, n, r.ID(), r.What, r.Severity, r.Confidence), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// NewReadFile detects cases where we read files
|
||||
func NewReadFile(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
rule := &readfile{
|
||||
pathJoin: gosec.NewCallList(),
|
||||
clean: gosec.NewCallList(),
|
||||
CallList: gosec.NewCallList(),
|
||||
MetaData: gosec.MetaData{
|
||||
ID: id,
|
||||
What: "Potential file inclusion via variable",
|
||||
Severity: gosec.Medium,
|
||||
Confidence: gosec.High,
|
||||
},
|
||||
}
|
||||
rule.pathJoin.Add("path/filepath", "Join")
|
||||
rule.pathJoin.Add("path", "Join")
|
||||
rule.clean.Add("path/filepath", "Clean")
|
||||
rule.clean.Add("path/filepath", "Rel")
|
||||
rule.Add("io/ioutil", "ReadFile")
|
||||
rule.Add("os", "Open")
|
||||
rule.Add("os", "OpenFile")
|
||||
return rule, []ast.Node{(*ast.CallExpr)(nil)}
|
||||
}
|
58
vendor/github.com/securego/gosec/v2/rules/rsa.go
generated
vendored
Normal file
58
vendor/github.com/securego/gosec/v2/rules/rsa.go
generated
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
// (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"
|
||||
)
|
||||
|
||||
type weakKeyStrength struct {
|
||||
gosec.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) (*gosec.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 gosec.NewIssue(c, 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, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
calls := gosec.NewCallList()
|
||||
calls.Add("crypto/rsa", "GenerateKey")
|
||||
bits := 2048
|
||||
return &weakKeyStrength{
|
||||
calls: calls,
|
||||
bits: bits,
|
||||
MetaData: gosec.MetaData{
|
||||
ID: id,
|
||||
Severity: gosec.Medium,
|
||||
Confidence: gosec.High,
|
||||
What: fmt.Sprintf("RSA keys should be at least %d bits", bits),
|
||||
},
|
||||
}, []ast.Node{(*ast.CallExpr)(nil)}
|
||||
}
|
116
vendor/github.com/securego/gosec/v2/rules/rulelist.go
generated
vendored
Normal file
116
vendor/github.com/securego/gosec/v2/rules/rulelist.go
generated
vendored
Normal file
|
@ -0,0 +1,116 @@
|
|||
// (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 is a mapping of rule ID's to rule definitions
|
||||
type RuleList map[string]RuleDefinition
|
||||
|
||||
// Builders returns all the create methods for a given rule list
|
||||
func (rl RuleList) Builders() map[string]gosec.RuleBuilder {
|
||||
builders := make(map[string]gosec.RuleBuilder)
|
||||
for _, def := range rl {
|
||||
builders[def.ID] = def.Create
|
||||
}
|
||||
return builders
|
||||
}
|
||||
|
||||
// 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(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},
|
||||
|
||||
// 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", "Unsafe defer call of a method returning an error", NewDeferredClosing},
|
||||
|
||||
// crypto
|
||||
{"G401", "Detect the usage of DES, RC4, MD5 or SHA1", NewUsesWeakCryptography},
|
||||
{"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},
|
||||
|
||||
// blocklist
|
||||
{"G501", "Import blocklist: crypto/md5", NewBlocklistedImportMD5},
|
||||
{"G502", "Import blocklist: crypto/des", NewBlocklistedImportDES},
|
||||
{"G503", "Import blocklist: crypto/rc4", NewBlocklistedImportRC4},
|
||||
{"G504", "Import blocklist: net/http/cgi", NewBlocklistedImportCGI},
|
||||
{"G505", "Import blocklist: crypto/sha1", NewBlocklistedImportSHA1},
|
||||
|
||||
// memory safety
|
||||
{"G601", "Implicit memory aliasing in RangeStmt", NewImplicitAliasing},
|
||||
}
|
||||
|
||||
ruleMap := make(map[string]RuleDefinition)
|
||||
|
||||
RULES:
|
||||
for _, rule := range rules {
|
||||
for _, filter := range filters {
|
||||
if filter(rule.ID) {
|
||||
continue RULES
|
||||
}
|
||||
}
|
||||
ruleMap[rule.ID] = rule
|
||||
}
|
||||
return ruleMap
|
||||
}
|
303
vendor/github.com/securego/gosec/v2/rules/sql.go
generated
vendored
Normal file
303
vendor/github.com/securego/gosec/v2/rules/sql.go
generated
vendored
Normal file
|
@ -0,0 +1,303 @@
|
|||
// (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"
|
||||
"strings"
|
||||
|
||||
"github.com/securego/gosec/v2"
|
||||
)
|
||||
|
||||
type sqlStatement struct {
|
||||
gosec.MetaData
|
||||
gosec.CallList
|
||||
|
||||
// Contains a list of patterns which must all match for the rule to match.
|
||||
patterns []*regexp.Regexp
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// 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) (*gosec.Issue, error) {
|
||||
_, fnName, err := gosec.GetCallInfo(call, ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var query ast.Node
|
||||
if strings.HasSuffix(fnName, "Context") {
|
||||
query = call.Args[1]
|
||||
} else {
|
||||
query = call.Args[0]
|
||||
}
|
||||
|
||||
if be, ok := query.(*ast.BinaryExpr); ok {
|
||||
operands := gosec.GetBinaryExprOperands(be)
|
||||
if start, ok := operands[0].(*ast.BasicLit); ok {
|
||||
if str, e := gosec.GetString(start); e == nil {
|
||||
if !s.MatchPatterns(str) {
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
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 gosec.NewIssue(ctx, be, s.ID(), s.What, s.Severity, s.Confidence), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Checks SQL query concatenation issues such as "SELECT * FROM table WHERE " + " ' OR 1=1"
|
||||
func (s *sqlStrConcat) Match(n ast.Node, ctx *gosec.Context) (*gosec.Issue, error) {
|
||||
switch stmt := n.(type) {
|
||||
case *ast.AssignStmt:
|
||||
for _, expr := range stmt.Rhs {
|
||||
if sqlQueryCall, ok := expr.(*ast.CallExpr); ok && s.ContainsCallExpr(expr, ctx) != nil {
|
||||
return s.checkQuery(sqlQueryCall, ctx)
|
||||
}
|
||||
}
|
||||
case *ast.ExprStmt:
|
||||
if sqlQueryCall, ok := stmt.X.(*ast.CallExpr); ok && s.ContainsCallExpr(stmt.X, ctx) != nil {
|
||||
return s.checkQuery(sqlQueryCall, ctx)
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// NewSQLStrConcat looks for cases where we are building SQL strings via concatenation
|
||||
func NewSQLStrConcat(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
rule := &sqlStrConcat{
|
||||
sqlStatement: sqlStatement{
|
||||
patterns: []*regexp.Regexp{
|
||||
regexp.MustCompile(`(?i)(SELECT|DELETE|INSERT|UPDATE|INTO|FROM|WHERE) `),
|
||||
},
|
||||
MetaData: gosec.MetaData{
|
||||
ID: id,
|
||||
Severity: gosec.Medium,
|
||||
Confidence: gosec.High,
|
||||
What: "SQL string concatenation",
|
||||
},
|
||||
CallList: gosec.NewCallList(),
|
||||
},
|
||||
}
|
||||
|
||||
rule.AddAll("*database/sql.DB", "Query", "QueryContext", "QueryRow", "QueryRowContext")
|
||||
rule.AddAll("*database/sql.Tx", "Query", "QueryContext", "QueryRow", "QueryRowContext")
|
||||
return rule, []ast.Node{(*ast.AssignStmt)(nil), (*ast.ExprStmt)(nil)}
|
||||
}
|
||||
|
||||
type sqlStrFormat struct {
|
||||
gosec.CallList
|
||||
sqlStatement
|
||||
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) (*gosec.Issue, error) {
|
||||
_, fnName, err := gosec.GetCallInfo(call, ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var query ast.Node
|
||||
if strings.HasSuffix(fnName, "Context") {
|
||||
query = call.Args[1]
|
||||
} else {
|
||||
query = call.Args[0]
|
||||
}
|
||||
|
||||
if ident, ok := query.(*ast.Ident); ok && ident.Obj != nil {
|
||||
decl := ident.Obj.Decl
|
||||
if assign, ok := decl.(*ast.AssignStmt); ok {
|
||||
for _, expr := range assign.Rhs {
|
||||
issue, err := s.checkFormatting(expr, ctx)
|
||||
if issue != nil {
|
||||
return issue, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (s *sqlStrFormat) checkFormatting(n ast.Node, ctx *gosec.Context) (*gosec.Issue, error) {
|
||||
// argIndex changes the function argument which gets matched to the regex
|
||||
argIndex := 0
|
||||
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, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
// the function is Fprintf so set argIndex = 1
|
||||
argIndex = 1
|
||||
}
|
||||
}
|
||||
|
||||
// no formatter
|
||||
if len(node.Args) == 0 {
|
||||
return nil, 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, 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, nil
|
||||
}
|
||||
}
|
||||
if s.MatchPatterns(formatter) {
|
||||
return gosec.NewIssue(ctx, n, s.ID(), s.What, s.Severity, s.Confidence), nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Check SQL query formatting issues such as "fmt.Sprintf("SELECT * FROM foo where '%s', userInput)"
|
||||
func (s *sqlStrFormat) Match(n ast.Node, ctx *gosec.Context) (*gosec.Issue, error) {
|
||||
switch stmt := n.(type) {
|
||||
case *ast.AssignStmt:
|
||||
for _, expr := range stmt.Rhs {
|
||||
if sqlQueryCall, ok := expr.(*ast.CallExpr); ok && s.ContainsCallExpr(expr, ctx) != nil {
|
||||
return s.checkQuery(sqlQueryCall, ctx)
|
||||
}
|
||||
}
|
||||
case *ast.ExprStmt:
|
||||
if sqlQueryCall, ok := stmt.X.(*ast.CallExpr); ok && s.ContainsCallExpr(stmt.X, ctx) != nil {
|
||||
return s.checkQuery(sqlQueryCall, ctx)
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// NewSQLStrFormat looks for cases where we're building SQL query strings using format strings
|
||||
func NewSQLStrFormat(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
rule := &sqlStrFormat{
|
||||
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) "),
|
||||
regexp.MustCompile("%[^bdoxXfFp]"),
|
||||
},
|
||||
MetaData: gosec.MetaData{
|
||||
ID: id,
|
||||
Severity: gosec.Medium,
|
||||
Confidence: gosec.High,
|
||||
What: "SQL string formatting",
|
||||
},
|
||||
},
|
||||
}
|
||||
rule.AddAll("*database/sql.DB", "Query", "QueryContext", "QueryRow", "QueryRowContext")
|
||||
rule.AddAll("*database/sql.Tx", "Query", "QueryContext", "QueryRow", "QueryRowContext")
|
||||
rule.fmtCalls.AddAll("fmt", "Sprint", "Sprintf", "Sprintln", "Fprintf")
|
||||
rule.noIssue.AddAll("os", "Stdout", "Stderr")
|
||||
rule.noIssueQuoted.Add("github.com/lib/pq", "QuoteIdentifier")
|
||||
|
||||
return rule, []ast.Node{(*ast.AssignStmt)(nil), (*ast.ExprStmt)(nil)}
|
||||
}
|
38
vendor/github.com/securego/gosec/v2/rules/ssh.go
generated
vendored
Normal file
38
vendor/github.com/securego/gosec/v2/rules/ssh.go
generated
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
package rules
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
|
||||
"github.com/securego/gosec/v2"
|
||||
)
|
||||
|
||||
type sshHostKey struct {
|
||||
gosec.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 *gosec.Issue, err error) {
|
||||
if _, matches := gosec.MatchCallByPackage(n, c, r.pkg, r.calls...); matches {
|
||||
return gosec.NewIssue(c, 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, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
return &sshHostKey{
|
||||
pkg: "golang.org/x/crypto/ssh",
|
||||
calls: []string{"InsecureIgnoreHostKey"},
|
||||
MetaData: gosec.MetaData{
|
||||
ID: id,
|
||||
What: "Use of ssh InsecureIgnoreHostKey should be audited",
|
||||
Severity: gosec.Medium,
|
||||
Confidence: gosec.High,
|
||||
},
|
||||
}, []ast.Node{(*ast.CallExpr)(nil)}
|
||||
}
|
66
vendor/github.com/securego/gosec/v2/rules/ssrf.go
generated
vendored
Normal file
66
vendor/github.com/securego/gosec/v2/rules/ssrf.go
generated
vendored
Normal file
|
@ -0,0 +1,66 @@
|
|||
package rules
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
"go/types"
|
||||
|
||||
"github.com/securego/gosec/v2"
|
||||
)
|
||||
|
||||
type ssrf struct {
|
||||
gosec.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) (*gosec.Issue, error) {
|
||||
// Call expression is using http package directly
|
||||
if node := r.ContainsPkgCallExpr(n, c, false); node != nil {
|
||||
if r.ResolveVar(node, c) {
|
||||
return gosec.NewIssue(c, 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, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
rule := &ssrf{
|
||||
CallList: gosec.NewCallList(),
|
||||
MetaData: gosec.MetaData{
|
||||
ID: id,
|
||||
What: "Potential HTTP request made with variable url",
|
||||
Severity: gosec.Medium,
|
||||
Confidence: gosec.Medium,
|
||||
},
|
||||
}
|
||||
rule.AddAll("net/http", "Do", "Get", "Head", "Post", "PostForm", "RoundTrip")
|
||||
return rule, []ast.Node{(*ast.CallExpr)(nil)}
|
||||
}
|
85
vendor/github.com/securego/gosec/v2/rules/subproc.go
generated
vendored
Normal file
85
vendor/github.com/securego/gosec/v2/rules/subproc.go
generated
vendored
Normal file
|
@ -0,0 +1,85 @@
|
|||
// (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"
|
||||
)
|
||||
|
||||
type subprocess struct {
|
||||
gosec.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) (*gosec.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)
|
||||
if _, ok := obj.(*types.Var); ok && !gosec.TryResolve(ident, c) {
|
||||
return gosec.NewIssue(c, n, r.ID(), "Subprocess launched with variable", gosec.Medium, gosec.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 gosec.NewIssue(c, n, r.ID(), "Subprocess launched with function call as argument or cmd arguments", gosec.Medium, gosec.High), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// isContext checks whether or not the node is a CommandContext call or not
|
||||
// Thi 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, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
rule := &subprocess{gosec.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")
|
||||
return rule, []ast.Node{(*ast.CallExpr)(nil)}
|
||||
}
|
58
vendor/github.com/securego/gosec/v2/rules/tempfiles.go
generated
vendored
Normal file
58
vendor/github.com/securego/gosec/v2/rules/tempfiles.go
generated
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
// (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"
|
||||
)
|
||||
|
||||
type badTempFile struct {
|
||||
gosec.MetaData
|
||||
calls gosec.CallList
|
||||
args *regexp.Regexp
|
||||
}
|
||||
|
||||
func (t *badTempFile) ID() string {
|
||||
return t.MetaData.ID
|
||||
}
|
||||
|
||||
func (t *badTempFile) Match(n ast.Node, c *gosec.Context) (gi *gosec.Issue, err error) {
|
||||
if node := t.calls.ContainsPkgCallExpr(n, c, false); node != nil {
|
||||
if arg, e := gosec.GetString(node.Args[0]); t.args.MatchString(arg) && e == nil {
|
||||
return gosec.NewIssue(c, n, t.ID(), t.What, t.Severity, t.Confidence), nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// NewBadTempFile detects direct writes to predictable path in temporary directory
|
||||
func NewBadTempFile(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
calls := gosec.NewCallList()
|
||||
calls.Add("io/ioutil", "WriteFile")
|
||||
calls.Add("os", "Create")
|
||||
return &badTempFile{
|
||||
calls: calls,
|
||||
args: regexp.MustCompile(`^/tmp/.*$|^/var/tmp/.*$`),
|
||||
MetaData: gosec.MetaData{
|
||||
ID: id,
|
||||
Severity: gosec.Medium,
|
||||
Confidence: gosec.High,
|
||||
What: "File creation in shared tmp directory without using ioutil.Tempfile",
|
||||
},
|
||||
}, []ast.Node{(*ast.CallExpr)(nil)}
|
||||
}
|
61
vendor/github.com/securego/gosec/v2/rules/templates.go
generated
vendored
Normal file
61
vendor/github.com/securego/gosec/v2/rules/templates.go
generated
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
// (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"
|
||||
)
|
||||
|
||||
type templateCheck struct {
|
||||
gosec.MetaData
|
||||
calls gosec.CallList
|
||||
}
|
||||
|
||||
func (t *templateCheck) ID() string {
|
||||
return t.MetaData.ID
|
||||
}
|
||||
|
||||
func (t *templateCheck) Match(n ast.Node, c *gosec.Context) (*gosec.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 gosec.NewIssue(c, 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, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
|
||||
calls := gosec.NewCallList()
|
||||
calls.Add("html/template", "HTML")
|
||||
calls.Add("html/template", "HTMLAttr")
|
||||
calls.Add("html/template", "JS")
|
||||
calls.Add("html/template", "URL")
|
||||
return &templateCheck{
|
||||
calls: calls,
|
||||
MetaData: gosec.MetaData{
|
||||
ID: id,
|
||||
Severity: gosec.Medium,
|
||||
Confidence: gosec.Low,
|
||||
What: "this method will not auto-escape HTML. Verify data is well formed.",
|
||||
},
|
||||
}, []ast.Node{(*ast.CallExpr)(nil)}
|
||||
}
|
172
vendor/github.com/securego/gosec/v2/rules/tls.go
generated
vendored
Normal file
172
vendor/github.com/securego/gosec/v2/rules/tls.go
generated
vendored
Normal file
|
@ -0,0 +1,172 @@
|
|||
// (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"
|
||||
|
||||
"github.com/securego/gosec/v2"
|
||||
)
|
||||
|
||||
type insecureConfigTLS struct {
|
||||
gosec.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) *gosec.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 gosec.NewIssue(c, ident, t.ID(), err, gosec.High, gosec.High)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *insecureConfigTLS) processTLSConfVal(n *ast.KeyValueExpr, c *gosec.Context) *gosec.Issue {
|
||||
if ident, ok := n.Key.(*ast.Ident); ok {
|
||||
switch ident.Name {
|
||||
case "InsecureSkipVerify":
|
||||
if node, ok := n.Value.(*ast.Ident); ok {
|
||||
if node.Name != "false" {
|
||||
return gosec.NewIssue(c, n, t.ID(), "TLS InsecureSkipVerify set true.", gosec.High, gosec.High)
|
||||
}
|
||||
} else {
|
||||
// TODO(tk): symbol tab look up to get the actual value
|
||||
return gosec.NewIssue(c, n, t.ID(), "TLS InsecureSkipVerify may be true.", gosec.High, gosec.Low)
|
||||
}
|
||||
|
||||
case "PreferServerCipherSuites":
|
||||
if node, ok := n.Value.(*ast.Ident); ok {
|
||||
if node.Name == "false" {
|
||||
return gosec.NewIssue(c, n, t.ID(), "TLS PreferServerCipherSuites set false.", gosec.Medium, gosec.High)
|
||||
}
|
||||
} else {
|
||||
// TODO(tk): symbol tab look up to get the actual value
|
||||
return gosec.NewIssue(c, n, t.ID(), "TLS PreferServerCipherSuites may be false.", gosec.Medium, gosec.Low)
|
||||
}
|
||||
|
||||
case "MinVersion":
|
||||
if ival, ierr := gosec.GetInt(n.Value); ierr == nil {
|
||||
t.actualMinVersion = ival
|
||||
} else {
|
||||
if se, ok := n.Value.(*ast.SelectorExpr); ok {
|
||||
if pkg, ok := se.X.(*ast.Ident); ok && pkg.Name == "tls" {
|
||||
t.actualMinVersion = t.mapVersion(se.Sel.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case "MaxVersion":
|
||||
if ival, ierr := gosec.GetInt(n.Value); ierr == nil {
|
||||
t.actualMaxVersion = ival
|
||||
} else {
|
||||
if se, ok := n.Value.(*ast.SelectorExpr); ok {
|
||||
if pkg, ok := se.X.(*ast.Ident); ok && pkg.Name == "tls" {
|
||||
t.actualMaxVersion = t.mapVersion(se.Sel.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case "CipherSuites":
|
||||
if ret := t.processTLSCipherSuites(n.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) *gosec.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 gosec.NewIssue(c, n, t.ID(), "TLS MinVersion too low.", gosec.High, gosec.High)
|
||||
}
|
||||
if t.actualMaxVersion < t.MaxVersion {
|
||||
return gosec.NewIssue(c, n, t.ID(), "TLS MaxVersion too low.", gosec.High, gosec.High)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *insecureConfigTLS) resetVersion() {
|
||||
t.actualMaxVersion = 0
|
||||
t.actualMinVersion = 0
|
||||
}
|
||||
|
||||
func (t *insecureConfigTLS) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) {
|
||||
if complit, ok := n.(*ast.CompositeLit); ok && complit.Type != nil {
|
||||
actualType := c.Info.TypeOf(complit.Type)
|
||||
if actualType != nil && actualType.String() == t.requiredType {
|
||||
for _, elt := range complit.Elts {
|
||||
if kve, ok := elt.(*ast.KeyValueExpr); ok {
|
||||
issue := t.processTLSConfVal(kve, c)
|
||||
if issue != nil {
|
||||
return issue, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
issue := t.checkVersion(complit, c)
|
||||
t.resetVersion()
|
||||
return issue, nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
92
vendor/github.com/securego/gosec/v2/rules/tls_config.go
generated
vendored
Normal file
92
vendor/github.com/securego/gosec/v2/rules/tls_config.go
generated
vendored
Normal file
|
@ -0,0 +1,92 @@
|
|||
package rules
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
|
||||
"github.com/securego/gosec/v2"
|
||||
)
|
||||
|
||||
// NewModernTLSCheck creates a check for Modern TLS ciphers
|
||||
// DO NOT EDIT - generated by tlsconfig tool
|
||||
func NewModernTLSCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
return &insecureConfigTLS{
|
||||
MetaData: gosec.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)}
|
||||
}
|
||||
|
||||
// NewIntermediateTLSCheck creates a check for Intermediate TLS ciphers
|
||||
// DO NOT EDIT - generated by tlsconfig tool
|
||||
func NewIntermediateTLSCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
return &insecureConfigTLS{
|
||||
MetaData: gosec.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)}
|
||||
}
|
||||
|
||||
// NewOldTLSCheck creates a check for Old TLS ciphers
|
||||
// DO NOT EDIT - generated by tlsconfig tool
|
||||
func NewOldTLSCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
return &insecureConfigTLS{
|
||||
MetaData: gosec.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)}
|
||||
}
|
53
vendor/github.com/securego/gosec/v2/rules/unsafe.go
generated
vendored
Normal file
53
vendor/github.com/securego/gosec/v2/rules/unsafe.go
generated
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
// (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"
|
||||
)
|
||||
|
||||
type usingUnsafe struct {
|
||||
gosec.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 *gosec.Issue, err error) {
|
||||
if _, matches := gosec.MatchCallByPackage(n, c, r.pkg, r.calls...); matches {
|
||||
return gosec.NewIssue(c, 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, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
return &usingUnsafe{
|
||||
pkg: "unsafe",
|
||||
calls: []string{"Alignof", "Offsetof", "Sizeof", "Pointer"},
|
||||
MetaData: gosec.MetaData{
|
||||
ID: id,
|
||||
What: "Use of unsafe calls should be audited",
|
||||
Severity: gosec.Low,
|
||||
Confidence: gosec.High,
|
||||
},
|
||||
}, []ast.Node{(*ast.CallExpr)(nil)}
|
||||
}
|
58
vendor/github.com/securego/gosec/v2/rules/weakcrypto.go
generated
vendored
Normal file
58
vendor/github.com/securego/gosec/v2/rules/weakcrypto.go
generated
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
// (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"
|
||||
)
|
||||
|
||||
type usesWeakCryptography struct {
|
||||
gosec.MetaData
|
||||
blocklist map[string][]string
|
||||
}
|
||||
|
||||
func (r *usesWeakCryptography) ID() string {
|
||||
return r.MetaData.ID
|
||||
}
|
||||
|
||||
func (r *usesWeakCryptography) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) {
|
||||
for pkg, funcs := range r.blocklist {
|
||||
if _, matched := gosec.MatchCallByPackage(n, c, pkg, funcs...); matched {
|
||||
return gosec.NewIssue(c, n, r.ID(), r.What, r.Severity, r.Confidence), nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// NewUsesWeakCryptography detects uses of des.* md5.* or rc4.*
|
||||
func NewUsesWeakCryptography(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
calls := make(map[string][]string)
|
||||
calls["crypto/des"] = []string{"NewCipher", "NewTripleDESCipher"}
|
||||
calls["crypto/md5"] = []string{"New", "Sum"}
|
||||
calls["crypto/sha1"] = []string{"New", "Sum"}
|
||||
calls["crypto/rc4"] = []string{"NewCipher"}
|
||||
rule := &usesWeakCryptography{
|
||||
blocklist: calls,
|
||||
MetaData: gosec.MetaData{
|
||||
ID: id,
|
||||
Severity: gosec.Medium,
|
||||
Confidence: gosec.High,
|
||||
What: "Use of weak cryptographic primitive",
|
||||
},
|
||||
}
|
||||
return rule, []ast.Node{(*ast.CallExpr)(nil)}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue