mirror of
https://github.com/securego/gosec.git
synced 2026-01-15 09:53:40 +08:00
Compare commits
55 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
19fa856bad | ||
|
|
62fa4b4e9b | ||
|
|
074dc71087 | ||
|
|
79a5b13bdb | ||
|
|
97f03d9939 | ||
|
|
0ba05e160a | ||
|
|
d3933f9e14 | ||
|
|
4e68fb5b15 | ||
|
|
0c8e63ed86 | ||
|
|
6a26c231fc | ||
|
|
1b0873a235 | ||
|
|
845483e0b1 | ||
|
|
45bf9a6095 | ||
|
|
a5982fb6a6 | ||
|
|
ea6d49d1b5 | ||
|
|
21fcd2f904 | ||
|
|
3cda47a9b8 | ||
|
|
0212c83699 | ||
|
|
9a25f4ed2d | ||
|
|
602ced7e71 | ||
|
|
7dd9ddd583 | ||
|
|
b0f3e78e07 | ||
|
|
05f3ca80f9 | ||
|
|
a9b0ef0a11 | ||
|
|
9c19cb6501 | ||
|
|
fb587c1d10 | ||
|
|
c3ede62822 | ||
|
|
0a929c7b6c | ||
|
|
12be14859b | ||
|
|
0dcc3362ae | ||
|
|
34d144b3fa | ||
|
|
a64cde55a4 | ||
|
|
b69c3d48c8 | ||
|
|
89dfdc0c97 | ||
|
|
0791d31471 | ||
|
|
2ef1d9a037 | ||
|
|
afc9903ba9 | ||
|
|
82eaa12696 | ||
|
|
607d607b51 | ||
|
|
b99b5f7838 | ||
|
|
8af0af7611 | ||
|
|
ea5d31f7f5 | ||
|
|
48bbf96b56 | ||
|
|
26f10e0a7a | ||
|
|
7d539ed494 | ||
|
|
43577cebb7 | ||
|
|
c0680bb6a3 | ||
|
|
db8d98b571 | ||
|
|
507f8472ca | ||
|
|
853e1d5034 | ||
|
|
09a2941ad4 | ||
|
|
9399e7bed7 | ||
|
|
2fad8a4193 | ||
|
|
1fbcf10e18 | ||
|
|
b12c0f6e4e |
33
.github/workflows/ci.yml
vendored
33
.github/workflows/ci.yml
vendored
@@ -7,38 +7,33 @@ on:
|
||||
branches:
|
||||
- master
|
||||
jobs:
|
||||
golangci:
|
||||
name: lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v2
|
||||
with:
|
||||
version: latest
|
||||
test:
|
||||
needs: [golangci]
|
||||
strategy:
|
||||
matrix:
|
||||
go_version:
|
||||
- '1.16'
|
||||
- '1.17'
|
||||
- '1.18'
|
||||
- '1.19'
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
GO111MODULE: on
|
||||
steps:
|
||||
- name: Setup go ${{ matrix.go_version }}
|
||||
uses: actions/setup-go@v2
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: ${{ matrix.go_version }}
|
||||
- name: Checkout Source
|
||||
uses: actions/checkout@v2
|
||||
- uses: actions/cache@v2
|
||||
uses: actions/checkout@v3
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-
|
||||
- name: lint
|
||||
uses: golangci/golangci-lint-action@v3
|
||||
with:
|
||||
version: latest
|
||||
- name: Run Tests
|
||||
run: make test
|
||||
coverage:
|
||||
@@ -48,12 +43,12 @@ jobs:
|
||||
GO111MODULE: on
|
||||
steps:
|
||||
- name: Setup go
|
||||
uses: actions/setup-go@v2
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '1.17'
|
||||
go-version: '1.19'
|
||||
- name: Checkout Source
|
||||
uses: actions/checkout@v2
|
||||
- uses: actions/cache@v2
|
||||
uses: actions/checkout@v3
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
@@ -62,7 +57,7 @@ jobs:
|
||||
- name: Create Test Coverage
|
||||
run: make test-coverage
|
||||
- name: Upload Test Coverage
|
||||
uses: codecov/codecov-action@v2
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
fail_ci_if_error: true
|
||||
|
||||
62
.github/workflows/release.yml
vendored
62
.github/workflows/release.yml
vendored
@@ -10,35 +10,65 @@ jobs:
|
||||
GO111MODULE: on
|
||||
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
|
||||
steps:
|
||||
- name: Checkout Source
|
||||
uses: actions/checkout@v2
|
||||
- name: Checkout Source
|
||||
uses: actions/checkout@v3
|
||||
- name: Unshallow
|
||||
run: git fetch --prune --unshallow
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.17
|
||||
- name : Get release version
|
||||
id: get_version
|
||||
run: echo ::set-env name=RELEASE_VERSION::$(echo ${GITHUB_REF:10})
|
||||
go-version: 1.19
|
||||
- name: Install Cosign
|
||||
uses: sigstore/cosign-installer@v2
|
||||
with:
|
||||
cosign-release: 'v1.6.0'
|
||||
- name: Store Cosign private key in a file
|
||||
run: 'echo "$COSIGN_KEY" > /tmp/cosign.key'
|
||||
shell: bash
|
||||
env:
|
||||
COSIGN_KEY: ${{secrets.COSIGN_KEY}}
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{secrets.DOCKER_USERNAME}}
|
||||
password: ${{secrets.DOCKER_PASSWORD}}
|
||||
- name: Generate SBOM
|
||||
uses: CycloneDX/gh-gomod-generate-sbom@v1
|
||||
with:
|
||||
version: v1
|
||||
args: mod -licenses -json -output bom.json
|
||||
- name: Docker meta
|
||||
uses: docker/metadata-action@v4
|
||||
id: meta
|
||||
with:
|
||||
images: securego/gosec
|
||||
flavor: |
|
||||
latest=true
|
||||
tags: |
|
||||
type=sha,format=long
|
||||
type=semver,pattern={{version}}
|
||||
- name: Release Binaries
|
||||
uses: goreleaser/goreleaser-action@v2
|
||||
uses: goreleaser/goreleaser-action@v3
|
||||
with:
|
||||
version: latest
|
||||
args: release --rm-dist
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||
COSIGN_PASSWORD: ${{secrets.COSIGN_PASSWORD}}
|
||||
- name: Release Docker Image
|
||||
uses: elgohr/Publish-Docker-Github-Action@master
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
name: securego/gosec
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
buildargs: GO_VERSION=1.17
|
||||
tags: "latest,${{ env.RELEASE_VERSION }}"
|
||||
tag_names: true
|
||||
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
||||
tags: ${{steps.meta.outputs.tags}}
|
||||
labels: ${{steps.meta.outputs.labels}}
|
||||
push: true
|
||||
build-args: GO_VERSION=1.19
|
||||
- name: Sign Docker Image
|
||||
run: cosign sign -key /tmp/cosign.key ${TAGS}
|
||||
env:
|
||||
TAGS: ${{steps.meta.outputs.tags}}
|
||||
COSIGN_PASSWORD: ${{secrets.COSIGN_PASSWORD}}
|
||||
|
||||
4
.github/workflows/scan.yml
vendored
4
.github/workflows/scan.yml
vendored
@@ -13,14 +13,14 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Security Scan
|
||||
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
|
||||
uses: github/codeql-action/upload-sarif@v2
|
||||
with:
|
||||
# Path to SARIF file relative to the root of the repository
|
||||
sarif_file: results.sarif
|
||||
|
||||
@@ -9,7 +9,7 @@ release:
|
||||
name: gosec
|
||||
|
||||
builds:
|
||||
- main : ./cmd/gosec/
|
||||
- main: ./cmd/gosec/
|
||||
binary: gosec
|
||||
goos:
|
||||
- darwin
|
||||
@@ -21,3 +21,10 @@ builds:
|
||||
ldflags: -X main.Version={{.Version}} -X main.GitTag={{.Tag}} -X main.BuildDate={{.Date}}
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
|
||||
signs:
|
||||
- cmd: cosign
|
||||
stdin: '{{ .Env.COSIGN_PASSWORD}}'
|
||||
args: ["sign-blob", "--key=/tmp/cosign.key", "--output=${signature}", "${artifact}"]
|
||||
artifacts: all
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
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 apk add --no-cache ca-certificates make git curl gcc libc-dev
|
||||
RUN mkdir -p /build
|
||||
WORKDIR /build
|
||||
COPY . /build/
|
||||
@@ -8,7 +8,7 @@ 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 openssh
|
||||
RUN apk add --no-cache ca-certificates bash git gcc libc-dev openssh
|
||||
ENV GO111MODULE on
|
||||
COPY --from=builder /build/gosec /bin/gosec
|
||||
COPY entrypoint.sh /bin/entrypoint.sh
|
||||
|
||||
8
Makefile
8
Makefile
@@ -12,7 +12,7 @@ GOBIN ?= $(GOPATH)/bin
|
||||
GOLINT ?= $(GOBIN)/golint
|
||||
GOSEC ?= $(GOBIN)/gosec
|
||||
GINKGO ?= $(GOBIN)/ginkgo
|
||||
GO_VERSION = 1.17
|
||||
GO_VERSION = 1.18
|
||||
|
||||
default:
|
||||
$(MAKE) build
|
||||
@@ -31,12 +31,16 @@ fmt:
|
||||
@([ ! -z "$(FORMATTED)" ] && printf "Fixed unformatted files:\n$(FORMATTED)") || true
|
||||
|
||||
lint:
|
||||
@echo "LINTING"
|
||||
@echo "LINTING: golint"
|
||||
$(GO_NOMOD) get -u golang.org/x/lint/golint
|
||||
$(GOLINT) -set_exit_status ./...
|
||||
@echo "VETTING"
|
||||
$(GO) vet ./...
|
||||
|
||||
golangci:
|
||||
@echo "LINTING: golangci-lint"
|
||||
golangci-lint run
|
||||
|
||||
sec:
|
||||
@echo "SECURITY SCANNING"
|
||||
./$(BIN) ./...
|
||||
|
||||
21
README.md
21
README.md
@@ -143,6 +143,10 @@ directory you can supply `./...` as the input argument.
|
||||
- G108: Profiling endpoint automatically exposed on /debug/pprof
|
||||
- G109: Potential Integer overflow made by strconv.Atoi result conversion to int16/32
|
||||
- G110: Potential DoS vulnerability via decompression bomb
|
||||
- G111: Potential directory traversal
|
||||
- G112: Potential slowloris attack
|
||||
- G113: Usage of Rat.SetString in math/big with an overflow (CVE-2022-23772)
|
||||
- G114: Use of net/http serve function that has no support for setting timeouts
|
||||
- G201: SQL query construction using format string
|
||||
- G202: SQL query construction using string concatenation
|
||||
- G203: Use of unescaped data in HTML templates
|
||||
@@ -218,7 +222,7 @@ of functions which will be skipped when auditing the not checked errors:
|
||||
}
|
||||
```
|
||||
|
||||
You can also configure the hard-coded credentials rule `G101` with additional patters, or adjust the entropy threshold:
|
||||
You can also configure the hard-coded credentials rule `G101` with additional patterns, or adjust the entropy threshold:
|
||||
|
||||
```JSON
|
||||
{
|
||||
@@ -407,6 +411,19 @@ git push origin v1.0.0
|
||||
The GitHub [release workflow](.github/workflows/release.yml) triggers immediately after the tag is pushed upstream. This flow will
|
||||
release the binaries using the [goreleaser](https://goreleaser.com/actions/) action and then it will build and publish the docker image into Docker Hub.
|
||||
|
||||
The released artifacts are signed using [cosign](https://docs.sigstore.dev/). You can use the public key from [cosign.pub](cosign.pub)
|
||||
file to verify the signature of docker image and binaries files.
|
||||
|
||||
The docker image signature can be verified with the following command:
|
||||
```
|
||||
cosign verify --key cosign.pub securego/gosec:<TAG>
|
||||
```
|
||||
|
||||
The binary files signature can be verified with the following command:
|
||||
```
|
||||
cosign verify-blob --key cosign.pub --signature gosec_<VERSION>_darwin_amd64.tar.gz.sig gosec_<VERSION>_darwin_amd64.tar.gz
|
||||
```
|
||||
|
||||
### Docker image
|
||||
|
||||
You can also build locally the docker image by using the command:
|
||||
@@ -450,4 +467,4 @@ This is a [list](USERS.md) with some of the gosec's users.
|
||||
|
||||
Support this project by becoming a sponsor. Your logo will show up here with a link to your website
|
||||
|
||||
<a href="https://github.com/Daimler" target="_blank"><img src="https://avatars.githubusercontent.com/u/34240465?s=80&v=4"></a>
|
||||
<a href="https://github.com/mercedes-benz" target="_blank"><img src="https://avatars.githubusercontent.com/u/34240465?s=80&v=4"></a>
|
||||
|
||||
64
analyzer.go
64
analyzer.go
@@ -29,6 +29,7 @@ import (
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/tools/go/packages"
|
||||
)
|
||||
@@ -88,6 +89,7 @@ type Analyzer struct {
|
||||
excludeGenerated bool
|
||||
showIgnored bool
|
||||
trackSuppressions bool
|
||||
concurrency int
|
||||
}
|
||||
|
||||
// SuppressionInfo object is to record the kind and the justification that used
|
||||
@@ -98,7 +100,7 @@ type SuppressionInfo struct {
|
||||
}
|
||||
|
||||
// NewAnalyzer builds a new analyzer.
|
||||
func NewAnalyzer(conf Config, tests bool, excludeGenerated bool, trackSuppressions bool, logger *log.Logger) *Analyzer {
|
||||
func NewAnalyzer(conf Config, tests bool, excludeGenerated bool, trackSuppressions bool, concurrency int, logger *log.Logger) *Analyzer {
|
||||
ignoreNoSec := false
|
||||
if enabled, err := conf.IsGlobalEnabled(Nosec); err == nil {
|
||||
ignoreNoSec = enabled
|
||||
@@ -121,6 +123,7 @@ func NewAnalyzer(conf Config, tests bool, excludeGenerated bool, trackSuppressio
|
||||
stats: &Metrics{},
|
||||
errors: make(map[string][]Error),
|
||||
tests: tests,
|
||||
concurrency: concurrency,
|
||||
excludeGenerated: excludeGenerated,
|
||||
trackSuppressions: trackSuppressions,
|
||||
}
|
||||
@@ -153,15 +156,64 @@ func (gosec *Analyzer) Process(buildTags []string, packagePaths ...string) error
|
||||
Tests: gosec.tests,
|
||||
}
|
||||
|
||||
for _, pkgPath := range packagePaths {
|
||||
pkgs, err := gosec.load(pkgPath, config)
|
||||
if err != nil {
|
||||
gosec.AppendError(pkgPath, err)
|
||||
type result struct {
|
||||
pkgPath string
|
||||
pkgs []*packages.Package
|
||||
err error
|
||||
}
|
||||
|
||||
results := make(chan result)
|
||||
jobs := make(chan string, len(packagePaths))
|
||||
quit := make(chan struct{})
|
||||
|
||||
var wg sync.WaitGroup
|
||||
|
||||
worker := func(j chan string, r chan result, quit chan struct{}) {
|
||||
for {
|
||||
select {
|
||||
case s := <-j:
|
||||
packages, err := gosec.load(s, config)
|
||||
select {
|
||||
case r <- result{pkgPath: s, pkgs: packages, err: err}:
|
||||
case <-quit:
|
||||
// we've been told to stop, probably an error while
|
||||
// processing a previous result.
|
||||
wg.Done()
|
||||
return
|
||||
}
|
||||
default:
|
||||
// j is empty and there are no jobs left
|
||||
wg.Done()
|
||||
return
|
||||
}
|
||||
}
|
||||
for _, pkg := range pkgs {
|
||||
}
|
||||
|
||||
// fill the buffer
|
||||
for _, pkgPath := range packagePaths {
|
||||
jobs <- pkgPath
|
||||
}
|
||||
|
||||
for i := 0; i < gosec.concurrency; i++ {
|
||||
wg.Add(1)
|
||||
go worker(jobs, results, quit)
|
||||
}
|
||||
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(results)
|
||||
}()
|
||||
|
||||
for r := range results {
|
||||
if r.err != nil {
|
||||
gosec.AppendError(r.pkgPath, r.err)
|
||||
}
|
||||
for _, pkg := range r.pkgs {
|
||||
if pkg.Name != "" {
|
||||
err := gosec.ParseErrors(pkg)
|
||||
if err != nil {
|
||||
close(quit)
|
||||
wg.Wait() // wait for the goroutines to stop
|
||||
return fmt.Errorf("parsing errors in pkg %q: %w", pkg.Name, err)
|
||||
}
|
||||
gosec.Check(pkg)
|
||||
|
||||
@@ -2,7 +2,6 @@ package gosec_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
@@ -24,13 +23,13 @@ var _ = Describe("Analyzer", func() {
|
||||
)
|
||||
BeforeEach(func() {
|
||||
logger, _ = testutils.NewLogger()
|
||||
analyzer = gosec.NewAnalyzer(nil, tests, false, false, logger)
|
||||
analyzer = gosec.NewAnalyzer(nil, tests, false, false, 1, logger)
|
||||
})
|
||||
|
||||
Context("when processing a package", func() {
|
||||
It("should not report an error if the package contains no Go files", func() {
|
||||
analyzer.LoadRules(rules.Generate(false).RulesInfo())
|
||||
dir, err := ioutil.TempDir("", "empty")
|
||||
dir, err := os.MkdirTemp("", "empty")
|
||||
defer os.RemoveAll(dir)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, dir)
|
||||
@@ -77,6 +76,29 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(metrics.NumFiles).To(Equal(2))
|
||||
})
|
||||
|
||||
It("should be able to analyze multiple Go files concurrently", func() {
|
||||
customAnalyzer := gosec.NewAnalyzer(nil, true, true, false, 32, logger)
|
||||
customAnalyzer.LoadRules(rules.Generate(false).RulesInfo())
|
||||
pkg := testutils.NewTestPackage()
|
||||
defer pkg.Close()
|
||||
pkg.AddFile("foo.go", `
|
||||
package main
|
||||
func main(){
|
||||
bar()
|
||||
}`)
|
||||
pkg.AddFile("bar.go", `
|
||||
package main
|
||||
func bar(){
|
||||
println("package has two files!")
|
||||
}`)
|
||||
err := pkg.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = customAnalyzer.Process(buildTags, pkg.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
_, metrics, _ := customAnalyzer.Report()
|
||||
Expect(metrics.NumFiles).To(Equal(2))
|
||||
})
|
||||
|
||||
It("should be able to analyze multiple Go packages", func() {
|
||||
analyzer.LoadRules(rules.Generate(false).RulesInfo())
|
||||
pkg1 := testutils.NewTestPackage()
|
||||
@@ -262,7 +284,7 @@ var _ = Describe("Analyzer", func() {
|
||||
// overwrite nosec option
|
||||
nosecIgnoreConfig := gosec.NewConfig()
|
||||
nosecIgnoreConfig.SetGlobal(gosec.Nosec, "true")
|
||||
customAnalyzer := gosec.NewAnalyzer(nosecIgnoreConfig, tests, false, false, logger)
|
||||
customAnalyzer := gosec.NewAnalyzer(nosecIgnoreConfig, tests, false, false, 1, logger)
|
||||
customAnalyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G401")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
@@ -286,7 +308,7 @@ var _ = Describe("Analyzer", func() {
|
||||
nosecIgnoreConfig := gosec.NewConfig()
|
||||
nosecIgnoreConfig.SetGlobal(gosec.Nosec, "true")
|
||||
nosecIgnoreConfig.SetGlobal(gosec.ShowIgnored, "true")
|
||||
customAnalyzer := gosec.NewAnalyzer(nosecIgnoreConfig, tests, false, false, logger)
|
||||
customAnalyzer := gosec.NewAnalyzer(nosecIgnoreConfig, tests, false, false, 1, logger)
|
||||
customAnalyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G401")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
@@ -379,7 +401,7 @@ var _ = Describe("Analyzer", func() {
|
||||
// overwrite nosec option
|
||||
nosecIgnoreConfig := gosec.NewConfig()
|
||||
nosecIgnoreConfig.SetGlobal(gosec.NoSecAlternative, "#falsePositive")
|
||||
customAnalyzer := gosec.NewAnalyzer(nosecIgnoreConfig, tests, false, false, logger)
|
||||
customAnalyzer := gosec.NewAnalyzer(nosecIgnoreConfig, tests, false, false, 1, logger)
|
||||
customAnalyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G401")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
@@ -402,7 +424,7 @@ var _ = Describe("Analyzer", func() {
|
||||
// overwrite nosec option
|
||||
nosecIgnoreConfig := gosec.NewConfig()
|
||||
nosecIgnoreConfig.SetGlobal(gosec.NoSecAlternative, "#falsePositive")
|
||||
customAnalyzer := gosec.NewAnalyzer(nosecIgnoreConfig, tests, false, false, logger)
|
||||
customAnalyzer := gosec.NewAnalyzer(nosecIgnoreConfig, tests, false, false, 1, logger)
|
||||
customAnalyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G401")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
@@ -418,7 +440,7 @@ var _ = Describe("Analyzer", func() {
|
||||
})
|
||||
|
||||
It("should be able to analyze Go test package", func() {
|
||||
customAnalyzer := gosec.NewAnalyzer(nil, true, false, false, logger)
|
||||
customAnalyzer := gosec.NewAnalyzer(nil, true, false, false, 1, logger)
|
||||
customAnalyzer.LoadRules(rules.Generate(false).RulesInfo())
|
||||
pkg := testutils.NewTestPackage()
|
||||
defer pkg.Close()
|
||||
@@ -443,7 +465,7 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(issues).Should(HaveLen(1))
|
||||
})
|
||||
It("should be able to scan generated files if NOT excluded", func() {
|
||||
customAnalyzer := gosec.NewAnalyzer(nil, true, false, false, logger)
|
||||
customAnalyzer := gosec.NewAnalyzer(nil, true, false, false, 1, logger)
|
||||
customAnalyzer.LoadRules(rules.Generate(false).RulesInfo())
|
||||
pkg := testutils.NewTestPackage()
|
||||
defer pkg.Close()
|
||||
@@ -464,7 +486,7 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(issues).Should(HaveLen(1))
|
||||
})
|
||||
It("should be able to skip generated files if excluded", func() {
|
||||
customAnalyzer := gosec.NewAnalyzer(nil, true, true, false, logger)
|
||||
customAnalyzer := gosec.NewAnalyzer(nil, true, true, false, 1, logger)
|
||||
customAnalyzer.LoadRules(rules.Generate(false).RulesInfo())
|
||||
pkg := testutils.NewTestPackage()
|
||||
defer pkg.Close()
|
||||
@@ -671,7 +693,7 @@ var _ = Describe("Analyzer", func() {
|
||||
|
||||
Context("when tracking suppressions", func() {
|
||||
BeforeEach(func() {
|
||||
analyzer = gosec.NewAnalyzer(nil, tests, false, true, logger)
|
||||
analyzer = gosec.NewAnalyzer(nil, tests, false, true, 1, logger)
|
||||
})
|
||||
|
||||
It("should not report an error if the violation is suppressed", func() {
|
||||
|
||||
25
call_list.go
25
call_list.go
@@ -47,7 +47,7 @@ func (c CallList) Add(selector, ident string) {
|
||||
}
|
||||
|
||||
// Contains returns true if the package and function are
|
||||
/// members of this call list.
|
||||
// members of this call list.
|
||||
func (c CallList) Contains(selector, ident string) bool {
|
||||
if idents, ok := c[selector]; ok {
|
||||
_, found := idents[ident]
|
||||
@@ -77,17 +77,26 @@ func (c CallList) ContainsPkgCallExpr(n ast.Node, ctx *Context, stripVendor bool
|
||||
return nil
|
||||
}
|
||||
|
||||
// Use only explicit path (optionally strip vendor path prefix) to reduce conflicts
|
||||
path, ok := GetImportPath(selector, ctx)
|
||||
if !ok {
|
||||
return nil
|
||||
// Selector can have two forms:
|
||||
// 1. A short name if a module function is called (expr.Name).
|
||||
// E.g., "big" if called function from math/big.
|
||||
// 2. A full name if a structure function is called (TypeOf(expr)).
|
||||
// E.g., "math/big.Rat" if called function of Rat structure from math/big.
|
||||
if !strings.ContainsRune(selector, '.') {
|
||||
// Use only explicit path (optionally strip vendor path prefix) to reduce conflicts
|
||||
path, ok := GetImportPath(selector, ctx)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
selector = path
|
||||
}
|
||||
|
||||
if stripVendor {
|
||||
if vendorIdx := strings.Index(path, vendorPath); vendorIdx >= 0 {
|
||||
path = path[vendorIdx+len(vendorPath):]
|
||||
if vendorIdx := strings.Index(selector, vendorPath); vendorIdx >= 0 {
|
||||
selector = selector[vendorIdx+len(vendorPath):]
|
||||
}
|
||||
}
|
||||
if !c.Contains(path, ident) {
|
||||
if !c.Contains(selector, ident) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,10 @@ package main
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
@@ -70,7 +71,7 @@ func (a *arrayFlags) Set(value string) error {
|
||||
}
|
||||
|
||||
var (
|
||||
//#nosec flag
|
||||
// #nosec flag
|
||||
flagIgnoreNoSec = flag.Bool("nosec", false, "Ignores #nosec comments when set")
|
||||
|
||||
// show ignored
|
||||
@@ -79,7 +80,7 @@ var (
|
||||
// format output
|
||||
flagFormat = flag.String("fmt", "text", "Set output format. Valid options are: json, yaml, csv, junit-xml, html, sonarqube, golint, sarif or text")
|
||||
|
||||
//#nosec alternative tag
|
||||
// #nosec alternative tag
|
||||
flagAlternativeNoSec = flag.String("nosec-tag", "", "Set an alternative string for #nosec. Some examples: #dontanalyze, #falsepositive")
|
||||
|
||||
// output file
|
||||
@@ -114,6 +115,9 @@ var (
|
||||
// fail by confidence
|
||||
flagConfidence = flag.String("confidence", "low", "Filter out the issues with a lower confidence than the given value. Valid options are: low, medium, high")
|
||||
|
||||
// concurrency value
|
||||
flagConcurrency = flag.Int("concurrency", runtime.NumCPU(), "Concurrency value")
|
||||
|
||||
// do not fail
|
||||
flagNoFail = flag.Bool("no-fail", false, "Do not fail the scanning, even if issues were found")
|
||||
|
||||
@@ -129,6 +133,9 @@ var (
|
||||
// print the text report with color, this is enabled by default
|
||||
flagColor = flag.Bool("color", true, "Prints the text format report with colorization when it goes in the stdout")
|
||||
|
||||
// append ./... to the target dir.
|
||||
flagRecursive = flag.Bool("r", false, "Appends \"./...\" to the target dir.")
|
||||
|
||||
// overrides the output format when stdout the results while saving them in the output file
|
||||
flagVerbose = flag.String("verbose", "", "Overrides the output format when stdout the results while saving them in the output file.\nValid options are: json, yaml, csv, junit-xml, html, sonarqube, golint, sarif or text")
|
||||
|
||||
@@ -141,7 +148,7 @@ var (
|
||||
logger *log.Logger
|
||||
)
|
||||
|
||||
//#nosec
|
||||
// #nosec
|
||||
func usage() {
|
||||
usageText := fmt.Sprintf(usageText, Version, GitTag, BuildDate)
|
||||
fmt.Fprintln(os.Stderr, usageText)
|
||||
@@ -166,12 +173,12 @@ func usage() {
|
||||
func loadConfig(configFile string) (gosec.Config, error) {
|
||||
config := gosec.NewConfig()
|
||||
if configFile != "" {
|
||||
//#nosec
|
||||
// #nosec
|
||||
file, err := os.Open(configFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close() //#nosec G307
|
||||
defer file.Close() // #nosec G307
|
||||
if _, err := config.ReadFrom(file); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -246,11 +253,11 @@ func printReport(format string, color bool, rootPaths []string, reportInfo *gose
|
||||
}
|
||||
|
||||
func saveReport(filename, format string, rootPaths []string, reportInfo *gosec.ReportInfo) error {
|
||||
outfile, err := os.Create(filename) //#nosec G304
|
||||
outfile, err := os.Create(filename) // #nosec G304
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer outfile.Close() //#nosec G307
|
||||
defer outfile.Close() // #nosec G307
|
||||
err = report.CreateReport(outfile, format, false, rootPaths, reportInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -286,6 +293,19 @@ func filterIssues(issues []*gosec.Issue, severity gosec.Score, confidence gosec.
|
||||
return result, trueIssues
|
||||
}
|
||||
|
||||
func exit(issues []*gosec.Issue, errors map[string][]gosec.Error, noFail bool) {
|
||||
nsi := 0
|
||||
for _, issue := range issues {
|
||||
if len(issue.Suppressions) == 0 {
|
||||
nsi++
|
||||
}
|
||||
}
|
||||
if (nsi > 0 || len(errors) > 0) && !noFail {
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Makes sure some version information is set
|
||||
prepareVersionInfo()
|
||||
@@ -299,9 +319,9 @@ func main() {
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "\nError: failed to exclude the %q directory from scan", "vendor")
|
||||
}
|
||||
err = flag.Set("exclude-dir", ".git")
|
||||
err = flag.Set("exclude-dir", "\\.git/")
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "\nError: failed to exclude the %q directory from scan", ".git")
|
||||
fmt.Fprintf(os.Stderr, "\nError: failed to exclude the %q directory from scan", "\\.git/")
|
||||
}
|
||||
|
||||
// set for exclude
|
||||
@@ -315,9 +335,9 @@ func main() {
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// Ensure at least one file was specified
|
||||
if flag.NArg() == 0 {
|
||||
fmt.Fprintf(os.Stderr, "\nError: FILE [FILE...] or './...' expected\n") //#nosec
|
||||
// Ensure at least one file was specified or that the recursive -r flag was set.
|
||||
if flag.NArg() == 0 && !*flagRecursive {
|
||||
fmt.Fprintf(os.Stderr, "\nError: FILE [FILE...] or './...' or -r expected\n") // #nosec
|
||||
flag.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
@@ -334,7 +354,7 @@ func main() {
|
||||
}
|
||||
|
||||
if *flagQuiet {
|
||||
logger = log.New(ioutil.Discard, "", 0)
|
||||
logger = log.New(io.Discard, "", 0)
|
||||
} else {
|
||||
logger = log.New(logWriter, "[gosec] ", log.LstdFlags)
|
||||
}
|
||||
@@ -371,18 +391,24 @@ func main() {
|
||||
}
|
||||
|
||||
// Create the analyzer
|
||||
analyzer := gosec.NewAnalyzer(config, *flagScanTests, *flagExcludeGenerated, *flagTrackSuppressions, logger)
|
||||
analyzer := gosec.NewAnalyzer(config, *flagScanTests, *flagExcludeGenerated, *flagTrackSuppressions, *flagConcurrency, logger)
|
||||
analyzer.LoadRules(ruleList.RulesInfo())
|
||||
|
||||
excludedDirs := gosec.ExcludedDirsRegExp(flagDirsExclude)
|
||||
var packages []string
|
||||
for _, path := range flag.Args() {
|
||||
|
||||
paths := flag.Args()
|
||||
if len(paths) == 0 {
|
||||
paths = append(paths, "./...")
|
||||
}
|
||||
for _, path := range paths {
|
||||
pcks, err := gosec.PackagePaths(path, excludedDirs)
|
||||
if err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
packages = append(packages, pcks...)
|
||||
}
|
||||
|
||||
if len(packages) == 0 {
|
||||
logger.Fatal("No packages found")
|
||||
}
|
||||
@@ -434,10 +460,7 @@ func main() {
|
||||
}
|
||||
|
||||
// Finalize logging
|
||||
logWriter.Close() //#nosec
|
||||
logWriter.Close() // #nosec
|
||||
|
||||
// Do we have an issue? If so exit 1 unless NoFail is set
|
||||
if (len(issues) > 0 || len(errors) > 0) && !*flagNoFail {
|
||||
os.Exit(1)
|
||||
}
|
||||
exit(issues, errors, *flagNoFail)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
//go:build go1.14 || !go1.11
|
||||
// +build go1.14 !go1.11
|
||||
|
||||
// main
|
||||
package main
|
||||
|
||||
import (
|
||||
@@ -1,34 +0,0 @@
|
||||
//go:build go1.12 && !go1.14
|
||||
// +build go1.12,!go1.14
|
||||
|
||||
// This file can be removed once go1.13 is no longer supported
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"sort"
|
||||
)
|
||||
|
||||
func mapTLSVersions(tlsVersions []string) []int {
|
||||
var versions []int
|
||||
for _, tlsVersion := range tlsVersions {
|
||||
switch tlsVersion {
|
||||
case "TLSv1.3":
|
||||
versions = append(versions, tls.VersionTLS13)
|
||||
case "TLSv1.2":
|
||||
versions = append(versions, tls.VersionTLS12)
|
||||
case "TLSv1.1":
|
||||
versions = append(versions, tls.VersionTLS11)
|
||||
case "TLSv1":
|
||||
versions = append(versions, tls.VersionTLS10)
|
||||
case "SSLv3":
|
||||
// unsupported from go1.14
|
||||
versions = append(versions, tls.VersionSSL30)
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
sort.Ints(versions)
|
||||
return versions
|
||||
}
|
||||
@@ -1,6 +1,3 @@
|
||||
//go:build go1.12
|
||||
// +build go1.12
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
@@ -10,13 +7,14 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/mozilla/tls-observatory/constants"
|
||||
"golang.org/x/text/cases"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -82,7 +80,8 @@ func getTLSConfFromURL(url string) (*ServerSideTLSJson, error) {
|
||||
}
|
||||
|
||||
func getGoCipherConfig(name string, sstls ServerSideTLSJson) (goCipherConfiguration, error) {
|
||||
cipherConf := goCipherConfiguration{Name: strings.Title(name)}
|
||||
caser := cases.Title(language.English)
|
||||
cipherConf := goCipherConfiguration{Name: caser.String(name)}
|
||||
conf, ok := sstls.Configurations[name]
|
||||
if !ok {
|
||||
return cipherConf, fmt.Errorf("TLS configuration '%s' not found", name)
|
||||
@@ -188,7 +187,7 @@ func main() {
|
||||
}
|
||||
|
||||
outputPath := filepath.Join(dir, *outputFile)
|
||||
if err := ioutil.WriteFile(outputPath, src, 0o644); err != nil {
|
||||
if err := os.WriteFile(outputPath, src, 0o644); err != nil {
|
||||
log.Fatalf("Writing output: %s", err)
|
||||
} //#nosec G306
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -64,7 +63,7 @@ func (c Config) convertGlobals() {
|
||||
// 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)
|
||||
data, err := io.ReadAll(r)
|
||||
if err != nil {
|
||||
return int64(len(data)), err
|
||||
}
|
||||
|
||||
4
cosign.pub
Normal file
4
cosign.pub
Normal file
@@ -0,0 +1,4 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFphl7f2VuFRfsi4wqiLUCQ9xHQgV
|
||||
O2VMDNcvh+kxiymLXa+GkPzSKExFYIlVwfg13URvCiB+kFvITmLzuLiGQg==
|
||||
-----END PUBLIC KEY-----
|
||||
@@ -89,6 +89,11 @@ var (
|
||||
Description: "Creating and using insecure temporary files can leave application and system data vulnerable to attack.",
|
||||
Name: "Insecure Temporary File",
|
||||
},
|
||||
{
|
||||
ID: "400",
|
||||
Description: "The software does not properly control the allocation and maintenance of a limited resource, thereby enabling an actor to influence the amount of resources consumed, eventually leading to the exhaustion of available resources.",
|
||||
Name: "Uncontrolled Resource Consumption",
|
||||
},
|
||||
{
|
||||
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.",
|
||||
|
||||
@@ -19,7 +19,11 @@ func (w *Weakness) SprintURL() string {
|
||||
|
||||
// SprintID format the CWE ID
|
||||
func (w *Weakness) SprintID() string {
|
||||
return fmt.Sprintf("%s-%s", Acronym, w.ID)
|
||||
id := "0000"
|
||||
if w != nil {
|
||||
id = w.ID
|
||||
}
|
||||
return fmt.Sprintf("%s-%s", Acronym, id)
|
||||
}
|
||||
|
||||
// MarshalJSON print only id and URL
|
||||
|
||||
23
go.mod
23
go.mod
@@ -2,17 +2,26 @@ module github.com/securego/gosec/v2
|
||||
|
||||
require (
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/gookit/color v1.5.0
|
||||
github.com/lib/pq v1.10.4
|
||||
github.com/gookit/color v1.5.1
|
||||
github.com/lib/pq v1.10.6
|
||||
github.com/mozilla/tls-observatory v0.0.0-20210609171429-7bc42856d2e5
|
||||
github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354
|
||||
github.com/onsi/ginkgo/v2 v2.0.0
|
||||
github.com/onsi/gomega v1.17.0
|
||||
golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce
|
||||
github.com/onsi/ginkgo/v2 v2.1.4
|
||||
github.com/onsi/gomega v1.20.0
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616
|
||||
golang.org/x/text v0.3.7
|
||||
golang.org/x/tools v0.1.8
|
||||
golang.org/x/tools v0.1.12
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
||||
go 1.16
|
||||
require (
|
||||
github.com/google/go-cmp v0.5.8 // indirect
|
||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
go 1.19
|
||||
|
||||
89
go.sum
89
go.sum
@@ -89,8 +89,6 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
|
||||
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=
|
||||
@@ -103,7 +101,6 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V
|
||||
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=
|
||||
@@ -134,9 +131,7 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
|
||||
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.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
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=
|
||||
@@ -147,7 +142,8 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
|
||||
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/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
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=
|
||||
@@ -157,7 +153,6 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf
|
||||
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/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
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=
|
||||
@@ -167,8 +162,8 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/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.5.0 h1:1Opow3+BWDwqor78DcJkJCIwnkviFi+rrOANki9BUFw=
|
||||
github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo=
|
||||
github.com/gookit/color v1.5.1 h1:Vjg2VEcdHpwq+oY63s/ksHrgJYCTo0bwWvmmYWdE9fQ=
|
||||
github.com/gookit/color v1.5.1/go.mod h1:wZFzea4X8qN6vHOSP2apMb4/+w/orMznEzYsIHPaqKM=
|
||||
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=
|
||||
@@ -188,7 +183,6 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
|
||||
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/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/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=
|
||||
@@ -221,8 +215,8 @@ github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+
|
||||
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/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk=
|
||||
github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs=
|
||||
github.com/lib/pq v1.10.6/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=
|
||||
@@ -257,23 +251,16 @@ github.com/mwitkow/go-proto-validators v0.2.0/go.mod h1:ZfA1hW+UH/2ZHOWvQ3HnQaU0
|
||||
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.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
|
||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||
github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ=
|
||||
github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
|
||||
github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY=
|
||||
github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU=
|
||||
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.17.0 h1:9Luw4uT5HTjHTN8+aNcSThgH1vdXnmdJ8xIfZ4wyTRE=
|
||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q=
|
||||
github.com/onsi/gomega v1.20.0/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo=
|
||||
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=
|
||||
@@ -325,10 +312,9 @@ github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
|
||||
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/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
|
||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
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=
|
||||
@@ -347,8 +333,6 @@ github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZ
|
||||
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=
|
||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
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=
|
||||
@@ -376,8 +360,8 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
|
||||
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/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce h1:Roh6XWxHFKrPgC/EQhVubSAGQ6Ozk6IdxHSzt1mR0EI=
|
||||
golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
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=
|
||||
@@ -411,8 +395,8 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
|
||||
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.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
|
||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
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=
|
||||
@@ -442,15 +426,11 @@ golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/
|
||||
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-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
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=
|
||||
@@ -465,8 +445,6 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
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/sync v0.0.0-20210220032951-036812b2e83c/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=
|
||||
@@ -484,13 +462,10 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
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=
|
||||
@@ -510,22 +485,16 @@ golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
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-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 h1:id054HUawV2/6IGm2IV8KZQjqtwAOo2CYlOToYqa0d0=
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
||||
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.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@@ -579,14 +548,11 @@ golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roY
|
||||
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.8 h1:P1HhGGuLW4aAclzjtmJdf0mJOjVUZUzOTqkAkWL+l6w=
|
||||
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
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=
|
||||
@@ -665,9 +631,7 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
||||
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/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
||||
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=
|
||||
@@ -679,7 +643,6 @@ 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=
|
||||
@@ -690,11 +653,11 @@ 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=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/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=
|
||||
|
||||
59
helpers.go
59
helpers.go
@@ -34,12 +34,15 @@ import (
|
||||
// initialization only imports.
|
||||
//
|
||||
// Usage:
|
||||
// node, matched := MatchCallByPackage(n, ctx, "math/rand", "Read")
|
||||
//
|
||||
// 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
|
||||
importedName, found = GetAliasedName(pkg, c)
|
||||
if !found {
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
|
||||
if callExpr, ok := n.(*ast.CallExpr); ok {
|
||||
@@ -245,7 +248,7 @@ func GetBinaryExprOperands(be *ast.BinaryExpr) []ast.Node {
|
||||
}
|
||||
|
||||
// GetImportedName returns the name used for the package within the
|
||||
// code. It will resolve aliases and ignores initialization only imports.
|
||||
// code. It will ignore initialization only imports.
|
||||
func GetImportedName(path string, ctx *Context) (string, bool) {
|
||||
importName, imported := ctx.Imports.Imported[path]
|
||||
if !imported {
|
||||
@@ -256,20 +259,39 @@ func GetImportedName(path string, ctx *Context) (string, bool) {
|
||||
return "", false
|
||||
}
|
||||
|
||||
if alias, ok := ctx.Imports.Aliased[path]; ok {
|
||||
importName = alias
|
||||
return importName, true
|
||||
}
|
||||
|
||||
// GetAliasedName returns the aliased name used for the package within the
|
||||
// code. It will ignore initialization only imports.
|
||||
func GetAliasedName(path string, ctx *Context) (string, bool) {
|
||||
importName, imported := ctx.Imports.Aliased[path]
|
||||
if !imported {
|
||||
return "", false
|
||||
}
|
||||
|
||||
if _, initonly := ctx.Imports.InitOnly[path]; initonly {
|
||||
return "", false
|
||||
}
|
||||
|
||||
return importName, true
|
||||
}
|
||||
|
||||
// GetImportPath resolves the full import path of an identifier based on
|
||||
// the imports in the current context.
|
||||
// the imports in the current context(including aliases).
|
||||
func GetImportPath(name string, ctx *Context) (string, bool) {
|
||||
for path := range ctx.Imports.Imported {
|
||||
if imported, ok := GetImportedName(path, ctx); ok && imported == name {
|
||||
return path, true
|
||||
}
|
||||
}
|
||||
|
||||
for path := range ctx.Imports.Aliased {
|
||||
if imported, ok := GetAliasedName(path, ctx); ok && imported == name {
|
||||
return path, true
|
||||
}
|
||||
}
|
||||
|
||||
return "", false
|
||||
}
|
||||
|
||||
@@ -449,3 +471,28 @@ func RootPath(root string) (string, error) {
|
||||
root = strings.TrimSuffix(root, "...")
|
||||
return filepath.Abs(root)
|
||||
}
|
||||
|
||||
// GoVersion returns parsed version of Go from runtime
|
||||
func GoVersion() (int, int, int) {
|
||||
return parseGoVersion(runtime.Version())
|
||||
}
|
||||
|
||||
// parseGoVersion parses Go version.
|
||||
// example:
|
||||
// - go1.19rc2
|
||||
// - go1.19beta2
|
||||
// - go1.19.4
|
||||
// - go1.19
|
||||
func parseGoVersion(version string) (int, int, int) {
|
||||
exp := regexp.MustCompile(`go(\d+).(\d+)(?:.(\d+))?.*`)
|
||||
parts := exp.FindStringSubmatch(version)
|
||||
if len(parts) <= 1 {
|
||||
return 0, 0, 0
|
||||
}
|
||||
|
||||
major, _ := strconv.Atoi(parts[1])
|
||||
minor, _ := strconv.Atoi(parts[2])
|
||||
build, _ := strconv.Atoi(parts[3])
|
||||
|
||||
return major, minor, build
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package gosec_test
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
@@ -18,9 +17,9 @@ var _ = Describe("Helpers", func() {
|
||||
var dir string
|
||||
JustBeforeEach(func() {
|
||||
var err error
|
||||
dir, err = ioutil.TempDir("", "gosec")
|
||||
dir, err = os.MkdirTemp("", "gosec")
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
_, err = ioutil.TempFile(dir, "test*.go")
|
||||
_, err = os.MkdirTemp(dir, "test*.go")
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
})
|
||||
AfterEach(func() {
|
||||
|
||||
5
issue.go
5
issue.go
@@ -63,6 +63,9 @@ var ruleToCWE = map[string]string{
|
||||
"G108": "200",
|
||||
"G109": "190",
|
||||
"G110": "409",
|
||||
"G111": "22",
|
||||
"G112": "400",
|
||||
"G113": "190",
|
||||
"G201": "89",
|
||||
"G202": "89",
|
||||
"G203": "79",
|
||||
@@ -180,7 +183,7 @@ func NewIssue(ctx *Context, node ast.Node, ruleID, desc string, severity Score,
|
||||
|
||||
var code string
|
||||
if file, err := os.Open(fobj.Name()); err == nil {
|
||||
defer file.Close() //#nosec
|
||||
defer file.Close() // #nosec
|
||||
s := codeSnippetStartLine(node, fobj)
|
||||
e := codeSnippetEndLine(node, fobj)
|
||||
code, err = codeSnippet(file, s, e, node)
|
||||
|
||||
@@ -276,10 +276,11 @@ var _ = Describe("Formatter", func() {
|
||||
})
|
||||
Context("When using different report formats", func() {
|
||||
grules := []string{
|
||||
"G101", "G102", "G103", "G104", "G106",
|
||||
"G107", "G109", "G110", "G201", "G202", "G203", "G204",
|
||||
"G301", "G302", "G303", "G304", "G305", "G401", "G402",
|
||||
"G403", "G404", "G501", "G502", "G503", "G504", "G505",
|
||||
"G101", "G102", "G103", "G104", "G106", "G107", "G109",
|
||||
"G110", "G111", "G112", "G113", "G201", "G202", "G203",
|
||||
"G204", "G301", "G302", "G303", "G304", "G305", "G401",
|
||||
"G402", "G403", "G404", "G501", "G502", "G503", "G504",
|
||||
"G505", "G601",
|
||||
}
|
||||
|
||||
It("csv formatted report should contain the CWE mapping", func() {
|
||||
|
||||
@@ -15,7 +15,7 @@ func WriteReport(w io.Writer, data *gosec.ReportInfo) error {
|
||||
|
||||
for _, issue := range data.Issues {
|
||||
what := issue.What
|
||||
if issue.Cwe.ID != "" {
|
||||
if issue.Cwe != nil && issue.Cwe.ID != "" {
|
||||
what = fmt.Sprintf("[%s] %s", issue.Cwe.SprintID(), issue.What)
|
||||
}
|
||||
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
<meta charset="utf-8">
|
||||
<title>Golang Security Checker</title>
|
||||
<link rel="shortcut icon" type="image/png" href="https://securego.io/img/favicon.png">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css" integrity="sha512-IgmDkwzs96t4SrChW29No3NXBIBv8baW490zk5aXvhCD8vuZM3yUSkbyTBcXohkySecyzIrUwiF/qV0cuPcL3Q==" crossorigin="anonymous"/>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.4.0/styles/default.min.css" integrity="sha512-hasIneQUHlh06VNBe7f6ZcHmeRTLIaQWFd43YriJ0UND19bvYRauxthDg8E4eVNPm9bRUhr5JGeqH7FRFXQu5g==" crossorigin="anonymous"/>
|
||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.4.0/highlight.min.js" integrity="sha512-IaaKO80nPNs5j+VLxd42eK/7sYuXQmr+fyywCNA0e+C6gtQnuCXNtORe9xR4LqGPz5U9VpH+ff41wKs/ZmC3iA==" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.4.0/languages/go.min.js" integrity="sha512-cSV8KK6UAf1DR6Fh7+AU8Vn9q/X1CX60ktQ4R1gfaWuRnGL30r7LPiCdI3AdyiIjcalKZnyAkw5xH1QZQkDT7A==" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.4/css/bulma.min.css" integrity="sha512-HqxHUkJM0SYcbvxUw5P60SzdOTy/QVwA1JJrvaXJv4q7lmbDZCmZaqz01UPOaQveoxfYRv1tHozWGPMcuTBuvQ==" crossorigin="anonymous"/>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/styles/default.min.css" integrity="sha512-hasIneQUHlh06VNBe7f6ZcHmeRTLIaQWFd43YriJ0UND19bvYRauxthDg8E4eVNPm9bRUhr5JGeqH7FRFXQu5g==" crossorigin="anonymous"/>
|
||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/highlight.min.js" integrity="sha512-gU7kztaQEl7SHJyraPfZLQCNnrKdaQi5ndOyt4L4UPL/FHDd/uB9Je6KDARIqwnNNE27hnqoWLBq+Kpe4iHfeQ==" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/languages/go.min.js" integrity="sha512-6m7H6Bk2KM24+q+jB5KGHNS/qjz2+9E3DCJiDPHRUzqkMT6myjxX6ZG3poLVNIBn31lPhufOZcLHfYwsl53aHQ==" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/react/15.7.0/react.min.js" integrity="sha512-+TFn1Gqbwx/qgwW3NU1/YtFYTfHGeD1e/8YfJZzkb6TFEZP4SUwp1Az9DMeWh3qC0F+YPKXbV3YclMUwBTvO3g==" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-dom.min.js" integrity="sha512-8C49ZG/SaQnWaUgCHTU1o8uIQNYE6R8me38SwF26g2Q0byEXF4Jlvm+T/JAMHMeTBiEVPslSZRv9Xt4AV0pfmw==" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js" integrity="sha512-kp7YHLxuJDJcOzStgd6vtpxr4ZU9kjn77e6dBsivSz+pUuAuMlE2UTdKB7jjsWT84qbS8kdCWHPETnP/ctrFsA==" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.18.12/babel.min.js" integrity="sha512-AiVzbSxXraEL1ZC5MTLFal3rPCl56WrCIoXdur5U31SQ1byUZzgOnhqGeCFqwD6Owv9Q1DhS82Cpz+Tdym8hjQ==" crossorigin="anonymous"></script>
|
||||
<style>
|
||||
.field-label {
|
||||
min-width: 80px;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package html
|
||||
|
||||
import (
|
||||
|
||||
// use go embed to import template
|
||||
_ "embed"
|
||||
"html/template"
|
||||
|
||||
@@ -8,11 +8,15 @@ import (
|
||||
)
|
||||
|
||||
func generatePlaintext(issue *gosec.Issue) string {
|
||||
cweID := "CWE"
|
||||
if issue.Cwe != nil {
|
||||
cweID = issue.Cwe.ID
|
||||
}
|
||||
return "Results:\n" +
|
||||
"[" + issue.File + ":" + issue.Line + "] - " +
|
||||
issue.What + " (Confidence: " + strconv.Itoa(int(issue.Confidence)) +
|
||||
", Severity: " + strconv.Itoa(int(issue.Severity)) +
|
||||
", CWE: " + issue.Cwe.ID + ")\n" + "> " + html.EscapeString(issue.Code)
|
||||
", CWE: " + cweID + ")\n" + "> " + html.EscapeString(issue.Code)
|
||||
}
|
||||
|
||||
// GenerateReport Convert a gosec report to a JUnit Report
|
||||
|
||||
@@ -27,12 +27,14 @@ func GenerateReport(rootPaths []string, data *gosec.ReportInfo) (*Report, error)
|
||||
weaknesses := make(map[string]*cwe.Weakness)
|
||||
|
||||
for _, issue := range data.Issues {
|
||||
_, ok := weaknesses[issue.Cwe.ID]
|
||||
if !ok {
|
||||
weakness := cwe.Get(issue.Cwe.ID)
|
||||
weaknesses[issue.Cwe.ID] = weakness
|
||||
cweTaxon := parseSarifTaxon(weakness)
|
||||
cweTaxa = append(cweTaxa, cweTaxon)
|
||||
if issue.Cwe != nil {
|
||||
_, ok := weaknesses[issue.Cwe.ID]
|
||||
if !ok {
|
||||
weakness := cwe.Get(issue.Cwe.ID)
|
||||
weaknesses[issue.Cwe.ID] = weakness
|
||||
cweTaxon := parseSarifTaxon(weakness)
|
||||
cweTaxa = append(cweTaxa, cweTaxon)
|
||||
}
|
||||
}
|
||||
|
||||
r, ok := rulesIndices[issue.RuleID]
|
||||
@@ -71,9 +73,14 @@ func GenerateReport(rootPaths []string, data *gosec.ReportInfo) (*Report, error)
|
||||
|
||||
// parseSarifRule return SARIF rule field struct
|
||||
func parseSarifRule(issue *gosec.Issue) *ReportingDescriptor {
|
||||
cwe := gosec.GetCweByRule(issue.RuleID)
|
||||
name := issue.RuleID
|
||||
if cwe != nil {
|
||||
name = cwe.Name
|
||||
}
|
||||
return &ReportingDescriptor{
|
||||
ID: issue.RuleID,
|
||||
Name: issue.What,
|
||||
Name: name,
|
||||
ShortDescription: NewMultiformatMessageString(issue.What),
|
||||
FullDescription: NewMultiformatMessageString(issue.What),
|
||||
Help: NewMultiformatMessageString(fmt.Sprintf("%s\nSeverity: %s\nConfidence: %s\n",
|
||||
@@ -92,6 +99,9 @@ func parseSarifRule(issue *gosec.Issue) *ReportingDescriptor {
|
||||
}
|
||||
|
||||
func buildSarifReportingDescriptorRelationship(weakness *cwe.Weakness) *ReportingDescriptorRelationship {
|
||||
if weakness == nil {
|
||||
return nil
|
||||
}
|
||||
return &ReportingDescriptorRelationship{
|
||||
Target: &ReportingDescriptorReference{
|
||||
ID: weakness.ID,
|
||||
@@ -183,7 +193,24 @@ func parseSarifRegion(issue *gosec.Issue) (*Region, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
snippet := NewArtifactContent(issue.Code)
|
||||
var code string
|
||||
line := startLine
|
||||
codeLines := strings.Split(issue.Code, "\n")
|
||||
for _, codeLine := range codeLines {
|
||||
lineStart := fmt.Sprintf("%d:", line)
|
||||
if strings.HasPrefix(codeLine, lineStart) {
|
||||
code += strings.TrimSpace(
|
||||
strings.TrimPrefix(codeLine, lineStart))
|
||||
if endLine > startLine {
|
||||
code += "\n"
|
||||
}
|
||||
line++
|
||||
if line > endLine {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
snippet := NewArtifactContent(code)
|
||||
return NewRegion(startLine, endLine, col, col, "go").WithSnippet(snippet), nil
|
||||
}
|
||||
|
||||
|
||||
@@ -56,5 +56,59 @@ var _ = Describe("Sarif Formatter", func() {
|
||||
hasSuppressions, _ := regexp.MatchString(`"suppressions": \[(\s*){`, result)
|
||||
Expect(hasSuppressions).To(BeTrue())
|
||||
})
|
||||
It("sarif formatted report should contain the formatted one line code snippet", func() {
|
||||
ruleID := "G101"
|
||||
cwe := gosec.GetCweByRule(ruleID)
|
||||
code := "68: \t\t}\n69: \t\tvar data = template.HTML(v.TmplFile)\n70: \t\tisTmpl := true\n"
|
||||
expectedCode := "var data = template.HTML(v.TmplFile)"
|
||||
issue := gosec.Issue{
|
||||
File: "/home/src/project/test.go",
|
||||
Line: "69",
|
||||
Col: "14",
|
||||
RuleID: ruleID,
|
||||
What: "test",
|
||||
Confidence: gosec.High,
|
||||
Severity: gosec.High,
|
||||
Code: code,
|
||||
Cwe: cwe,
|
||||
Suppressions: []gosec.SuppressionInfo{
|
||||
{
|
||||
Kind: "kind",
|
||||
Justification: "justification",
|
||||
},
|
||||
},
|
||||
}
|
||||
reportInfo := gosec.NewReportInfo([]*gosec.Issue{&issue}, &gosec.Metrics{}, map[string][]gosec.Error{}).WithVersion("v2.7.0")
|
||||
sarifReport, err := sarif.GenerateReport([]string{}, reportInfo)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(sarifReport.Runs[0].Results[0].Locations[0].PhysicalLocation.Region.Snippet.Text).Should(Equal(expectedCode))
|
||||
})
|
||||
It("sarif formatted report should contain the formatted multiple line code snippet", func() {
|
||||
ruleID := "G101"
|
||||
cwe := gosec.GetCweByRule(ruleID)
|
||||
code := "68: }\n69: var data = template.HTML(v.TmplFile)\n70: isTmpl := true\n"
|
||||
expectedCode := "var data = template.HTML(v.TmplFile)\nisTmpl := true\n"
|
||||
issue := gosec.Issue{
|
||||
File: "/home/src/project/test.go",
|
||||
Line: "69-70",
|
||||
Col: "14",
|
||||
RuleID: ruleID,
|
||||
What: "test",
|
||||
Confidence: gosec.High,
|
||||
Severity: gosec.High,
|
||||
Code: code,
|
||||
Cwe: cwe,
|
||||
Suppressions: []gosec.SuppressionInfo{
|
||||
{
|
||||
Kind: "kind",
|
||||
Justification: "justification",
|
||||
},
|
||||
},
|
||||
}
|
||||
reportInfo := gosec.NewReportInfo([]*gosec.Issue{&issue}, &gosec.Metrics{}, map[string][]gosec.Error{}).WithVersion("v2.7.0")
|
||||
sarifReport, err := sarif.GenerateReport([]string{}, reportInfo)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(sarifReport.Runs[0].Results[0].Locations[0].PhysicalLocation.Region.Snippet.Text).Should(Equal(expectedCode))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -6,7 +6,7 @@ Golang errors in file: [{{ $filePath }}]:
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{ range $index, $issue := .Issues }}
|
||||
[{{ highlight $issue.FileLocation $issue.Severity $issue.NoSec }}] - {{ $issue.RuleID }}{{ if $issue.NoSec }} ({{- success "NoSec" -}}){{ end }} ({{ $issue.Cwe.SprintID }}): {{ $issue.What }} (Confidence: {{ $issue.Confidence}}, Severity: {{ $issue.Severity }})
|
||||
[{{ highlight $issue.FileLocation $issue.Severity $issue.NoSec }}] - {{ $issue.RuleID }}{{ if $issue.NoSec }} ({{- success "NoSec" -}}){{ end }} ({{ if $issue.Cwe }}{{$issue.Cwe.SprintID}}{{ else }}{{"CWE"}}{{ end }}): {{ $issue.What }} (Confidence: {{ $issue.Confidence}}, Severity: {{ $issue.Severity }})
|
||||
{{ printCode $issue }}
|
||||
|
||||
{{ end }}
|
||||
|
||||
@@ -3,9 +3,7 @@ package text
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
|
||||
// use go embed to import template
|
||||
_ "embed"
|
||||
_ "embed" // use go embed to import template
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
|
||||
64
rules/directory-traversal.go
Normal file
64
rules/directory-traversal.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package rules
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
"regexp"
|
||||
|
||||
"github.com/securego/gosec/v2"
|
||||
)
|
||||
|
||||
type traversal struct {
|
||||
pattern *regexp.Regexp
|
||||
gosec.MetaData
|
||||
}
|
||||
|
||||
func (r *traversal) ID() string {
|
||||
return r.MetaData.ID
|
||||
}
|
||||
|
||||
func (r *traversal) Match(n ast.Node, ctx *gosec.Context) (*gosec.Issue, error) {
|
||||
switch node := n.(type) {
|
||||
case *ast.CallExpr:
|
||||
return r.matchCallExpr(node, ctx)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (r *traversal) matchCallExpr(assign *ast.CallExpr, ctx *gosec.Context) (*gosec.Issue, error) {
|
||||
for _, i := range assign.Args {
|
||||
if basiclit, ok1 := i.(*ast.BasicLit); ok1 {
|
||||
if fun, ok2 := assign.Fun.(*ast.SelectorExpr); ok2 {
|
||||
if x, ok3 := fun.X.(*ast.Ident); ok3 {
|
||||
string := x.Name + "." + fun.Sel.Name + "(" + basiclit.Value + ")"
|
||||
if r.pattern.MatchString(string) {
|
||||
return gosec.NewIssue(ctx, assign, r.ID(), r.What, r.Severity, r.Confidence), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// NewDirectoryTraversal attempts to find the use of http.Dir("/")
|
||||
func NewDirectoryTraversal(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
pattern := `http\.Dir\("\/"\)|http\.Dir\('\/'\)`
|
||||
if val, ok := conf[id]; ok {
|
||||
conf := val.(map[string]interface{})
|
||||
if configPattern, ok := conf["pattern"]; ok {
|
||||
if cfgPattern, ok := configPattern.(string); ok {
|
||||
pattern = cfgPattern
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &traversal{
|
||||
pattern: regexp.MustCompile(pattern),
|
||||
MetaData: gosec.MetaData{
|
||||
ID: id,
|
||||
What: "Potential directory traversal",
|
||||
Confidence: gosec.Medium,
|
||||
Severity: gosec.Medium,
|
||||
},
|
||||
}, []ast.Node{(*ast.CallExpr)(nil)}
|
||||
}
|
||||
@@ -89,7 +89,7 @@ func NewNoErrorCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
whitelist.Add("hash.Hash", "Write")
|
||||
whitelist.Add("os", "Unsetenv")
|
||||
|
||||
if configured, ok := conf["G104"]; ok {
|
||||
if configured, ok := conf[id]; ok {
|
||||
if whitelisted, ok := configured.(map[string]interface{}); ok {
|
||||
for pkg, funcs := range whitelisted {
|
||||
if funcs, ok := funcs.([]interface{}); ok {
|
||||
|
||||
@@ -64,7 +64,7 @@ func (r *filePermissions) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, err
|
||||
|
||||
// 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", 0o600)
|
||||
mode := getConfiguredMode(conf, id, 0o600)
|
||||
return &filePermissions{
|
||||
mode: mode,
|
||||
pkgs: []string{"io/ioutil", "os"},
|
||||
@@ -81,7 +81,7 @@ func NewWritePerms(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
// 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", 0o600)
|
||||
mode := getConfiguredMode(conf, id, 0o600)
|
||||
return &filePermissions{
|
||||
mode: mode,
|
||||
pkgs: []string{"os"},
|
||||
@@ -98,7 +98,7 @@ func NewFilePerms(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
// 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", 0o750)
|
||||
mode := getConfiguredMode(conf, id, 0o750)
|
||||
return &filePermissions{
|
||||
mode: mode,
|
||||
pkgs: []string{"os"},
|
||||
|
||||
@@ -122,7 +122,7 @@ func NewHardcodedCredentials(id string, conf gosec.Config) (gosec.Rule, []ast.No
|
||||
perCharThreshold := 3.0
|
||||
ignoreEntropy := false
|
||||
truncateString := 16
|
||||
if val, ok := conf["G101"]; ok {
|
||||
if val, ok := conf[id]; ok {
|
||||
conf := val.(map[string]interface{})
|
||||
if configPattern, ok := conf["pattern"]; ok {
|
||||
if cfgPattern, ok := configPattern.(string); ok {
|
||||
|
||||
38
rules/http_serve.go
Normal file
38
rules/http_serve.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package rules
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
|
||||
"github.com/securego/gosec/v2"
|
||||
)
|
||||
|
||||
type httpServeWithoutTimeouts struct {
|
||||
gosec.MetaData
|
||||
pkg string
|
||||
calls []string
|
||||
}
|
||||
|
||||
func (r *httpServeWithoutTimeouts) ID() string {
|
||||
return r.MetaData.ID
|
||||
}
|
||||
|
||||
func (r *httpServeWithoutTimeouts) Match(n ast.Node, c *gosec.Context) (gi *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
|
||||
}
|
||||
|
||||
// NewHTTPServeWithoutTimeouts detects use of net/http serve functions that have no support for setting timeouts.
|
||||
func NewHTTPServeWithoutTimeouts(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
return &httpServeWithoutTimeouts{
|
||||
pkg: "net/http",
|
||||
calls: []string{"ListenAndServe", "ListenAndServeTLS", "Serve", "ServeTLS"},
|
||||
MetaData: gosec.MetaData{
|
||||
ID: id,
|
||||
What: "Use of net/http serve function that has no support for setting timeouts",
|
||||
Severity: gosec.Medium,
|
||||
Confidence: gosec.High,
|
||||
},
|
||||
}, []ast.Node{(*ast.CallExpr)(nil)}
|
||||
}
|
||||
@@ -61,7 +61,7 @@ func (i *integerOverflowCheck) Match(node ast.Node, ctx *gosec.Context) (*gosec.
|
||||
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 {
|
||||
if _, 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
|
||||
}
|
||||
|
||||
44
rules/math_big_rat.go
Normal file
44
rules/math_big_rat.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package rules
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
|
||||
"github.com/securego/gosec/v2"
|
||||
)
|
||||
|
||||
type usingOldMathBig struct {
|
||||
gosec.MetaData
|
||||
calls gosec.CallList
|
||||
}
|
||||
|
||||
func (r *usingOldMathBig) ID() string {
|
||||
return r.MetaData.ID
|
||||
}
|
||||
|
||||
func (r *usingOldMathBig) Match(node ast.Node, ctx *gosec.Context) (gi *gosec.Issue, err error) {
|
||||
if callExpr := r.calls.ContainsPkgCallExpr(node, ctx, false); callExpr == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
confidence := gosec.Low
|
||||
major, minor, build := gosec.GoVersion()
|
||||
if major == 1 && (minor == 16 && build < 14 || minor == 17 && build < 7) {
|
||||
confidence = gosec.Medium
|
||||
}
|
||||
|
||||
return gosec.NewIssue(ctx, node, r.ID(), r.What, r.Severity, confidence), nil
|
||||
}
|
||||
|
||||
// NewUsingOldMathBig rule detects the use of Rat.SetString from math/big.
|
||||
func NewUsingOldMathBig(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
calls := gosec.NewCallList()
|
||||
calls.Add("math/big.Rat", "SetString")
|
||||
return &usingOldMathBig{
|
||||
calls: calls,
|
||||
MetaData: gosec.MetaData{
|
||||
ID: id,
|
||||
What: "Potential uncontrolled memory consumption in Rat.SetString (CVE-2022-23772)",
|
||||
Severity: gosec.High,
|
||||
},
|
||||
}, []ast.Node{(*ast.CallExpr)(nil)}
|
||||
}
|
||||
@@ -73,6 +73,10 @@ func Generate(trackSuppressions bool, filters ...RuleFilter) RuleList {
|
||||
{"G108", "Profiling endpoint is automatically exposed", NewPprofCheck},
|
||||
{"G109", "Converting strconv.Atoi result to int32/int16", NewIntegerOverflowCheck},
|
||||
{"G110", "Detect io.Copy instead of io.CopyN when decompression", NewDecompressionBombCheck},
|
||||
{"G111", "Detect http.Dir('/') as a potential risk", NewDirectoryTraversal},
|
||||
{"G112", "Detect ReadHeaderTimeout not configured as a potential risk", NewSlowloris},
|
||||
{"G113", "Usage of Rat.SetString in math/big with an overflow", NewUsingOldMathBig},
|
||||
{"G114", "Use of net/http serve function that has no support for setting timeouts", NewHTTPServeWithoutTimeouts},
|
||||
|
||||
// injection
|
||||
{"G201", "SQL query construction using format string", NewSQLStrFormat},
|
||||
|
||||
@@ -24,7 +24,7 @@ var _ = Describe("gosec rules", func() {
|
||||
BeforeEach(func() {
|
||||
logger, _ = testutils.NewLogger()
|
||||
config = gosec.NewConfig()
|
||||
analyzer = gosec.NewAnalyzer(config, tests, false, false, logger)
|
||||
analyzer = gosec.NewAnalyzer(config, tests, false, false, 1, logger)
|
||||
runner = func(rule string, samples []testutils.CodeSample) {
|
||||
for n, sample := range samples {
|
||||
analyzer.Reset()
|
||||
@@ -90,6 +90,22 @@ var _ = Describe("gosec rules", func() {
|
||||
runner("G110", testutils.SampleCodeG110)
|
||||
})
|
||||
|
||||
It("should detect potential directory traversal", func() {
|
||||
runner("G111", testutils.SampleCodeG111)
|
||||
})
|
||||
|
||||
It("should detect potential slowloris attack", func() {
|
||||
runner("G112", testutils.SampleCodeG112)
|
||||
})
|
||||
|
||||
It("should detect potential uncontrolled memory consumption in Rat.SetString", func() {
|
||||
runner("G113", testutils.SampleCodeG113)
|
||||
})
|
||||
|
||||
It("should detect uses of net/http serve functions that have no support for setting timeouts", func() {
|
||||
runner("G114", testutils.SampleCodeG114)
|
||||
})
|
||||
|
||||
It("should detect sql injection via format strings", func() {
|
||||
runner("G201", testutils.SampleCodeG201)
|
||||
})
|
||||
|
||||
70
rules/slowloris.go
Normal file
70
rules/slowloris.go
Normal file
@@ -0,0 +1,70 @@
|
||||
// (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 slowloris struct {
|
||||
gosec.MetaData
|
||||
}
|
||||
|
||||
func (r *slowloris) ID() string {
|
||||
return r.MetaData.ID
|
||||
}
|
||||
|
||||
func containsReadHeaderTimeout(node *ast.CompositeLit) bool {
|
||||
if node == nil {
|
||||
return false
|
||||
}
|
||||
for _, elt := range node.Elts {
|
||||
if kv, ok := elt.(*ast.KeyValueExpr); ok {
|
||||
if ident, ok := kv.Key.(*ast.Ident); ok {
|
||||
if ident.Name == "ReadHeaderTimeout" || ident.Name == "ReadTimeout" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (r *slowloris) Match(n ast.Node, ctx *gosec.Context) (*gosec.Issue, error) {
|
||||
switch node := n.(type) {
|
||||
case *ast.CompositeLit:
|
||||
actualType := ctx.Info.TypeOf(node.Type)
|
||||
if actualType != nil && actualType.String() == "net/http.Server" {
|
||||
if !containsReadHeaderTimeout(node) {
|
||||
return gosec.NewIssue(ctx, node, r.ID(), r.What, r.Severity, r.Confidence), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// NewSlowloris attempts to find the http.Server struct and check if the ReadHeaderTimeout is configured.
|
||||
func NewSlowloris(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
return &slowloris{
|
||||
MetaData: gosec.MetaData{
|
||||
ID: id,
|
||||
What: "Potential Slowloris Attack because ReadHeaderTimeout is not configured in the http.Server",
|
||||
Confidence: gosec.Low,
|
||||
Severity: gosec.Medium,
|
||||
},
|
||||
}, []ast.Node{(*ast.CompositeLit)(nil)}
|
||||
}
|
||||
77
rules/sql.go
77
rules/sql.go
@@ -15,9 +15,9 @@
|
||||
package rules
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/securego/gosec/v2"
|
||||
)
|
||||
@@ -30,6 +30,51 @@ type sqlStatement struct {
|
||||
patterns []*regexp.Regexp
|
||||
}
|
||||
|
||||
var sqlCallIdents = map[string]map[string]int{
|
||||
"*database/sql.DB": {
|
||||
"Exec": 0,
|
||||
"ExecContext": 1,
|
||||
"Query": 0,
|
||||
"QueryContext": 1,
|
||||
"QueryRow": 0,
|
||||
"QueryRowContext": 1,
|
||||
"Prepare": 0,
|
||||
"PrepareContext": 1,
|
||||
},
|
||||
"*database/sql.Tx": {
|
||||
"Exec": 0,
|
||||
"ExecContext": 1,
|
||||
"Query": 0,
|
||||
"QueryContext": 1,
|
||||
"QueryRow": 0,
|
||||
"QueryRowContext": 1,
|
||||
"Prepare": 0,
|
||||
"PrepareContext": 1,
|
||||
},
|
||||
}
|
||||
|
||||
// findQueryArg locates the argument taking raw SQL
|
||||
func findQueryArg(call *ast.CallExpr, ctx *gosec.Context) (ast.Expr, error) {
|
||||
typeName, fnName, err := gosec.GetCallInfo(call, ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
i := -1
|
||||
if ni, ok := sqlCallIdents[typeName]; ok {
|
||||
if i, ok = ni[fnName]; !ok {
|
||||
i = -1
|
||||
}
|
||||
}
|
||||
if i == -1 {
|
||||
return nil, fmt.Errorf("SQL argument index not found for %s.%s", typeName, fnName)
|
||||
}
|
||||
if i >= len(call.Args) {
|
||||
return nil, nil
|
||||
}
|
||||
query := call.Args[i]
|
||||
return query, nil
|
||||
}
|
||||
|
||||
func (s *sqlStatement) ID() string {
|
||||
return s.MetaData.ID
|
||||
}
|
||||
@@ -69,16 +114,10 @@ func (s *sqlStrConcat) checkObject(n *ast.Ident, c *gosec.Context) bool {
|
||||
|
||||
// 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)
|
||||
query, err := findQueryArg(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)
|
||||
@@ -137,8 +176,11 @@ func NewSQLStrConcat(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
},
|
||||
}
|
||||
|
||||
rule.AddAll("*database/sql.DB", "Query", "QueryContext", "QueryRow", "QueryRowContext", "Exec", "ExecContext", "Prepare", "PrepareContext")
|
||||
rule.AddAll("*database/sql.Tx", "Query", "QueryContext", "QueryRow", "QueryRowContext", "Exec", "ExecContext", "Prepare", "PrepareContext")
|
||||
for s, si := range sqlCallIdents {
|
||||
for i := range si {
|
||||
rule.Add(s, i)
|
||||
}
|
||||
}
|
||||
return rule, []ast.Node{(*ast.AssignStmt)(nil), (*ast.ExprStmt)(nil)}
|
||||
}
|
||||
|
||||
@@ -171,16 +213,10 @@ func (s *sqlStrFormat) constObject(e ast.Expr, c *gosec.Context) bool {
|
||||
}
|
||||
|
||||
func (s *sqlStrFormat) checkQuery(call *ast.CallExpr, ctx *gosec.Context) (*gosec.Issue, error) {
|
||||
_, fnName, err := gosec.GetCallInfo(call, ctx)
|
||||
query, err := findQueryArg(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
|
||||
@@ -306,8 +342,11 @@ func NewSQLStrFormat(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
},
|
||||
},
|
||||
}
|
||||
rule.AddAll("*database/sql.DB", "Query", "QueryContext", "QueryRow", "QueryRowContext", "Exec", "ExecContext", "Prepare", "PrepareContext")
|
||||
rule.AddAll("*database/sql.Tx", "Query", "QueryContext", "QueryRow", "QueryRowContext", "Exec", "ExecContext", "Prepare", "PrepareContext")
|
||||
for s, si := range sqlCallIdents {
|
||||
for i := range si {
|
||||
rule.Add(s, i)
|
||||
}
|
||||
}
|
||||
rule.fmtCalls.AddAll("fmt", "Sprint", "Sprintf", "Sprintln", "Fprintf")
|
||||
rule.noIssue.AddAll("os", "Stdout", "Stderr")
|
||||
rule.noIssueQuoted.Add("github.com/lib/pq", "QuoteIdentifier")
|
||||
|
||||
@@ -77,6 +77,13 @@ func (r *subprocess) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) {
|
||||
return gosec.NewIssue(c, n, r.ID(), "Subprocess launched with variable", gosec.Medium, gosec.High), nil
|
||||
}
|
||||
}
|
||||
case *ast.ValueSpec:
|
||||
_, valueSpec := ident.Obj.Decl.(*ast.ValueSpec)
|
||||
if variable && valueSpec {
|
||||
if !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) {
|
||||
|
||||
@@ -54,7 +54,7 @@ func NewTemplateCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
ID: id,
|
||||
Severity: gosec.Medium,
|
||||
Confidence: gosec.Low,
|
||||
What: "this method will not auto-escape HTML. Verify data is well formed.",
|
||||
What: "The used method does not auto-escape HTML. This can potentially lead to 'Cross-site Scripting' vulnerabilities, in case the attacker controls the input.",
|
||||
},
|
||||
}, []ast.Node{(*ast.CallExpr)(nil)}
|
||||
}
|
||||
|
||||
23
rules/tls.go
23
rules/tls.go
@@ -88,7 +88,16 @@ func (t *insecureConfigTLS) processTLSConfVal(n *ast.KeyValueExpr, c *gosec.Cont
|
||||
|
||||
case "MinVersion":
|
||||
if d, ok := n.Value.(*ast.Ident); ok {
|
||||
if vs, ok := d.Obj.Decl.(*ast.ValueSpec); ok && len(vs.Values) > 0 {
|
||||
obj := d.Obj
|
||||
if obj == nil {
|
||||
for _, f := range c.PkgFiles {
|
||||
obj = f.Scope.Lookup(d.Name)
|
||||
if obj != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if vs, ok := obj.Decl.(*ast.ValueSpec); ok && len(vs.Values) > 0 {
|
||||
if s, ok := vs.Values[0].(*ast.SelectorExpr); ok {
|
||||
x := s.X.(*ast.Ident).Name
|
||||
sel := s.Sel.Name
|
||||
@@ -113,8 +122,10 @@ func (t *insecureConfigTLS) processTLSConfVal(n *ast.KeyValueExpr, c *gosec.Cont
|
||||
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)
|
||||
if pkg, ok := se.X.(*ast.Ident); ok {
|
||||
if ip, ok := gosec.GetImportPath(pkg.Name, c); ok && ip == "crypto/tls" {
|
||||
t.actualMinVersion = t.mapVersion(se.Sel.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -124,8 +135,10 @@ func (t *insecureConfigTLS) processTLSConfVal(n *ast.KeyValueExpr, c *gosec.Cont
|
||||
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)
|
||||
if pkg, ok := se.X.(*ast.Ident); ok {
|
||||
if ip, ok := gosec.GetImportPath(pkg.Name, c); ok && ip == "crypto/tls" {
|
||||
t.actualMaxVersion = t.mapVersion(se.Sel.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package testutils
|
||||
import (
|
||||
"fmt"
|
||||
"go/build"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
@@ -30,7 +29,7 @@ type TestPackage struct {
|
||||
// NewTestPackage will create a new and empty package. Must call Close() to cleanup
|
||||
// auxiliary files
|
||||
func NewTestPackage() *TestPackage {
|
||||
workingDir, err := ioutil.TempDir("", "gosecs_test")
|
||||
workingDir, err := os.MkdirTemp("", "gosecs_test")
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
@@ -53,7 +52,7 @@ func (p *TestPackage) write() error {
|
||||
return nil
|
||||
}
|
||||
for filename, content := range p.Files {
|
||||
if e := ioutil.WriteFile(filename, []byte(content), 0o644); e != nil {
|
||||
if e := os.WriteFile(filename, []byte(content), 0o644); e != nil {
|
||||
return e
|
||||
} //#nosec G306
|
||||
}
|
||||
|
||||
@@ -795,7 +795,8 @@ func main() {
|
||||
}
|
||||
value := int32(bigValue)
|
||||
fmt.Println(value)
|
||||
}`}, 1, gosec.NewConfig()}, {[]string{`
|
||||
}`}, 1, gosec.NewConfig()},
|
||||
{[]string{`
|
||||
package main
|
||||
|
||||
import (
|
||||
@@ -811,7 +812,8 @@ func main() {
|
||||
if int16(bigValue) < 0 {
|
||||
fmt.Println(bigValue)
|
||||
}
|
||||
}`}, 1, gosec.NewConfig()}, {[]string{`
|
||||
}`}, 1, gosec.NewConfig()},
|
||||
{[]string{`
|
||||
package main
|
||||
|
||||
import (
|
||||
@@ -825,7 +827,8 @@ func main() {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println(bigValue)
|
||||
}`}, 0, gosec.NewConfig()}, {[]string{`
|
||||
}`}, 0, gosec.NewConfig()},
|
||||
{[]string{`
|
||||
package main
|
||||
|
||||
import (
|
||||
@@ -846,7 +849,8 @@ func test() {
|
||||
bigValue := 30
|
||||
value := int32(bigValue)
|
||||
fmt.Println(value)
|
||||
}`}, 0, gosec.NewConfig()}, {[]string{`
|
||||
}`}, 0, gosec.NewConfig()},
|
||||
{[]string{`
|
||||
package main
|
||||
|
||||
import (
|
||||
@@ -862,6 +866,17 @@ func main() {
|
||||
}
|
||||
v := int32(value)
|
||||
fmt.Println(v)
|
||||
}`}, 0, gosec.NewConfig()},
|
||||
{[]string{`
|
||||
package main
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
func main() {
|
||||
a, err := strconv.Atoi("a")
|
||||
b := int32(a) //#nosec G109
|
||||
fmt.Println(b, err)
|
||||
}`}, 0, gosec.NewConfig()},
|
||||
}
|
||||
|
||||
@@ -982,6 +997,197 @@ func main() {
|
||||
}`}, 0, gosec.NewConfig()},
|
||||
}
|
||||
|
||||
// SampleCodeG111 - potential directory traversal
|
||||
SampleCodeG111 = []CodeSample{
|
||||
{[]string{`
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
http.Handle("/bad/", http.StripPrefix("/bad/", http.FileServer(http.Dir("/"))))
|
||||
http.HandleFunc("/", HelloServer)
|
||||
log.Fatal(http.ListenAndServe(":"+os.Getenv("PORT"), nil))
|
||||
}
|
||||
|
||||
func HelloServer(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:])
|
||||
}`}, 1, gosec.NewConfig()},
|
||||
}
|
||||
|
||||
// SampleCodeG112 - potential slowloris attack
|
||||
SampleCodeG112 = []CodeSample{
|
||||
{[]string{`
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func main() {
|
||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:])
|
||||
})
|
||||
err := (&http.Server{
|
||||
Addr: ":1234",
|
||||
}).ListenAndServe()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
`}, 1, gosec.NewConfig()},
|
||||
{[]string{`
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func main() {
|
||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:])
|
||||
})
|
||||
server := &http.Server{
|
||||
Addr: ":1234",
|
||||
ReadHeaderTimeout: 3 * time.Second,
|
||||
}
|
||||
err := server.ListenAndServe()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
`}, 0, gosec.NewConfig()},
|
||||
{[]string{`
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func main() {
|
||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:])
|
||||
})
|
||||
server := &http.Server{
|
||||
Addr: ":1234",
|
||||
ReadTimeout: 1 * time.Second,
|
||||
}
|
||||
err := server.ListenAndServe()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
`}, 0, gosec.NewConfig()},
|
||||
}
|
||||
|
||||
// SampleCodeG113 - Usage of Rat.SetString in math/big with an overflow
|
||||
SampleCodeG113 = []CodeSample{
|
||||
{[]string{
|
||||
`
|
||||
package main
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func main() {
|
||||
r := big.Rat{}
|
||||
r.SetString("13e-9223372036854775808")
|
||||
|
||||
fmt.Println(r)
|
||||
}`,
|
||||
}, 1, gosec.NewConfig()},
|
||||
}
|
||||
|
||||
// SampleCodeG114 - Use of net/http serve functions that have no support for setting timeouts
|
||||
SampleCodeG114 = []CodeSample{
|
||||
{[]string{
|
||||
`
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := http.ListenAndServe(":8080", nil)
|
||||
log.Fatal(err)
|
||||
}`,
|
||||
}, 1, gosec.NewConfig()},
|
||||
{
|
||||
[]string{
|
||||
`
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := http.ListenAndServeTLS(":8443", "cert.pem", "key.pem", nil)
|
||||
log.Fatal(err)
|
||||
}`,
|
||||
}, 1, gosec.NewConfig(),
|
||||
},
|
||||
{
|
||||
[]string{
|
||||
`
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func main() {
|
||||
l, err := net.Listen("tcp", ":8080")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer l.Close()
|
||||
err = http.Serve(l, nil)
|
||||
log.Fatal(err)
|
||||
}`,
|
||||
}, 1, gosec.NewConfig(),
|
||||
},
|
||||
{
|
||||
[]string{
|
||||
`
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func main() {
|
||||
l, err := net.Listen("tcp", ":8443")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer l.Close()
|
||||
err = http.ServeTLS(l, nil, "cert.pem", "key.pem")
|
||||
log.Fatal(err)
|
||||
}`,
|
||||
}, 1, gosec.NewConfig(),
|
||||
},
|
||||
}
|
||||
|
||||
// SampleCodeG201 - SQL injection via format string
|
||||
SampleCodeG201 = []CodeSample{
|
||||
{[]string{`
|
||||
@@ -1890,6 +2096,28 @@ func main() {
|
||||
log.Printf("Command finished with error: %v", err)
|
||||
}
|
||||
`}, 1, gosec.NewConfig()},
|
||||
{[]string{`
|
||||
// Initializing a local variable using a environmental
|
||||
// variable is consider as a dangerous user input
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var run = "sleep" + os.Getenv("SOMETHING")
|
||||
cmd := exec.Command(run, "5")
|
||||
err := cmd.Start()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
log.Printf("Waiting for command to finish...")
|
||||
err = cmd.Wait()
|
||||
log.Printf("Command finished with error: %v", err)
|
||||
}`}, 1, gosec.NewConfig()},
|
||||
}
|
||||
|
||||
// SampleCodeG301 - mkdir permission check
|
||||
@@ -2838,6 +3066,40 @@ func TlsConfig1() *tls.Config {
|
||||
return &tls.Config{MinVersion: 0x0304}
|
||||
}
|
||||
`}, 1, gosec.NewConfig()},
|
||||
{[]string{`
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func main() {
|
||||
cfg := tls.Config{
|
||||
MinVersion: MinVer,
|
||||
}
|
||||
fmt.Println("tls min version", cfg.MinVersion)
|
||||
}
|
||||
`, `
|
||||
package main
|
||||
|
||||
import "crypto/tls"
|
||||
|
||||
const MinVer = tls.VersionTLS13
|
||||
`}, 0, gosec.NewConfig()},
|
||||
{[]string{`
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
cryptotls "crypto/tls"
|
||||
)
|
||||
|
||||
func main() {
|
||||
_ = tls.Config{MinVersion: tls.VersionTLS12}
|
||||
_ = cryptotls.Config{MinVersion: cryptotls.VersionTLS12}
|
||||
}
|
||||
`}, 0, gosec.NewConfig()},
|
||||
}
|
||||
|
||||
// SampleCodeG403 - weak key strength
|
||||
|
||||
Reference in New Issue
Block a user