Compare commits

...

55 Commits

Author SHA1 Message Date
Cosmin Cojocar
19fa856bad fix: make sure that nil Cwe pointer is handled when getting the CWE ID 2022-08-20 13:32:31 +02:00
Cosmin Cojocar
62fa4b4e9b test: remove white spaces from template 2022-08-20 13:08:50 +02:00
Cosmin Cojocar
074dc71087 fix: handle nil CWE pointer in text template 2022-08-20 13:08:50 +02:00
renovate[bot]
79a5b13bdb chore(deps): update dependency babel-standalone to v7 2022-08-15 09:17:13 +02:00
Cosmin Cojocar
97f03d9939 chore: update module go to 1.19
Signed-off-by: Cosmin Cojocar <gcojocar@adobe.com>
2022-08-08 10:56:19 +02:00
Cosmin Cojocar
0ba05e160a chore: fix lint warnings
Signed-off-by: Cosmin Cojocar <gcojocar@adobe.com>
2022-08-08 10:56:19 +02:00
Cosmin Cojocar
d3933f9e14 chore: add support for Go 1.19
Signed-off-by: Cosmin Cojocar <gcojocar@adobe.com>
2022-08-08 10:56:19 +02:00
Ludovic Fernandez
4e68fb5b15 fix: parsing of the Go version (#844)
* fix: parsing of the Go version

* fix: convert pseudo directive to comment
2022-08-08 09:28:41 +02:00
Ville Skyttä
0c8e63ed86 Detect use of net/http functions that have no support for setting timeouts (#842)
https://blog.cloudflare.com/the-complete-guide-to-golang-net-http-timeouts/
https://blog.cloudflare.com/exposing-go-on-the-internet/

Closes https://github.com/securego/gosec/issues/833
2022-08-02 17:16:44 +02:00
Ville Skyttä
6a26c231fc Refactor SQL rules for better extensibility (#841)
Remove hardwired assumption and heuristics on index of arg taking a SQL
string, be explicit about it instead.
2022-08-02 15:25:30 +02:00
renovate[bot]
1b0873a235 chore(deps): update module golang.org/x/tools to v0.1.12 (#840)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-02 08:08:23 +02:00
Cosmin Cojocar
845483e0b1 Fix lint warning
Signed-off-by: Cosmin Cojocar <gcojocar@adobe.com>
2022-07-28 11:10:00 +02:00
Cosmin Cojocar
45bf9a6095 Check the suppressed issues when generating the exit code
Signed-off-by: Cosmin Cojocar <gcojocar@adobe.com>
2022-07-28 11:10:00 +02:00
Dmitry Golushko
a5982fb6a6 Fix for G402. Check package path instead of package name (#838) 2022-07-28 08:51:30 +02:00
Ziqi Zhao
ea6d49d1b5 fix G204 bugs (#835)
Signed-off-by: Ziqi Zhao <zhaoziqi9146@gmail.com>
2022-07-26 11:08:43 +02:00
Cosmin Cojocar
21fcd2f904 Phase out support for Go 1.16 since is not supported anymore by Go team (#837)
Signed-off-by: Cosmin Cojocar <gcojocar@adobe.com>
2022-07-26 11:08:30 +02:00
renovate[bot]
3cda47a9b8 chore(deps): update all dependencies (#836)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-26 10:57:36 +02:00
renovate[bot]
0212c83699 chore(deps): update dependency highlight.js to v11.6.0 (#830)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-18 16:20:54 +02:00
Tim Costa
9a25f4ed2d fix: filepaths with git anywhere in them being erroneously excluded (#828)
Co-authored-by: Tim Costa <timcosta@amazon.com>
2022-07-06 06:46:49 +02:00
云微
602ced7e71 Fix wrong location for G109 (#829)
Before this commit, G109 will report on `strconv.Atoi`.
After this, it will report on the convertion like`int32(a)`.
2022-07-06 06:37:11 +02:00
renovate[bot]
7dd9ddd583 chore(deps): update golang.org/x/crypto digest to 0559593 (#826)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-06 06:34:31 +02:00
云微
b0f3e78e07 fix ReadTimeout for G112 rule 2022-06-23 14:58:13 +02:00
Sascha Grunert
05f3ca80f9 Pin cosign-installer to v2 (#824)
We now have tags available in the cosign-installer, which allows us to
pin the latest release via `v2`.

Signed-off-by: Sascha Grunert <sgrunert@redhat.com>
2022-06-23 14:50:50 +02:00
renovate[bot]
a9b0ef0a11 chore(deps): update all dependencies (#822)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-06-13 19:48:12 +02:00
Vladimir Severov
9c19cb6501 Add check for usage of Rat.SetString in math/big with an overflow error (#819)
* Add check for usage of Rat.SetString in math/big with an overflow error

Rat.SetString in math/big in Go before 1.16.14 and 1.17.x before 1.17.7
has an overflow that can lead to Uncontrolled Memory Consumption.

It is the CVE-2022-23772.

* Use ContainsPkgCallExpr instead of manual parsing
2022-06-03 00:19:51 +02:00
Peter Dave Hello
fb587c1d10 Remove additional --update for apk in Dockerfile (#818)
There is no need to use --update with --no-cache when using apk on
Alpine Linux, as using --no-cache will fetch the index every time and
leave no local cache, so the index will always be the latest without
temporary files remain in the image.
2022-05-31 15:06:52 +02:00
Thomas Gorham
c3ede62822 Update x/tools to pick up fix for golang/go#51629 (#817) 2022-05-29 17:41:10 +02:00
renovate[bot]
0a929c7b6c chore(deps): update all dependencies (#816)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-05-29 17:36:29 +02:00
renovate[bot]
12be14859b chore(deps): update all dependencies (#812)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-05-09 12:02:57 +02:00
renovate[bot]
0dcc3362ae chore(deps): update all dependencies (#811)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-05-02 21:00:33 +02:00
云微
34d144b3fa Add new rule for Slowloris Attack 2022-04-30 12:38:50 +02:00
Cosmin Cojocar
a64cde55a4 Fix the dependencies after renovate upate (#806) 2022-04-11 20:21:09 +02:00
renovate[bot]
b69c3d48c8 chore(deps): update all dependencies (#805)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-04-11 20:12:37 +02:00
Cosmin Cojocar
89dfdc0c97 Update the description message of template rule (#803) 2022-04-05 07:41:36 +02:00
Gautam Mehta
0791d31471 Fix typo in ReadMe (#802) 2022-04-05 07:15:22 +02:00
Cosmin Cojocar
2ef1d9a037 Fix build after renovate update (#800) 2022-03-28 20:38:14 +02:00
robot-5
afc9903ba9 Fix use rule IDs to retrieve the rule config 2022-03-28 20:28:02 +02:00
renovate[bot]
82eaa12696 chore(deps): update all dependencies (#796)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-03-28 20:23:59 +02:00
Cosmin Cojocar
607d607b51 Enable Go 1.18 in the ci and release workflows
* Enable Go 1.18 in the ci and release workflows

* Fix lint warning

* Add golangci as a make target
2022-03-21 16:53:22 +01:00
Cosmin Cojocar
b99b5f7838 Fix the lint action after upgrade (#790) 2022-03-14 14:19:29 +01:00
renovate[bot]
8af0af7611 chore(deps): update all dependencies (#789)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-03-14 14:10:28 +01:00
Per Arn
ea5d31f7f5 Add a recursive flag -r to skip specifying ./... path
* added recursive flag to skip specifying ./... path

* refactored to remove code duplication
2022-03-07 10:31:22 +01:00
Calin Capitanu
48bbf96b56 Adds directory traversal for Http.Dir("/") 2022-03-06 10:58:47 +01:00
Cosmin Cojocar
26f10e0a7a Extend the release action to sign the docker image and binary files with cosign (#781)
* Extend the release action to sign the docker image and binary files with cosign

* Fix lint warnings

* Fix the ling warnings

* Fix the lint warnings
2022-02-22 21:33:42 +01:00
kruskal
7d539ed494 feat: add concurrency option to parallelize package loading (#778)
* feat: add concurrency option to parallelize package loading

* refactor: move wg.add inside the for loop

* fix: gracefully stop the workers on error

* test: add test for concurrent scan
2022-02-16 18:23:37 +01:00
Renovate Bot
43577cebb7 chore(deps): update all dependencies 2022-02-16 12:21:25 +01:00
Cosmin Cojocar
c0680bb6a3 Process the code snippet before adding it to the SARIF report
Preprocess the code snippet from the issue in order to extract only the line(s)
of code where the issue is located.  In addition remove the line numbers and whitespaces
before writing the code snippet into the SARIF report.
2022-02-09 16:19:40 +01:00
de-jcup
db8d98b571 Updated sponsor link in README.md
- Because of rebranding (Daimler AG has become
  Mercedes-Benz Group AG) the github organization has
  been renamed as well.
- Updated sponsorship link in README.md to new github organization
2022-02-07 10:34:42 +01:00
Renovate Bot
507f8472ca chore(deps): update golang.org/x/crypto commit hash to 30dcbda 2022-02-07 10:34:16 +01:00
Renovate Bot
853e1d5034 chore(deps): update all dependencies 2022-01-31 18:58:38 +01:00
Cosmin Cojocar
09a2941ad4 Use the CWE name as a name in the SARIF report 2022-01-27 15:51:51 +01:00
renovate[bot]
9399e7bed7 chore(deps): update all dependencies (#771)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-01-27 11:26:33 +10:00
Cosmin Cojocar
2fad8a4193 Resolve the TLS min version when is declarted in the same package but in a different file 2022-01-26 19:27:26 +01:00
Cosmin Cojocar
1fbcf10e18 Add a test for tls min version defined in a different file 2022-01-26 19:27:26 +01:00
renovate[bot]
b12c0f6e4e chore(deps): update all dependencies (#765)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-01-26 11:10:11 +01:00
48 changed files with 1073 additions and 281 deletions

View File

@@ -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

View File

@@ -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}}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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) ./...

View File

@@ -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>

View File

@@ -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)

View File

@@ -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() {

View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -1,7 +1,3 @@
//go:build go1.14 || !go1.11
// +build go1.14 !go1.11
// main
package main
import (

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
View File

@@ -0,0 +1,4 @@
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFphl7f2VuFRfsi4wqiLUCQ9xHQgV
O2VMDNcvh+kxiymLXa+GkPzSKExFYIlVwfg13URvCiB+kFvITmLzuLiGQg==
-----END PUBLIC KEY-----

View File

@@ -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.",

View File

@@ -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
View File

@@ -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
View File

@@ -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=

View File

@@ -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
}

View File

@@ -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() {

View File

@@ -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)

View File

@@ -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() {

View File

@@ -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)
}

View File

@@ -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;

View File

@@ -1,7 +1,6 @@
package html
import (
// use go embed to import template
_ "embed"
"html/template"

View File

@@ -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

View File

@@ -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
}

View File

@@ -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))
})
})
})

View File

@@ -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 }}

View File

@@ -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"

View 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)}
}

View File

@@ -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 {

View File

@@ -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"},

View File

@@ -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
View 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)}
}

View File

@@ -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
View 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)}
}

View File

@@ -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},

View File

@@ -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
View 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)}
}

View File

@@ -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")

View File

@@ -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) {

View File

@@ -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)}
}

View File

@@ -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)
}
}
}
}

View File

@@ -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
}

View File

@@ -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