mirror of
https://github.com/securego/gosec.git
synced 2026-01-15 09:53:40 +08:00
Compare commits
103 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a7e1a59d8b | ||
|
|
925741b7ef | ||
|
|
59ae7e9e27 | ||
|
|
e7abd9e348 | ||
|
|
35e7bc1a94 | ||
|
|
2d1ed95a0b | ||
|
|
4a8cb4609f | ||
|
|
bcc8afbe30 | ||
|
|
d2d3ae66bd | ||
|
|
1e7ed06b15 | ||
|
|
1bef91a07f | ||
|
|
621702f13a | ||
|
|
017d1d655c | ||
|
|
67f63d4781 | ||
|
|
b4eabb1b18 | ||
|
|
52a80ff4bd | ||
|
|
e2a95069d9 | ||
|
|
6decf96c3d | ||
|
|
d522338364 | ||
|
|
270b5ce868 | ||
|
|
60279264be | ||
|
|
65d2d9f011 | ||
|
|
dc1c38b861 | ||
|
|
55dbf5ad81 | ||
|
|
2aaa9c41d6 | ||
|
|
700e9a9d18 | ||
|
|
d514c42671 | ||
|
|
1d458c50e1 | ||
|
|
955a68d0d1 | ||
|
|
1336dc6820 | ||
|
|
5fd2a37044 | ||
|
|
39e4477788 | ||
|
|
6141d100df | ||
|
|
9452efe4ad | ||
|
|
57ec63392c | ||
|
|
e5fee17863 | ||
|
|
136f6c0040 | ||
|
|
047453a82f | ||
|
|
76ccee5b2f | ||
|
|
a9eb1c96fa | ||
|
|
89c5da3ce0 | ||
|
|
43fee884f6 | ||
|
|
77238291df | ||
|
|
9552f0372d | ||
|
|
f4d2576c36 | ||
|
|
2258e3108d | ||
|
|
fbb08336de | ||
|
|
c66cb56f09 | ||
|
|
59291a08ae | ||
|
|
7466b7cad2 | ||
|
|
32dcc8a1f5 | ||
|
|
e0cca6fe95 | ||
|
|
534689b08f | ||
|
|
eb95db1c76 | ||
|
|
6c6da403f0 | ||
|
|
b12f51f7d6 | ||
|
|
54c2185ae6 | ||
|
|
36c81ed69b | ||
|
|
9a2d74ffe0 | ||
|
|
4c5ad914f3 | ||
|
|
e21b4d42cf | ||
|
|
92de0ee7a2 | ||
|
|
4fda076e5d | ||
|
|
b01f49e366 | ||
|
|
b62cc3316d | ||
|
|
bc77d16301 | ||
|
|
ef1a35faf9 | ||
|
|
09b914371e | ||
|
|
1bd92a8e30 | ||
|
|
ca55eca3de | ||
|
|
329cad89ee | ||
|
|
08beb25d41 | ||
|
|
d566be274e | ||
|
|
8c602d0bc4 | ||
|
|
399e835157 | ||
|
|
229cf63a09 | ||
|
|
699cb55eb3 | ||
|
|
9b13cd5ab4 | ||
|
|
08ea2a57db | ||
|
|
44156135bf | ||
|
|
3274716ce3 | ||
|
|
1fb6a46eed | ||
|
|
d2c92ed7b3 | ||
|
|
4fd98728a7 | ||
|
|
1501618b90 | ||
|
|
7d33bc1991 | ||
|
|
bd8b4b4ece | ||
|
|
1216c9b96b | ||
|
|
50d1b4ae6b | ||
|
|
c0ba7c7a74 | ||
|
|
a3299ce10c | ||
|
|
d4617f51ba | ||
|
|
1d23143bee | ||
|
|
6741874d9b | ||
|
|
a83689867d | ||
|
|
be8bd6e40b | ||
|
|
3004932005 | ||
|
|
1f3bdd9349 | ||
|
|
5f3194b581 | ||
|
|
abfe8cfd6d | ||
|
|
0396179112 | ||
|
|
5e53c8b9f7 | ||
|
|
014751c91c |
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
||||
test:
|
||||
strategy:
|
||||
matrix:
|
||||
version: [{go: '1.22.6', golangci: 'latest'}, {go: '1.23.0', golangci: 'latest'}]
|
||||
version: [{go: '1.23.11', golangci: 'latest'}, {go: '1.24.5', golangci: 'latest'}]
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
GO111MODULE: on
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-
|
||||
- name: lint
|
||||
uses: golangci/golangci-lint-action@v6
|
||||
uses: golangci/golangci-lint-action@v8
|
||||
with:
|
||||
version: ${{ matrix.version.golangci }}
|
||||
- name: Run Gosec Security Scanner
|
||||
@@ -48,7 +48,7 @@ jobs:
|
||||
- name: Setup go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.23.0'
|
||||
go-version: '1.24.5'
|
||||
- name: Checkout Source
|
||||
uses: actions/checkout@v4
|
||||
- uses: actions/cache@v4
|
||||
@@ -60,7 +60,7 @@ jobs:
|
||||
- name: Create Test Coverage
|
||||
run: make test-coverage
|
||||
- name: Upload Test Coverage
|
||||
uses: codecov/codecov-action@v4
|
||||
uses: codecov/codecov-action@v5
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
fail_ci_if_error: true
|
||||
|
||||
8
.github/workflows/release.yml
vendored
8
.github/workflows/release.yml
vendored
@@ -17,11 +17,11 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.23.0'
|
||||
go-version: '1.24.5'
|
||||
- name: Install Cosign
|
||||
uses: sigstore/cosign-installer@v3
|
||||
with:
|
||||
cosign-release: 'v2.4.0'
|
||||
cosign-release: 'v2.5.0'
|
||||
- name: Store Cosign private key in a file
|
||||
run: 'echo "$COSIGN_KEY" > /tmp/cosign.key'
|
||||
shell: bash
|
||||
@@ -67,9 +67,9 @@ jobs:
|
||||
tags: ${{steps.meta.outputs.tags}}
|
||||
labels: ${{steps.meta.outputs.labels}}
|
||||
push: true
|
||||
build-args: GO_VERSION=1.23
|
||||
build-args: GO_VERSION=1.24
|
||||
- name: Sign Docker Image
|
||||
run: cosign sign --yes --key /tmp/cosign.key ${DIGEST}
|
||||
run: cosign sign --yes --key /tmp/cosign.key ${DIGEST} --registry-username="$secrets.DOCKER_USERNAME" --registry-password="::add-mask::$secrets.DOCKER_PASSWORD"
|
||||
env:
|
||||
TAGS: ${{steps.meta.outputs.tags}}
|
||||
COSIGN_PASSWORD: ${{secrets.COSIGN_PASSWORD}}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
version: "2"
|
||||
linters:
|
||||
enable:
|
||||
- asciicheck
|
||||
@@ -5,45 +6,60 @@ linters:
|
||||
- copyloopvar
|
||||
- dogsled
|
||||
- durationcheck
|
||||
- errcheck
|
||||
- errorlint
|
||||
- gci
|
||||
- ginkgolinter
|
||||
- gochecknoinits
|
||||
- gofmt
|
||||
- gofumpt
|
||||
- goimports
|
||||
- gosec
|
||||
- gosimple
|
||||
- govet
|
||||
- importas
|
||||
- ineffassign
|
||||
- misspell
|
||||
- nakedret
|
||||
- nolintlint
|
||||
- revive
|
||||
- staticcheck
|
||||
- typecheck
|
||||
- testifylint
|
||||
- unconvert
|
||||
- unparam
|
||||
- unused
|
||||
- wastedassign
|
||||
|
||||
linters-settings:
|
||||
gci:
|
||||
sections:
|
||||
- standard
|
||||
- default
|
||||
- prefix(github.com/securego)
|
||||
staticcheck:
|
||||
checks:
|
||||
- all
|
||||
- '-SA1019'
|
||||
|
||||
revive:
|
||||
rules:
|
||||
- name: dot-imports
|
||||
disabled: true
|
||||
|
||||
run:
|
||||
timeout: 5m
|
||||
settings:
|
||||
revive:
|
||||
rules:
|
||||
- name: dot-imports
|
||||
disabled: true
|
||||
- name: filename-format
|
||||
arguments:
|
||||
- ^[a-z][_a-z0-9]*.go$
|
||||
- name: redefines-builtin-id
|
||||
staticcheck:
|
||||
checks:
|
||||
- all
|
||||
- -SA1019
|
||||
testifylint:
|
||||
enable-all: true
|
||||
exclusions:
|
||||
generated: lax
|
||||
presets:
|
||||
- comments
|
||||
- common-false-positives
|
||||
- legacy
|
||||
- std-error-handling
|
||||
paths:
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
formatters:
|
||||
enable:
|
||||
- gci
|
||||
- gofmt
|
||||
- gofumpt
|
||||
- goimports
|
||||
settings:
|
||||
gci:
|
||||
sections:
|
||||
- standard
|
||||
- default
|
||||
- prefix(github.com/securego)
|
||||
exclusions:
|
||||
generated: lax
|
||||
paths:
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
---
|
||||
version: 2
|
||||
project_name: gosec
|
||||
|
||||
release:
|
||||
|
||||
81
CONTRIBUTING.md
Normal file
81
CONTRIBUTING.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# Contributing
|
||||
|
||||
## Adding a new rule
|
||||
|
||||
New rules can be implemented in two ways:
|
||||
|
||||
- as a `gosec.Rule` -- these define an arbitrary function which will be called on every AST node in the analyzed file, and are appropriate for rules that mostly need to reason about a single statement.
|
||||
- as an Analyzer -- these can operate on the entire program, and receive an [SSA](https://pkg.go.dev/golang.org/x/tools/go/ssa) representation of the package. This type of rule is useful when you need to perform a more complex analysis that requires a great deal of context.
|
||||
|
||||
### Adding a gosec.Rule
|
||||
|
||||
1. Copy an existing rule file as a starting point-- `./rules/unsafe.go` is a good option, as it implements a very simple rule with no additional supporting logic. Put the copied file in the `./rules/` directory.
|
||||
2. Change the name of the rule constructor function and of the types in the rule file you've copied so they will be unique.
|
||||
3. Edit the `Generate` function in `./rules/rulelist.go` to include your rule.
|
||||
4. Add a RuleID to CWE ID mapping for your rule to the `ruleToCWE` map in `./issue/issue.go`. If you need a CWE that isn't already defined in `./cwe/data.go`, add it to the `idWeaknessess` map in that file.
|
||||
5. Use `make` to compile `gosec`. The binary will now contain your rule.
|
||||
|
||||
To make your rule actually useful, you will likely want to use the support functions defined in `./resolve.go`, `./helpers.go` and `./call_list.go`. There are inline comments explaining the purpose of most of these functions, and you can find usage examples in the existing rule files.
|
||||
|
||||
### Adding an Analyzer
|
||||
|
||||
1. Create a new go file under `./analyzers/` with the following scaffolding in it:
|
||||
|
||||
```go
|
||||
package analyzers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/tools/go/analysis"
|
||||
"golang.org/x/tools/go/analysis/passes/buildssa"
|
||||
"github.com/securego/gosec/v2/issue"
|
||||
)
|
||||
|
||||
const defaultIssueDescriptionMyAnalyzer = "My new analyzer!"
|
||||
|
||||
func newMyAnalyzer(id string, description string) *analysis.Analyzer {
|
||||
return &analysis.Analyzer{
|
||||
Name: id,
|
||||
Doc: description,
|
||||
Run: runMyAnalyzer,
|
||||
Requires: []*analysis.Analyzer{buildssa.Analyzer},
|
||||
}
|
||||
}
|
||||
|
||||
func runMyAnalyzer(pass *analysis.Pass) (interface{}, error) {
|
||||
ssaResult, err := getSSAResult(pass)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("building ssa representation: %w", err)
|
||||
}
|
||||
var issues []*issue.Issue
|
||||
fmt.Printf("My Analyzer ran! %+v\n", ssaResult)
|
||||
|
||||
return issues, nil
|
||||
}
|
||||
```
|
||||
|
||||
2. Add the analyzer to `./analyzers/analyzerslist.go` in the `defaultAnalyzers` variable under an entry like `{"G999", "My test analyzer", newMyAnalyzer}`
|
||||
3. Add a RuleID to CWE ID mapping for your rule to the `ruleToCWE` map in `./issue/issue.go`. If you need a CWE that isn't already defined in `./cwe/data.go`, add it to the `idWeaknessess` map in that file.
|
||||
4. `make`; then run the `gosec` binary produced. You should see the output from our print statement.
|
||||
5. You now have a working example analyzer to play with-- look at the other implemented analyzers for ideas on how to make useful rules.
|
||||
|
||||
## Developing your rule
|
||||
|
||||
There are some utility tools which are useful for analyzing the SSA and AST representation `gosec` works with before writing rules or analyzers.
|
||||
|
||||
For instance to dump the SSA, the [ssadump](https://pkg.go.dev/golang.org/x/tools/cmd/ssadump) tool can be used as following:
|
||||
|
||||
```bash
|
||||
ssadump -build F main.go
|
||||
```
|
||||
|
||||
Consult the documentation for ssadump for an overview of available output flags and options.
|
||||
|
||||
For outputting the AST and supporting information, there is a utility tool in <https://github.com/securego/gosec/blob/master/cmd/gosecutil/tools.go> which can be compiled and used as standalone.
|
||||
|
||||
```bash
|
||||
gosecutil -tool ast main.go
|
||||
```
|
||||
|
||||
Valid tool arguments for this command are `ast`, `callobj`, `uses`, `types`, `defs`, `comments`, and `imports`.
|
||||
10
Makefile
10
Makefile
@@ -17,7 +17,11 @@ GOSEC ?= $(GOBIN)/gosec
|
||||
GINKGO ?= $(GOBIN)/ginkgo
|
||||
GO_MINOR_VERSION = $(shell $(GO) version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f2)
|
||||
GOVULN_MIN_VERSION = 17
|
||||
GO_VERSION = 1.23
|
||||
GO_VERSION = 1.24
|
||||
LDFLAGS = -ldflags "\
|
||||
-X 'main.Version=$(shell git describe --tags --always)' \
|
||||
-X 'main.GitTag=$(shell git describe --tags --abbrev=0)' \
|
||||
-X 'main.BuildDate=$(shell date -u +%Y-%m-%dT%H:%M:%SZ)'"
|
||||
|
||||
default:
|
||||
$(MAKE) build
|
||||
@@ -62,10 +66,10 @@ test-coverage: install-test-deps
|
||||
go test -race -v -count=1 -coverprofile=coverage.out ./...
|
||||
|
||||
build:
|
||||
go build -o $(BIN) ./cmd/gosec/
|
||||
go build $(LDFLAGS) -o $(BIN) ./cmd/gosec/
|
||||
|
||||
build-race:
|
||||
go build -race -o $(BIN) ./cmd/gosec/
|
||||
go build -race $(LDFLAGS) -o $(BIN) ./cmd/gosec/
|
||||
|
||||
clean:
|
||||
rm -rf build vendor dist coverage.out
|
||||
|
||||
42
README.md
42
README.md
@@ -22,6 +22,7 @@ You may obtain a copy of the License [here](http://www.apache.org/licenses/LICEN
|
||||
[](https://github.com/securego/gosec/releases)
|
||||
[](https://hub.docker.com/r/securego/gosec/tags)
|
||||
[](http://securego.slack.com)
|
||||
[](https://github.com/nikolaydubina/go-recipes)
|
||||
|
||||
## Install
|
||||
|
||||
@@ -137,7 +138,6 @@ directory you can supply `./...` as the input argument.
|
||||
- G110: Potential DoS vulnerability via decompression bomb
|
||||
- G111: Potential directory traversal
|
||||
- G112: Potential slowloris attack
|
||||
- G113: Usage of Rat.SetString in math/big with an overflow (CVE-2022-23772)
|
||||
- G114: Use of net/http serve function that has no support for setting timeouts
|
||||
- G115: Potential integer overflow when converting between integer types
|
||||
- G201: SQL query construction using format string
|
||||
@@ -171,6 +171,7 @@ directory you can supply `./...` as the input argument.
|
||||
### Retired rules
|
||||
|
||||
- G105: Audit the use of math/big.Int.Exp - [CVE is fixed](https://github.com/golang/go/issues/15184)
|
||||
- G113: Usage of Rat.SetString in math/big with an overflow (CVE-2022-23772). This affected Go <1.16.14 and Go <1.17.7, which are no longer supported by gosec.
|
||||
- G307: Deferring a method which returns an error - causing more inconvenience than fixing a security issue, despite the details from this [blog post](https://www.joeshaw.org/dont-defer-close-on-writable-files/)
|
||||
|
||||
### Selecting rules
|
||||
@@ -211,30 +212,9 @@ A number of global settings can be provided in a configuration file as follows:
|
||||
$ gosec -conf config.json .
|
||||
```
|
||||
|
||||
Also some rules accept configuration. For instance on rule `G104`, it is possible to define packages along with a list
|
||||
of functions which will be skipped when auditing the not checked errors:
|
||||
#### Rule Configuration
|
||||
|
||||
```JSON
|
||||
{
|
||||
"G104": {
|
||||
"ioutil": ["WriteFile"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can also configure the hard-coded credentials rule `G101` with additional patterns, or adjust the entropy threshold:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"G101": {
|
||||
"pattern": "(?i)passwd|pass|password|pwd|secret|private_key|token",
|
||||
"ignore_entropy": false,
|
||||
"entropy_threshold": "80.0",
|
||||
"per_char_threshold": "3.0",
|
||||
"truncate": "32"
|
||||
}
|
||||
}
|
||||
```
|
||||
Some rules accept configuration flags as well; these flags are documented in [RULES.md](https://github.com/securego/gosec/blob/master/RULES.md).
|
||||
|
||||
#### Go version
|
||||
|
||||
@@ -308,7 +288,7 @@ func main() {
|
||||
}
|
||||
|
||||
client := &http.Client{Transport: tr}
|
||||
_, err := client.Get("https://golang.org/")
|
||||
_, err := client.Get("https://go.dev/")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
@@ -324,7 +304,13 @@ You could put the description or justification text for the annotation. The
|
||||
justification should be after the rule(s) to suppress and start with two or
|
||||
more dashes, e.g: `//#nosec G101 G102 -- This is a false positive`
|
||||
|
||||
In some cases you may also want to revisit places where `#nosec` annotations
|
||||
Alternatively, gosec also supports the `//gosec:disable` directive, which functions similar to `#nosec`:
|
||||
|
||||
```go
|
||||
//gosec:disable G101 -- This is a false positive
|
||||
```
|
||||
|
||||
In some cases you may also want to revisit places where `#nosec` or `//gosec:disable` annotations
|
||||
have been used. To run the scanner and ignore any `#nosec` annotations you
|
||||
can do the following:
|
||||
|
||||
@@ -355,7 +341,7 @@ comment.
|
||||
|
||||
### Build tags
|
||||
|
||||
gosec is able to pass your [Go build tags](https://golang.org/pkg/go/build/) to the analyzer.
|
||||
gosec is able to pass your [Go build tags](https://pkg.go.dev/go/build/) to the analyzer.
|
||||
They can be provided as a comma separated list as follows:
|
||||
|
||||
```bash
|
||||
@@ -387,6 +373,8 @@ $ gosec -fmt=json -out=results.json -stdout -verbose=text *.go
|
||||
|
||||
## Development
|
||||
|
||||
[CONTRIBUTING.md](https://github.com/securego/gosec/blob/master/CONTRIBUTING.md) contains detailed information about adding new rules to gosec.
|
||||
|
||||
### Build
|
||||
|
||||
You can build the binary with:
|
||||
|
||||
61
RULES.md
Normal file
61
RULES.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# Rule Documentation
|
||||
|
||||
## Rules accepting parameters
|
||||
|
||||
As [README.md](https://github.com/securego/gosec/blob/master/README.md) mentions, some rules can be configured by adding parameters to the gosec JSON config. Per rule configs are encoded as top level objects in the gosec config, with the rule ID (`Gxxx`) as the key.
|
||||
|
||||
Currently, the following rules accept parameters. This list is manually maintained; if you notice an omission please add it!
|
||||
|
||||
### G101
|
||||
|
||||
The hard-coded credentials rule `G101` can be configured with additional patterns, and the entropy threshold can be adjusted:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"G101": {
|
||||
"pattern": "(?i)passwd|pass|password|pwd|secret|private_key|token",
|
||||
"ignore_entropy": false,
|
||||
"entropy_threshold": "80.0",
|
||||
"per_char_threshold": "3.0",
|
||||
"truncate": "32"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### G104
|
||||
|
||||
The unchecked error value rule `G104` can be configured with additional functions that should be permitted to be called without checking errors.
|
||||
|
||||
```JSON
|
||||
{
|
||||
"G104": {
|
||||
"ioutil": ["WriteFile"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### G111
|
||||
|
||||
The HTTP Directory serving rule `G111` can be configured with a different regex for detecting potentially overly permissive servers. Note that this *replaces* the default pattern of `http\.Dir\("\/"\)|http\.Dir\('\/'\)`.
|
||||
|
||||
```JSON
|
||||
{
|
||||
"G111": {
|
||||
"pattern": "http\\.Dir\\(\"\\\/\"\\)|http\\.Dir\\('\\\/'\\)"
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### G301, G302, G306, G307
|
||||
|
||||
The various file and directory permission checking rules can be configured with a different maximum allowable file permission.
|
||||
|
||||
```JSON
|
||||
{
|
||||
"G301":"0o600",
|
||||
"G302":"0o600",
|
||||
"G306":"0o750",
|
||||
"G307":"0o750"
|
||||
}
|
||||
```
|
||||
1
USERS.md
1
USERS.md
@@ -16,6 +16,7 @@ This is a list of gosec's users. Please send a pull request with your organisati
|
||||
10. [Checkmarx](https://www.checkmarx.com/)
|
||||
11. [SeatGeek](https://www.seatgeek.com/)
|
||||
12. [reMarkable](https://remarkable.com)
|
||||
13. [SSOJet](https://ssojet.com)
|
||||
|
||||
## Projects
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ inputs:
|
||||
|
||||
runs:
|
||||
using: 'docker'
|
||||
image: 'docker://securego/gosec:2.21.0'
|
||||
image: 'docker://securego/gosec:2.22.5'
|
||||
args:
|
||||
- ${{ inputs.args }}
|
||||
|
||||
|
||||
148
analyzer.go
148
analyzer.go
@@ -16,6 +16,7 @@
|
||||
package gosec
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/build"
|
||||
@@ -56,6 +57,8 @@ const externalSuppressionJustification = "Globally suppressed."
|
||||
|
||||
const aliasOfAllRules = "*"
|
||||
|
||||
var directiveRegexp = regexp.MustCompile("^//gosec:disable(?: (.+))?$")
|
||||
|
||||
type ignore struct {
|
||||
start int
|
||||
end int
|
||||
@@ -543,8 +546,8 @@ func (gosec *Analyzer) ParseErrors(pkg *packages.Package) error {
|
||||
// AppendError appends an error to the file errors
|
||||
func (gosec *Analyzer) AppendError(file string, err error) {
|
||||
// Do not report the error for empty packages (e.g. files excluded from build with a tag)
|
||||
r := regexp.MustCompile(`no buildable Go source files in`)
|
||||
if r.MatchString(err.Error()) {
|
||||
var noGoErr *build.NoGoError
|
||||
if errors.As(err, &noGoErr) {
|
||||
return
|
||||
}
|
||||
errors := make([]Error, 0)
|
||||
@@ -558,71 +561,100 @@ func (gosec *Analyzer) AppendError(file string, err error) {
|
||||
|
||||
// ignore a node (and sub-tree) if it is tagged with a nosec tag comment
|
||||
func (gosec *Analyzer) ignore(n ast.Node) map[string]issue.SuppressionInfo {
|
||||
if groups, ok := gosec.context.Comments[n]; ok && !gosec.ignoreNosec {
|
||||
if gosec.ignoreNosec {
|
||||
return nil
|
||||
}
|
||||
groups, ok := gosec.context.Comments[n]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Checks if an alternative for #nosec is set and, if not, uses the default.
|
||||
noSecDefaultTag, err := gosec.config.GetGlobal(Nosec)
|
||||
if err != nil {
|
||||
noSecDefaultTag = NoSecTag(string(Nosec))
|
||||
} else {
|
||||
noSecDefaultTag = NoSecTag(noSecDefaultTag)
|
||||
}
|
||||
noSecAlternativeTag, err := gosec.config.GetGlobal(NoSecAlternative)
|
||||
if err != nil {
|
||||
noSecAlternativeTag = noSecDefaultTag
|
||||
} else {
|
||||
noSecAlternativeTag = NoSecTag(noSecAlternativeTag)
|
||||
// Checks if an alternative for #nosec is set and, if not, uses the default.
|
||||
noSecDefaultTag, err := gosec.config.GetGlobal(Nosec)
|
||||
if err != nil {
|
||||
noSecDefaultTag = NoSecTag(string(Nosec))
|
||||
} else {
|
||||
noSecDefaultTag = NoSecTag(noSecDefaultTag)
|
||||
}
|
||||
noSecAlternativeTag, err := gosec.config.GetGlobal(NoSecAlternative)
|
||||
if err != nil {
|
||||
noSecAlternativeTag = noSecDefaultTag
|
||||
} else {
|
||||
noSecAlternativeTag = NoSecTag(noSecAlternativeTag)
|
||||
}
|
||||
|
||||
for _, group := range groups {
|
||||
found, args := findNoSecDirective(group, noSecDefaultTag, noSecAlternativeTag)
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, group := range groups {
|
||||
comment := strings.TrimSpace(group.Text())
|
||||
foundDefaultTag := strings.HasPrefix(comment, noSecDefaultTag) || regexp.MustCompile("\n *"+noSecDefaultTag).MatchString(comment)
|
||||
foundAlternativeTag := strings.HasPrefix(comment, noSecAlternativeTag) || regexp.MustCompile("\n *"+noSecAlternativeTag).MatchString(comment)
|
||||
gosec.stats.NumNosec++
|
||||
|
||||
if foundDefaultTag || foundAlternativeTag {
|
||||
gosec.stats.NumNosec++
|
||||
|
||||
// Discard what's in front of the nosec tag.
|
||||
if foundDefaultTag {
|
||||
comment = strings.SplitN(comment, noSecDefaultTag, 2)[1]
|
||||
} else {
|
||||
comment = strings.SplitN(comment, noSecAlternativeTag, 2)[1]
|
||||
}
|
||||
|
||||
// Extract the directive and the justification.
|
||||
justification := ""
|
||||
commentParts := regexp.MustCompile(`-{2,}`).Split(comment, 2)
|
||||
directive := commentParts[0]
|
||||
if len(commentParts) > 1 {
|
||||
justification = strings.TrimSpace(strings.TrimRight(commentParts[1], "\n"))
|
||||
}
|
||||
|
||||
// Pull out the specific rules that are listed to be ignored.
|
||||
re := regexp.MustCompile(`(G\d{3})`)
|
||||
matches := re.FindAllStringSubmatch(directive, -1)
|
||||
|
||||
suppression := issue.SuppressionInfo{
|
||||
Kind: "inSource",
|
||||
Justification: justification,
|
||||
}
|
||||
|
||||
// Find the rule IDs to ignore.
|
||||
ignores := make(map[string]issue.SuppressionInfo)
|
||||
for _, v := range matches {
|
||||
ignores[v[1]] = suppression
|
||||
}
|
||||
|
||||
// If no specific rules were given, ignore everything.
|
||||
if len(matches) == 0 {
|
||||
ignores[aliasOfAllRules] = suppression
|
||||
}
|
||||
return ignores
|
||||
}
|
||||
// Extract the directive and the justification.
|
||||
justification := ""
|
||||
commentParts := regexp.MustCompile(`-{2,}`).Split(args, 2)
|
||||
directive := commentParts[0]
|
||||
if len(commentParts) > 1 {
|
||||
justification = strings.TrimSpace(strings.TrimRight(commentParts[1], "\n"))
|
||||
}
|
||||
|
||||
// Pull out the specific rules that are listed to be ignored.
|
||||
re := regexp.MustCompile(`(G\d{3})`)
|
||||
matches := re.FindAllStringSubmatch(directive, -1)
|
||||
|
||||
suppression := issue.SuppressionInfo{
|
||||
Kind: "inSource",
|
||||
Justification: justification,
|
||||
}
|
||||
|
||||
// Find the rule IDs to ignore.
|
||||
ignores := make(map[string]issue.SuppressionInfo)
|
||||
for _, v := range matches {
|
||||
ignores[v[1]] = suppression
|
||||
}
|
||||
|
||||
// If no specific rules were given, ignore everything.
|
||||
if len(matches) == 0 {
|
||||
ignores[aliasOfAllRules] = suppression
|
||||
}
|
||||
return ignores
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// findNoSecDirective checks if the comment group contains `#nosec` or `//gosec:disable` directive.
|
||||
// If found, it returns true and the directive's arguments.
|
||||
func findNoSecDirective(group *ast.CommentGroup, noSecDefaultTag, noSecAlternativeTag string) (bool, string) {
|
||||
// Check if the comment grounp has a nosec comment.
|
||||
for _, tag := range []string{noSecDefaultTag, noSecAlternativeTag} {
|
||||
if found, args := findNoSecTag(group, tag); found {
|
||||
return true, args
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the comment group has a directive comment.
|
||||
for _, c := range group.List {
|
||||
match := directiveRegexp.FindStringSubmatch(c.Text)
|
||||
if len(match) > 0 {
|
||||
return true, match[0]
|
||||
}
|
||||
}
|
||||
|
||||
return false, ""
|
||||
}
|
||||
|
||||
func findNoSecTag(group *ast.CommentGroup, tag string) (bool, string) {
|
||||
comment := strings.TrimSpace(group.Text())
|
||||
|
||||
if strings.HasPrefix(comment, tag) || regexp.MustCompile("\n *"+tag).MatchString(comment) {
|
||||
// Discard what's in front of the nosec tag.
|
||||
return true, strings.SplitN(comment, tag, 2)[1]
|
||||
}
|
||||
|
||||
return false, ""
|
||||
}
|
||||
|
||||
// Visit runs the gosec visitor logic over an AST created by parsing go code.
|
||||
// Rule methods added with AddRule will be invoked as necessary.
|
||||
func (gosec *Analyzer) Visit(n ast.Node) ast.Visitor {
|
||||
|
||||
618
analyzer_test.go
618
analyzer_test.go
@@ -16,18 +16,19 @@ package gosec_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"go/build"
|
||||
"log"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
"golang.org/x/tools/go/packages"
|
||||
|
||||
"github.com/securego/gosec/v2"
|
||||
"github.com/securego/gosec/v2/analyzers"
|
||||
"github.com/securego/gosec/v2/rules"
|
||||
"github.com/securego/gosec/v2/testutils"
|
||||
"golang.org/x/tools/go/packages"
|
||||
)
|
||||
|
||||
var _ = Describe("Analyzer", func() {
|
||||
@@ -45,10 +46,8 @@ var _ = Describe("Analyzer", func() {
|
||||
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 := os.MkdirTemp("", "empty")
|
||||
defer os.RemoveAll(dir)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, dir)
|
||||
dir := GinkgoT().TempDir()
|
||||
err := analyzer.Process(buildTags, dir)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
_, _, errors := analyzer.Report()
|
||||
Expect(errors).To(BeEmpty())
|
||||
@@ -232,6 +231,23 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(nosecIssues).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("should not report errors when a disable directive is present", func() {
|
||||
sample := testutils.SampleCodeG401[0]
|
||||
source := sample.Code[0]
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G401")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecSource := strings.Replace(source, "h := md5.New()", "h := md5.New() //gosec:disable", 1)
|
||||
nosecPackage.AddFile("md5.go", nosecSource)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
nosecIssues, _, _ := analyzer.Report()
|
||||
Expect(nosecIssues).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("should not report errors when a nosec line comment is present", func() {
|
||||
sample := testutils.SampleCodeG405[0]
|
||||
source := sample.Code[0]
|
||||
@@ -249,6 +265,23 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(nosecIssues).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("should not report errors when a disable directive is present", func() {
|
||||
sample := testutils.SampleCodeG405[0]
|
||||
source := sample.Code[0]
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G405")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecSource := strings.Replace(source, "c, e := des.NewCipher([]byte(\"mySecret\"))", "c, e := des.NewCipher([]byte(\"mySecret\")) //gosec:disable", 1)
|
||||
nosecPackage.AddFile("cipher.go", nosecSource)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
nosecIssues, _, _ := analyzer.Report()
|
||||
Expect(nosecIssues).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("should not report errors when a nosec line comment is present", func() {
|
||||
sample := testutils.SampleCodeG406[0]
|
||||
source := sample.Code[0]
|
||||
@@ -266,6 +299,23 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(nosecIssues).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("should not report errors when a disable directive is present", func() {
|
||||
sample := testutils.SampleCodeG406[0]
|
||||
source := sample.Code[0]
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G406")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecSource := strings.Replace(source, "h := md4.New()", "h := md4.New() //gosec:disable", 1)
|
||||
nosecPackage.AddFile("md4.go", nosecSource)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
nosecIssues, _, _ := analyzer.Report()
|
||||
Expect(nosecIssues).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("should not report errors when a nosec block comment is present", func() {
|
||||
sample := testutils.SampleCodeG401[0]
|
||||
source := sample.Code[0]
|
||||
@@ -335,6 +385,24 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(nosecIssues).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("should not report errors when an exclude comment is present for the correct rule", func() {
|
||||
// Rule for MD5 weak crypto usage
|
||||
sample := testutils.SampleCodeG401[0]
|
||||
source := sample.Code[0]
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G401")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecSource := strings.Replace(source, "h := md5.New()", "h := md5.New() //gosec:disable G401", 1)
|
||||
nosecPackage.AddFile("md5.go", nosecSource)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
nosecIssues, _, _ := analyzer.Report()
|
||||
Expect(nosecIssues).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("should not report errors when an exclude comment is present for the correct rule", func() {
|
||||
// Rule for DES weak crypto usage
|
||||
sample := testutils.SampleCodeG405[0]
|
||||
@@ -353,6 +421,24 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(nosecIssues).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("should not report errors when an exclude comment is present for the correct rule", func() {
|
||||
// Rule for DES weak crypto usage
|
||||
sample := testutils.SampleCodeG405[0]
|
||||
source := sample.Code[0]
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G405")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecSource := strings.Replace(source, "c, e := des.NewCipher([]byte(\"mySecret\"))", "c, e := des.NewCipher([]byte(\"mySecret\")) //gosec:disable G405", 1)
|
||||
nosecPackage.AddFile("cipher.go", nosecSource)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
nosecIssues, _, _ := analyzer.Report()
|
||||
Expect(nosecIssues).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("should not report errors when an exclude comment is present for the correct rule", func() {
|
||||
// Rule for MD4 deprecated weak crypto usage
|
||||
sample := testutils.SampleCodeG406[0]
|
||||
@@ -371,6 +457,24 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(nosecIssues).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("should not report errors when an exclude comment is present for the correct rule", func() {
|
||||
// Rule for MD4 deprecated weak crypto usage
|
||||
sample := testutils.SampleCodeG406[0]
|
||||
source := sample.Code[0]
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G406")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecSource := strings.Replace(source, "h := md4.New()", "h := md4.New() //gosec:disable G406", 1)
|
||||
nosecPackage.AddFile("md4.go", nosecSource)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
nosecIssues, _, _ := analyzer.Report()
|
||||
Expect(nosecIssues).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("should not report errors when a nosec block and line comment are present", func() {
|
||||
sample := testutils.SampleCodeG101[23]
|
||||
source := sample.Code[0]
|
||||
@@ -417,6 +521,52 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(nosecIssues).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("should not report errors when a disable directive block and line comment are present", func() {
|
||||
sample := testutils.SampleCodeG101[26]
|
||||
source := sample.Code[0]
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G101")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecPackage.AddFile("g101.go", source)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
nosecIssues, _, _ := analyzer.Report()
|
||||
Expect(nosecIssues).Should(BeEmpty())
|
||||
})
|
||||
It("should not report errors when only a disable directive block is present", func() {
|
||||
sample := testutils.SampleCodeG101[27]
|
||||
source := sample.Code[0]
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G101")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecPackage.AddFile("g101.go", source)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
nosecIssues, _, _ := analyzer.Report()
|
||||
Expect(nosecIssues).Should(BeEmpty())
|
||||
})
|
||||
It("should not report errors when a single line nosec is present on a multi-line issue", func() {
|
||||
sample := testutils.SampleCodeG112[4]
|
||||
source := sample.Code[0]
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G112")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecPackage.AddFile("g112.go", source)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
nosecIssues, _, _ := analyzer.Report()
|
||||
Expect(nosecIssues).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("should report errors when an exclude comment is present for a different rule", func() {
|
||||
sample := testutils.SampleCodeG401[0]
|
||||
source := sample.Code[0]
|
||||
@@ -434,6 +584,23 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(nosecIssues).Should(HaveLen(sample.Errors))
|
||||
})
|
||||
|
||||
It("should report errors when an exclude comment is present for a different rule", func() {
|
||||
sample := testutils.SampleCodeG401[0]
|
||||
source := sample.Code[0]
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G401")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecSource := strings.Replace(source, "h := md5.New()", "h := md5.New() //gosec:disable G301", 1)
|
||||
nosecPackage.AddFile("md5.go", nosecSource)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
nosecIssues, _, _ := analyzer.Report()
|
||||
Expect(nosecIssues).Should(HaveLen(sample.Errors))
|
||||
})
|
||||
|
||||
It("should report errors when an exclude comment is present for a different rule", func() {
|
||||
sample := testutils.SampleCodeG405[0]
|
||||
source := sample.Code[0]
|
||||
@@ -451,6 +618,23 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(nosecIssues).Should(HaveLen(sample.Errors))
|
||||
})
|
||||
|
||||
It("should report errors when an exclude comment is present for a different rule", func() {
|
||||
sample := testutils.SampleCodeG405[0]
|
||||
source := sample.Code[0]
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G405")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecSource := strings.Replace(source, "c, e := des.NewCipher([]byte(\"mySecret\"))", "c, e := des.NewCipher([]byte(\"mySecret\")) //gosec:disable G301", 1)
|
||||
nosecPackage.AddFile("cipher.go", nosecSource)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
nosecIssues, _, _ := analyzer.Report()
|
||||
Expect(nosecIssues).Should(HaveLen(sample.Errors))
|
||||
})
|
||||
|
||||
It("should report errors when an exclude comment is present for a different rule", func() {
|
||||
sample := testutils.SampleCodeG406[0]
|
||||
source := sample.Code[0]
|
||||
@@ -468,6 +652,23 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(nosecIssues).Should(HaveLen(sample.Errors))
|
||||
})
|
||||
|
||||
It("should report errors when an exclude comment is present for a different rule", func() {
|
||||
sample := testutils.SampleCodeG406[0]
|
||||
source := sample.Code[0]
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G406")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecSource := strings.Replace(source, "h := md4.New()", "h := md4.New() //gosec:disable G301", 1)
|
||||
nosecPackage.AddFile("md4.go", nosecSource)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
nosecIssues, _, _ := analyzer.Report()
|
||||
Expect(nosecIssues).Should(HaveLen(sample.Errors))
|
||||
})
|
||||
|
||||
It("should not report errors when an exclude comment is present for multiple rules, including the correct rule", func() {
|
||||
sample := testutils.SampleCodeG401[0]
|
||||
source := sample.Code[0]
|
||||
@@ -487,6 +688,25 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(nosecIssues).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("should not report errors when an exclude comment is present for multiple rules, including the correct rule", func() {
|
||||
sample := testutils.SampleCodeG401[0]
|
||||
source := sample.Code[0]
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G401")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecSource := strings.Replace(source, "h := md5.New()", "h := md5.New() //gosec:disable G301 G401", 1)
|
||||
nosecPackage.AddFile("md5.go", nosecSource)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
nosecIssues, _, _ := analyzer.Report()
|
||||
Expect(nosecIssues).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("should not report errors when an exclude comment is present for multiple rules, including the correct rule", func() {
|
||||
sample := testutils.SampleCodeG405[0]
|
||||
source := sample.Code[0]
|
||||
@@ -506,6 +726,25 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(nosecIssues).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("should not report errors when an exclude comment is present for multiple rules, including the correct rule", func() {
|
||||
sample := testutils.SampleCodeG405[0]
|
||||
source := sample.Code[0]
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G405")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecSource := strings.Replace(source, "c, e := des.NewCipher([]byte(\"mySecret\"))", "c, e := des.NewCipher([]byte(\"mySecret\")) //gosec:disable G301 G405", 1)
|
||||
nosecPackage.AddFile("cipher.go", nosecSource)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
nosecIssues, _, _ := analyzer.Report()
|
||||
Expect(nosecIssues).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("should not report errors when an exclude comment is present for multiple rules, including the correct rule", func() {
|
||||
sample := testutils.SampleCodeG406[0]
|
||||
source := sample.Code[0]
|
||||
@@ -525,6 +764,25 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(nosecIssues).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("should not report errors when an exclude comment is present for multiple rules, including the correct rule", func() {
|
||||
sample := testutils.SampleCodeG406[0]
|
||||
source := sample.Code[0]
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G406")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecSource := strings.Replace(source, "h := md4.New()", "h := md4.New() //gosec:disable G301 G406", 1)
|
||||
nosecPackage.AddFile("md4.go", nosecSource)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
nosecIssues, _, _ := analyzer.Report()
|
||||
Expect(nosecIssues).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("should pass the build tags", func() {
|
||||
sample := testutils.SampleCodeBuildTag[0]
|
||||
source := sample.Code[0]
|
||||
@@ -575,6 +833,29 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(nosecIssues).Should(HaveLen(sample.Errors))
|
||||
})
|
||||
|
||||
It("should be possible to overwrite disable directive, and report issues", func() {
|
||||
// Rule for MD5 weak crypto usage
|
||||
sample := testutils.SampleCodeG401[0]
|
||||
source := sample.Code[0]
|
||||
|
||||
// overwrite nosec option
|
||||
nosecIgnoreConfig := gosec.NewConfig()
|
||||
nosecIgnoreConfig.SetGlobal(gosec.Nosec, "true")
|
||||
customAnalyzer := gosec.NewAnalyzer(nosecIgnoreConfig, tests, false, false, 1, logger)
|
||||
customAnalyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G401")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecSource := strings.Replace(source, "h := md5.New()", "h := md5.New() //gosec:disable", 1)
|
||||
nosecPackage.AddFile("md5.go", nosecSource)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = customAnalyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
nosecIssues, _, _ := customAnalyzer.Report()
|
||||
Expect(nosecIssues).Should(HaveLen(sample.Errors))
|
||||
})
|
||||
|
||||
It("should be possible to overwrite nosec comments, and report issues", func() {
|
||||
// Rule for DES weak crypto usage
|
||||
sample := testutils.SampleCodeG405[0]
|
||||
@@ -598,6 +879,29 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(nosecIssues).Should(HaveLen(sample.Errors))
|
||||
})
|
||||
|
||||
It("should be possible to overwrite disable directive comments, and report issues", func() {
|
||||
// Rule for DES weak crypto usage
|
||||
sample := testutils.SampleCodeG405[0]
|
||||
source := sample.Code[0]
|
||||
|
||||
// overwrite nosec option
|
||||
nosecIgnoreConfig := gosec.NewConfig()
|
||||
nosecIgnoreConfig.SetGlobal(gosec.Nosec, "true")
|
||||
customAnalyzer := gosec.NewAnalyzer(nosecIgnoreConfig, tests, false, false, 1, logger)
|
||||
customAnalyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G405")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecSource := strings.Replace(source, "c, e := des.NewCipher([]byte(\"mySecret\"))", "c, e := des.NewCipher([]byte(\"mySecret\")) //gosec:disable", 1)
|
||||
nosecPackage.AddFile("cipher.go", nosecSource)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = customAnalyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
nosecIssues, _, _ := customAnalyzer.Report()
|
||||
Expect(nosecIssues).Should(HaveLen(sample.Errors))
|
||||
})
|
||||
|
||||
It("should be possible to overwrite nosec comments, and report issues", func() {
|
||||
// Rule for MD4 weak crypto usage
|
||||
sample := testutils.SampleCodeG406[0]
|
||||
@@ -621,6 +925,29 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(nosecIssues).Should(HaveLen(sample.Errors))
|
||||
})
|
||||
|
||||
It("should be possible to overwrite disable directive comments, and report issues", func() {
|
||||
// Rule for MD4 weak crypto usage
|
||||
sample := testutils.SampleCodeG406[0]
|
||||
source := sample.Code[0]
|
||||
|
||||
// overwrite nosec option
|
||||
nosecIgnoreConfig := gosec.NewConfig()
|
||||
nosecIgnoreConfig.SetGlobal(gosec.Nosec, "true")
|
||||
customAnalyzer := gosec.NewAnalyzer(nosecIgnoreConfig, tests, false, false, 1, logger)
|
||||
customAnalyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G406")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecSource := strings.Replace(source, "h := md4.New()", "h := md4.New() //gosec:disable", 1)
|
||||
nosecPackage.AddFile("md4.go", nosecSource)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = customAnalyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
nosecIssues, _, _ := customAnalyzer.Report()
|
||||
Expect(nosecIssues).Should(HaveLen(sample.Errors))
|
||||
})
|
||||
|
||||
It("should be possible to overwrite nosec comments, and report issues but they should not be counted", func() {
|
||||
// Rule for MD5 weak crypto usage
|
||||
sample := testutils.SampleCodeG401[0]
|
||||
@@ -716,6 +1043,23 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(nosecIssues).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("should not report errors when disable directive is in front of a line", func() {
|
||||
sample := testutils.SampleCodeG401[0]
|
||||
source := sample.Code[0]
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G401")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecSource := strings.Replace(source, "h := md5.New()", "//Some description\n//gosec:disable G401\nh := md5.New()", 1)
|
||||
nosecPackage.AddFile("md5.go", nosecSource)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
nosecIssues, _, _ := analyzer.Report()
|
||||
Expect(nosecIssues).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("should not report errors when nosec tag is in front of a line", func() {
|
||||
sample := testutils.SampleCodeG405[0]
|
||||
source := sample.Code[0]
|
||||
@@ -733,6 +1077,23 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(nosecIssues).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("should not report errors when disable directive is in front of a line", func() {
|
||||
sample := testutils.SampleCodeG405[0]
|
||||
source := sample.Code[0]
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G405")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecSource := strings.Replace(source, "c, e := des.NewCipher([]byte(\"mySecret\"))", "//Some description\n//gosec:disable G405\nc, e := des.NewCipher([]byte(\"mySecret\"))", 1)
|
||||
nosecPackage.AddFile("cipher.go", nosecSource)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
nosecIssues, _, _ := analyzer.Report()
|
||||
Expect(nosecIssues).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("should not report errors when nosec tag is in front of a line", func() {
|
||||
sample := testutils.SampleCodeG406[0]
|
||||
source := sample.Code[0]
|
||||
@@ -750,6 +1111,23 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(nosecIssues).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("should not report errors when disable directive is in front of a line", func() {
|
||||
sample := testutils.SampleCodeG406[0]
|
||||
source := sample.Code[0]
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G406")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecSource := strings.Replace(source, "h := md4.New()", "//Some description\n//gosec:disable G406\nh := md4.New()", 1)
|
||||
nosecPackage.AddFile("md4.go", nosecSource)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
nosecIssues, _, _ := analyzer.Report()
|
||||
Expect(nosecIssues).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("should report errors when nosec tag is not in front of a line", func() {
|
||||
sample := testutils.SampleCodeG401[0]
|
||||
source := sample.Code[0]
|
||||
@@ -869,6 +1247,23 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(nosecIssues).Should(HaveLen(sample.Errors))
|
||||
})
|
||||
|
||||
It("should report errors when there are disable directives after a //gosec:disable WrongRuleList", func() {
|
||||
sample := testutils.SampleCodeG401[0]
|
||||
source := sample.Code[0]
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G401")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecSource := strings.Replace(source, "h := md5.New()", "//gosec:disable G301\n//gosec:disable\nh := md5.New()", 1)
|
||||
nosecPackage.AddFile("md5.go", nosecSource)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
nosecIssues, _, _ := analyzer.Report()
|
||||
Expect(nosecIssues).Should(HaveLen(sample.Errors))
|
||||
})
|
||||
|
||||
It("should report errors when there are nosec tags after a #nosec WrongRuleList annotation", func() {
|
||||
sample := testutils.SampleCodeG405[0]
|
||||
source := sample.Code[0]
|
||||
@@ -886,6 +1281,23 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(nosecIssues).Should(HaveLen(sample.Errors))
|
||||
})
|
||||
|
||||
It("should report errors when there are disable directives after a //gosec:disable WrongRuleList", func() {
|
||||
sample := testutils.SampleCodeG405[0]
|
||||
source := sample.Code[0]
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G405")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecSource := strings.Replace(source, "c, e := des.NewCipher([]byte(\"mySecret\"))", "//gosec:disable G301\n//gosec:disable\nc, e := des.NewCipher([]byte(\"mySecret\"))", 1)
|
||||
nosecPackage.AddFile("cipher.go", nosecSource)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
nosecIssues, _, _ := analyzer.Report()
|
||||
Expect(nosecIssues).Should(HaveLen(sample.Errors))
|
||||
})
|
||||
|
||||
It("should report errors when there are nosec tags after a #nosec WrongRuleList annotation", func() {
|
||||
sample := testutils.SampleCodeG406[0]
|
||||
source := sample.Code[0]
|
||||
@@ -903,6 +1315,23 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(nosecIssues).Should(HaveLen(sample.Errors))
|
||||
})
|
||||
|
||||
It("should report errors when there are disable directives after a //gosec:disable WrongRuleList", func() {
|
||||
sample := testutils.SampleCodeG406[0]
|
||||
source := sample.Code[0]
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G406")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecSource := strings.Replace(source, "h := md4.New()", "//gosec:disable G301\n//gosec:disable\nh := md4.New()", 1)
|
||||
nosecPackage.AddFile("md4.go", nosecSource)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
nosecIssues, _, _ := analyzer.Report()
|
||||
Expect(nosecIssues).Should(HaveLen(sample.Errors))
|
||||
})
|
||||
|
||||
It("should be possible to use an alternative nosec tag", func() {
|
||||
// Rule for MD5 weak crypto usage
|
||||
sample := testutils.SampleCodeG401[0]
|
||||
@@ -1314,7 +1743,10 @@ var _ = Describe("Analyzer", func() {
|
||||
|
||||
Context("when appending errors", func() {
|
||||
It("should skip error for non-buildable packages", func() {
|
||||
analyzer.AppendError("test", errors.New(`loading file from package "pkg/test": no buildable Go source files in pkg/test`))
|
||||
err := &build.NoGoError{
|
||||
Dir: "pkg/test",
|
||||
}
|
||||
analyzer.AppendError("test", err)
|
||||
_, _, errors := analyzer.Report()
|
||||
Expect(errors).To(BeEmpty())
|
||||
})
|
||||
@@ -1364,6 +1796,26 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(issues[0].Suppressions[0].Justification).To(Equal("Justification"))
|
||||
})
|
||||
|
||||
It("should not report an error if the violation is suppressed", func() {
|
||||
sample := testutils.SampleCodeG401[0]
|
||||
source := sample.Code[0]
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G401")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecSource := strings.Replace(source, "h := md5.New()", "h := md5.New() //gosec:disable G401 -- Justification", 1)
|
||||
nosecPackage.AddFile("md5.go", nosecSource)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
issues, _, _ := analyzer.Report()
|
||||
Expect(issues).To(HaveLen(sample.Errors))
|
||||
Expect(issues[0].Suppressions).To(HaveLen(1))
|
||||
Expect(issues[0].Suppressions[0].Kind).To(Equal("inSource"))
|
||||
Expect(issues[0].Suppressions[0].Justification).To(Equal("Justification"))
|
||||
})
|
||||
|
||||
It("should not report an error if the violation is suppressed", func() {
|
||||
sample := testutils.SampleCodeG405[0]
|
||||
source := sample.Code[0]
|
||||
@@ -1384,6 +1836,26 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(issues[0].Suppressions[0].Justification).To(Equal("Justification"))
|
||||
})
|
||||
|
||||
It("should not report an error if the violation is suppressed", func() {
|
||||
sample := testutils.SampleCodeG405[0]
|
||||
source := sample.Code[0]
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G405")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecSource := strings.Replace(source, "c, e := des.NewCipher([]byte(\"mySecret\"))", "c, e := des.NewCipher([]byte(\"mySecret\")) //gosec:disable G405 -- Justification", 1)
|
||||
nosecPackage.AddFile("cipher.go", nosecSource)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
issues, _, _ := analyzer.Report()
|
||||
Expect(issues).To(HaveLen(sample.Errors))
|
||||
Expect(issues[0].Suppressions).To(HaveLen(1))
|
||||
Expect(issues[0].Suppressions[0].Kind).To(Equal("inSource"))
|
||||
Expect(issues[0].Suppressions[0].Justification).To(Equal("Justification"))
|
||||
})
|
||||
|
||||
It("should not report an error if the violation is suppressed", func() {
|
||||
sample := testutils.SampleCodeG406[0]
|
||||
source := sample.Code[0]
|
||||
@@ -1404,6 +1876,26 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(issues[0].Suppressions[0].Justification).To(Equal("Justification"))
|
||||
})
|
||||
|
||||
It("should not report an error if the violation is suppressed", func() {
|
||||
sample := testutils.SampleCodeG406[0]
|
||||
source := sample.Code[0]
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G406")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecSource := strings.Replace(source, "h := md4.New()", "h := md4.New() //gosec:disable G406 -- Justification", 1)
|
||||
nosecPackage.AddFile("md4.go", nosecSource)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
issues, _, _ := analyzer.Report()
|
||||
Expect(issues).To(HaveLen(sample.Errors))
|
||||
Expect(issues[0].Suppressions).To(HaveLen(1))
|
||||
Expect(issues[0].Suppressions[0].Kind).To(Equal("inSource"))
|
||||
Expect(issues[0].Suppressions[0].Justification).To(Equal("Justification"))
|
||||
})
|
||||
|
||||
It("should not report an error if the violation is suppressed without certain rules", func() {
|
||||
sample := testutils.SampleCodeG401[0]
|
||||
source := sample.Code[0]
|
||||
@@ -1424,6 +1916,26 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(issues[0].Suppressions[0].Justification).To(Equal(""))
|
||||
})
|
||||
|
||||
It("should not report an error if the violation is suppressed without certain rules", func() {
|
||||
sample := testutils.SampleCodeG401[0]
|
||||
source := sample.Code[0]
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G401")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecSource := strings.Replace(source, "h := md5.New()", "h := md5.New() //gosec:disable", 1)
|
||||
nosecPackage.AddFile("md5.go", nosecSource)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
issues, _, _ := analyzer.Report()
|
||||
Expect(issues).To(HaveLen(sample.Errors))
|
||||
Expect(issues[0].Suppressions).To(HaveLen(1))
|
||||
Expect(issues[0].Suppressions[0].Kind).To(Equal("inSource"))
|
||||
Expect(issues[0].Suppressions[0].Justification).To(Equal(""))
|
||||
})
|
||||
|
||||
It("should not report an error if the violation is suppressed without certain rules", func() {
|
||||
sample := testutils.SampleCodeG405[0]
|
||||
source := sample.Code[0]
|
||||
@@ -1444,6 +1956,26 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(issues[0].Suppressions[0].Justification).To(Equal(""))
|
||||
})
|
||||
|
||||
It("should not report an error if the violation is suppressed without certain rules", func() {
|
||||
sample := testutils.SampleCodeG405[0]
|
||||
source := sample.Code[0]
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G405")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecSource := strings.Replace(source, "c, e := des.NewCipher([]byte(\"mySecret\"))", "c, e := des.NewCipher([]byte(\"mySecret\")) //gosec:disable", 1)
|
||||
nosecPackage.AddFile("cipher.go", nosecSource)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
issues, _, _ := analyzer.Report()
|
||||
Expect(issues).To(HaveLen(sample.Errors))
|
||||
Expect(issues[0].Suppressions).To(HaveLen(1))
|
||||
Expect(issues[0].Suppressions[0].Kind).To(Equal("inSource"))
|
||||
Expect(issues[0].Suppressions[0].Justification).To(Equal(""))
|
||||
})
|
||||
|
||||
It("should not report an error if the violation is suppressed without certain rules", func() {
|
||||
sample := testutils.SampleCodeG406[0]
|
||||
source := sample.Code[0]
|
||||
@@ -1464,6 +1996,26 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(issues[0].Suppressions[0].Justification).To(Equal(""))
|
||||
})
|
||||
|
||||
It("should not report an error if the violation is suppressed without certain rules", func() {
|
||||
sample := testutils.SampleCodeG406[0]
|
||||
source := sample.Code[0]
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G406")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecSource := strings.Replace(source, "h := md4.New()", "h := md4.New() //gosec:disable", 1)
|
||||
nosecPackage.AddFile("md4.go", nosecSource)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
issues, _, _ := analyzer.Report()
|
||||
Expect(issues).To(HaveLen(sample.Errors))
|
||||
Expect(issues[0].Suppressions).To(HaveLen(1))
|
||||
Expect(issues[0].Suppressions[0].Kind).To(Equal("inSource"))
|
||||
Expect(issues[0].Suppressions[0].Justification).To(Equal(""))
|
||||
})
|
||||
|
||||
It("should not report an error if the rule is not included", func() {
|
||||
sample := testutils.SampleCodeG101[0]
|
||||
source := sample.Code[0]
|
||||
@@ -1617,6 +2169,27 @@ var _ = Describe("Analyzer", func() {
|
||||
Expect(issues[0].Suppressions[0].Kind).To(Equal("inSource"))
|
||||
})
|
||||
|
||||
It("should not report an error if the violation is suppressed on a struct filed", func() {
|
||||
sample := testutils.SampleCodeG402[0]
|
||||
source := sample.Code[0]
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G402")).RulesInfo())
|
||||
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecSource := strings.Replace(source,
|
||||
"TLSClientConfig: &tls.Config{InsecureSkipVerify: true}",
|
||||
"TLSClientConfig: &tls.Config{InsecureSkipVerify: true} //gosec:disable G402", 1)
|
||||
nosecPackage.AddFile("tls.go", nosecSource)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
issues, _, _ := analyzer.Report()
|
||||
Expect(issues).To(HaveLen(sample.Errors))
|
||||
Expect(issues[0].Suppressions).To(HaveLen(1))
|
||||
Expect(issues[0].Suppressions[0].Kind).To(Equal("inSource"))
|
||||
})
|
||||
|
||||
It("should not report an error if the violation is suppressed on multi-lien issue", func() {
|
||||
source := `
|
||||
package main
|
||||
@@ -1631,6 +2204,37 @@ f62e5bcda4fae4f82370da0c6f20697b8f8447ef
|
||||
` + "`" + "//#nosec G101 -- false positive, this is not a private data" + `
|
||||
func main() {
|
||||
fmt.Printf("Label: %s ", TokenLabel)
|
||||
}
|
||||
`
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G101")).RulesInfo())
|
||||
nosecPackage := testutils.NewTestPackage()
|
||||
defer nosecPackage.Close()
|
||||
nosecPackage.AddFile("pwd.go", source)
|
||||
err := nosecPackage.Build()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = analyzer.Process(buildTags, nosecPackage.Path)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
issues, _, _ := analyzer.Report()
|
||||
Expect(issues).To(HaveLen(1))
|
||||
Expect(issues[0].Suppressions).To(HaveLen(1))
|
||||
Expect(issues[0].Suppressions[0].Kind).To(Equal("inSource"))
|
||||
Expect(issues[0].Suppressions[0].Justification).To(Equal("false positive, this is not a private data"))
|
||||
})
|
||||
|
||||
It("should not report an error if the violation is suppressed on multi-lien issue", func() {
|
||||
source := `
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
const TokenLabel = `
|
||||
source += "`" + `
|
||||
f62e5bcda4fae4f82370da0c6f20697b8f8447ef
|
||||
` + "`" + "//gosec:disable G101 -- false positive, this is not a private data" + `
|
||||
func main() {
|
||||
fmt.Printf("Label: %s ", TokenLabel)
|
||||
}
|
||||
`
|
||||
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G101")).RulesInfo())
|
||||
|
||||
@@ -51,7 +51,7 @@ func (al *AnalyzerList) AnalyzersInfo() (map[string]AnalyzerDefinition, map[stri
|
||||
type AnalyzerFilter func(string) bool
|
||||
|
||||
// NewAnalyzerFilter is a closure that will include/exclude the analyzer ID's based on
|
||||
// the supplied boolean value.
|
||||
// the supplied boolean value (false means don't remove, true means exclude).
|
||||
func NewAnalyzerFilter(action bool, analyzerIDs ...string) AnalyzerFilter {
|
||||
analyzerlist := make(map[string]bool)
|
||||
for _, analyzer := range analyzerIDs {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package analyzers
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"fmt"
|
||||
"go/token"
|
||||
"math"
|
||||
@@ -22,7 +23,6 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/exp/constraints"
|
||||
"golang.org/x/tools/go/analysis"
|
||||
"golang.org/x/tools/go/analysis/passes/buildssa"
|
||||
"golang.org/x/tools/go/ssa"
|
||||
@@ -40,7 +40,7 @@ type integer struct {
|
||||
type rangeResult struct {
|
||||
minValue int
|
||||
maxValue uint
|
||||
explixitPositiveVals []uint
|
||||
explicitPositiveVals []uint
|
||||
explicitNegativeVals []int
|
||||
isRangeCheck bool
|
||||
convertFound bool
|
||||
@@ -49,7 +49,7 @@ type rangeResult struct {
|
||||
type branchResults struct {
|
||||
minValue *int
|
||||
maxValue *uint
|
||||
explixitPositiveVals []uint
|
||||
explicitPositiveVals []uint
|
||||
explicitNegativeVals []int
|
||||
convertFound bool
|
||||
}
|
||||
@@ -141,8 +141,8 @@ func parseIntType(intType string) (integer, error) {
|
||||
return integer{}, fmt.Errorf("invalid bit size: %d", intSize)
|
||||
}
|
||||
|
||||
var min int
|
||||
var max uint
|
||||
var minVal int
|
||||
var maxVal uint
|
||||
|
||||
if signed {
|
||||
shiftAmount := intSize - 1
|
||||
@@ -152,19 +152,19 @@ func parseIntType(intType string) (integer, error) {
|
||||
return integer{}, fmt.Errorf("invalid shift amount: %d", shiftAmount)
|
||||
}
|
||||
|
||||
max = (1 << uint(shiftAmount)) - 1
|
||||
min = -1 << (intSize - 1)
|
||||
maxVal = (1 << uint(shiftAmount)) - 1
|
||||
minVal = -1 << (intSize - 1)
|
||||
|
||||
} else {
|
||||
max = (1 << uint(intSize)) - 1
|
||||
min = 0
|
||||
maxVal = (1 << uint(intSize)) - 1
|
||||
minVal = 0
|
||||
}
|
||||
|
||||
return integer{
|
||||
signed: signed,
|
||||
size: intSize,
|
||||
min: min,
|
||||
max: max,
|
||||
min: minVal,
|
||||
max: maxVal,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -226,7 +226,12 @@ func isStringToIntConversion(instr *ssa.Convert, dstType string) bool {
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
isSafe := bitSizeValue <= dstInt.size && signed == dstInt.signed
|
||||
|
||||
// we're good if:
|
||||
// - signs match and bit size is <= than destination
|
||||
// - parsing unsigned and bit size is < than destination
|
||||
isSafe := (bitSizeValue <= dstInt.size && signed == dstInt.signed) ||
|
||||
(bitSizeValue < dstInt.size && !signed)
|
||||
return isSafe
|
||||
}
|
||||
}
|
||||
@@ -269,9 +274,9 @@ func hasExplicitRangeCheck(instr *ssa.Convert, dstType string) bool {
|
||||
case *ssa.If:
|
||||
result := getResultRange(v, instr, visitedIfs)
|
||||
if result.isRangeCheck {
|
||||
minValue = max(minValue, &result.minValue)
|
||||
maxValue = min(maxValue, &result.maxValue)
|
||||
explicitPositiveVals = append(explicitPositiveVals, result.explixitPositiveVals...)
|
||||
minValue = max(minValue, result.minValue)
|
||||
maxValue = min(maxValue, result.maxValue)
|
||||
explicitPositiveVals = append(explicitPositiveVals, result.explicitPositiveVals...)
|
||||
explicitNegativeVals = append(explicitNegativeVals, result.explicitNegativeVals...)
|
||||
}
|
||||
case *ssa.Call:
|
||||
@@ -323,18 +328,19 @@ func getResultRange(ifInstr *ssa.If, instr *ssa.Convert, visitedIfs map[*ssa.If]
|
||||
|
||||
if thenBounds.convertFound {
|
||||
result.convertFound = true
|
||||
result.minValue = max(result.minValue, thenBounds.minValue)
|
||||
result.maxValue = min(result.maxValue, thenBounds.maxValue)
|
||||
result.explixitPositiveVals = append(result.explixitPositiveVals, thenBounds.explixitPositiveVals...)
|
||||
result.explicitNegativeVals = append(result.explicitNegativeVals, thenBounds.explicitNegativeVals...)
|
||||
result.minValue = maxWithPtr(result.minValue, thenBounds.minValue)
|
||||
result.maxValue = minWithPtr(result.maxValue, thenBounds.maxValue)
|
||||
} else if elseBounds.convertFound {
|
||||
result.convertFound = true
|
||||
result.minValue = max(result.minValue, elseBounds.minValue)
|
||||
result.maxValue = min(result.maxValue, elseBounds.maxValue)
|
||||
result.explixitPositiveVals = append(result.explixitPositiveVals, elseBounds.explixitPositiveVals...)
|
||||
result.explicitNegativeVals = append(result.explicitNegativeVals, elseBounds.explicitNegativeVals...)
|
||||
result.minValue = maxWithPtr(result.minValue, elseBounds.minValue)
|
||||
result.maxValue = minWithPtr(result.maxValue, elseBounds.maxValue)
|
||||
}
|
||||
|
||||
result.explicitPositiveVals = append(result.explicitPositiveVals, thenBounds.explicitPositiveVals...)
|
||||
result.explicitNegativeVals = append(result.explicitNegativeVals, thenBounds.explicitNegativeVals...)
|
||||
result.explicitPositiveVals = append(result.explicitPositiveVals, elseBounds.explicitPositiveVals...)
|
||||
result.explicitNegativeVals = append(result.explicitNegativeVals, elseBounds.explicitNegativeVals...)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -344,15 +350,26 @@ func updateResultFromBinOp(result *rangeResult, binOp *ssa.BinOp, instr *ssa.Con
|
||||
operandsFlipped := false
|
||||
|
||||
compareVal, op := getRealValueFromOperation(instr.X)
|
||||
if x != compareVal {
|
||||
y, operandsFlipped = x, true
|
||||
|
||||
// Handle FieldAddr
|
||||
if fieldAddr, ok := compareVal.(*ssa.FieldAddr); ok {
|
||||
compareVal = fieldAddr
|
||||
}
|
||||
|
||||
if !isSameOrRelated(x, compareVal) {
|
||||
y = x
|
||||
operandsFlipped = true
|
||||
}
|
||||
|
||||
constVal, ok := y.(*ssa.Const)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: constVal.Value nil check avoids #1229 panic but seems to be hiding a bug in the code above or in x/tools/go/ssa.
|
||||
if constVal.Value == nil {
|
||||
// log.Fatalf("[gosec] constVal.Value is nil flipped=%t, constVal=%#v, binOp=%#v", operandsFlipped, constVal, binOp)
|
||||
return
|
||||
}
|
||||
switch binOp.Op {
|
||||
case token.LEQ, token.LSS:
|
||||
updateMinMaxForLessOrEqual(result, constVal, binOp.Op, operandsFlipped, successPathConvert)
|
||||
@@ -362,40 +379,35 @@ func updateResultFromBinOp(result *rangeResult, binOp *ssa.BinOp, instr *ssa.Con
|
||||
if !successPathConvert {
|
||||
break
|
||||
}
|
||||
|
||||
// Determine if the constant value is positive or negative.
|
||||
if strings.Contains(constVal.String(), "-") {
|
||||
result.explicitNegativeVals = append(result.explicitNegativeVals, int(constVal.Int64()))
|
||||
} else {
|
||||
result.explixitPositiveVals = append(result.explixitPositiveVals, uint(constVal.Uint64()))
|
||||
}
|
||||
|
||||
updateExplicitValues(result, constVal)
|
||||
case token.NEQ:
|
||||
if successPathConvert {
|
||||
break
|
||||
}
|
||||
|
||||
// Determine if the constant value is positive or negative.
|
||||
if strings.Contains(constVal.String(), "-") {
|
||||
result.explicitNegativeVals = append(result.explicitNegativeVals, int(constVal.Int64()))
|
||||
} else {
|
||||
result.explixitPositiveVals = append(result.explixitPositiveVals, uint(constVal.Uint64()))
|
||||
}
|
||||
updateExplicitValues(result, constVal)
|
||||
}
|
||||
|
||||
if op == "neg" {
|
||||
min := result.minValue
|
||||
max := result.maxValue
|
||||
minVal := result.minValue
|
||||
maxVal := result.maxValue
|
||||
|
||||
if min >= 0 {
|
||||
result.maxValue = uint(min)
|
||||
if minVal >= 0 {
|
||||
result.maxValue = uint(minVal)
|
||||
}
|
||||
if max <= math.MaxInt {
|
||||
result.minValue = int(max) //nolint:gosec
|
||||
if maxVal <= math.MaxInt {
|
||||
result.minValue = int(maxVal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func updateExplicitValues(result *rangeResult, constVal *ssa.Const) {
|
||||
if strings.Contains(constVal.String(), "-") {
|
||||
result.explicitNegativeVals = append(result.explicitNegativeVals, int(constVal.Int64()))
|
||||
} else {
|
||||
result.explicitPositiveVals = append(result.explicitPositiveVals, uint(constVal.Uint64()))
|
||||
}
|
||||
}
|
||||
|
||||
func updateMinMaxForLessOrEqual(result *rangeResult, constVal *ssa.Const, op token.Token, operandsFlipped bool, successPathConvert bool) {
|
||||
// If the success path has a conversion and the operands are not flipped, then the constant value is the maximum value.
|
||||
if successPathConvert && !operandsFlipped {
|
||||
@@ -437,8 +449,10 @@ func walkBranchForConvert(block *ssa.BasicBlock, instr *ssa.Convert, visitedIfs
|
||||
bounds.convertFound = bounds.convertFound || result.convertFound
|
||||
|
||||
if result.isRangeCheck {
|
||||
bounds.minValue = toPtr(max(result.minValue, bounds.minValue))
|
||||
bounds.maxValue = toPtr(min(result.maxValue, bounds.maxValue))
|
||||
bounds.minValue = toPtr(maxWithPtr(result.minValue, bounds.minValue))
|
||||
bounds.maxValue = toPtr(minWithPtr(result.maxValue, bounds.maxValue))
|
||||
bounds.explicitPositiveVals = append(bounds.explicitPositiveVals, result.explicitPositiveVals...)
|
||||
bounds.explicitNegativeVals = append(bounds.explicitNegativeVals, result.explicitNegativeVals...)
|
||||
}
|
||||
case *ssa.Call:
|
||||
if v == instr.X {
|
||||
@@ -463,9 +477,10 @@ func isRangeCheck(v ssa.Value, x ssa.Value) bool {
|
||||
switch op := v.(type) {
|
||||
case *ssa.BinOp:
|
||||
switch op.Op {
|
||||
case token.LSS, token.LEQ, token.GTR, token.GEQ,
|
||||
token.EQL, token.NEQ:
|
||||
return op.X == compareVal || op.Y == compareVal
|
||||
case token.LSS, token.LEQ, token.GTR, token.GEQ, token.EQL, token.NEQ:
|
||||
leftMatch := isSameOrRelated(op.X, compareVal)
|
||||
rightMatch := isSameOrRelated(op.Y, compareVal)
|
||||
return leftMatch || rightMatch
|
||||
}
|
||||
}
|
||||
return false
|
||||
@@ -475,12 +490,36 @@ func getRealValueFromOperation(v ssa.Value) (ssa.Value, string) {
|
||||
switch v := v.(type) {
|
||||
case *ssa.UnOp:
|
||||
if v.Op == token.SUB {
|
||||
return v.X, "neg"
|
||||
val, _ := getRealValueFromOperation(v.X)
|
||||
return val, "neg"
|
||||
}
|
||||
return getRealValueFromOperation(v.X)
|
||||
case *ssa.FieldAddr:
|
||||
return v, "field"
|
||||
case *ssa.Alloc:
|
||||
return v, "alloc"
|
||||
}
|
||||
return v, ""
|
||||
}
|
||||
|
||||
func isSameOrRelated(a, b ssa.Value) bool {
|
||||
aVal, _ := getRealValueFromOperation(a)
|
||||
bVal, _ := getRealValueFromOperation(b)
|
||||
|
||||
if aVal == bVal {
|
||||
return true
|
||||
}
|
||||
|
||||
// Check if both are FieldAddr operations referring to the same field of the same struct
|
||||
if aField, aOk := aVal.(*ssa.FieldAddr); aOk {
|
||||
if bField, bOk := bVal.(*ssa.FieldAddr); bOk {
|
||||
return aField.X == bField.X && aField.Field == bField.Field
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func explicitValsInRange(explicitPosVals []uint, explicitNegVals []int, dstInt integer) bool {
|
||||
if len(explicitPosVals) == 0 && len(explicitNegVals) == 0 {
|
||||
return false
|
||||
@@ -501,24 +540,18 @@ func explicitValsInRange(explicitPosVals []uint, explicitNegVals []int, dstInt i
|
||||
return true
|
||||
}
|
||||
|
||||
func min[T constraints.Integer](a T, b *T) T {
|
||||
func minWithPtr[T cmp.Ordered](a T, b *T) T {
|
||||
if b == nil {
|
||||
return a
|
||||
}
|
||||
if a < *b {
|
||||
return a
|
||||
}
|
||||
return *b
|
||||
return min(a, *b)
|
||||
}
|
||||
|
||||
func max[T constraints.Integer](a T, b *T) T {
|
||||
func maxWithPtr[T cmp.Ordered](a T, b *T) T {
|
||||
if b == nil {
|
||||
return a
|
||||
}
|
||||
if a > *b {
|
||||
return a
|
||||
}
|
||||
return *b
|
||||
return max(a, *b)
|
||||
}
|
||||
|
||||
func toPtr[T any](a T) *T {
|
||||
|
||||
@@ -48,10 +48,7 @@ func runHardCodedNonce(pass *analysis.Pass) (interface{}, error) {
|
||||
// Example "Test" 3, 1 -- means the function "Test" which accepts 3 arguments, and has the nonce arg as second argument
|
||||
calls := map[string][]int{
|
||||
"(crypto/cipher.AEAD).Seal": {4, 1},
|
||||
"(crypto/cipher.AEAD).Open": {4, 1},
|
||||
"crypto/cipher.NewCBCDecrypter": {2, 1},
|
||||
"crypto/cipher.NewCBCEncrypter": {2, 1},
|
||||
"crypto/cipher.NewCFBDecrypter": {2, 1},
|
||||
"crypto/cipher.NewCFBEncrypter": {2, 1},
|
||||
"crypto/cipher.NewCTR": {2, 1},
|
||||
"crypto/cipher.NewOFB": {2, 1},
|
||||
@@ -163,9 +160,9 @@ func iterateThroughReferrers(variable ssa.Value, funcsToTrack map[string][]int,
|
||||
if refs == nil {
|
||||
return gosecIssues, nil
|
||||
}
|
||||
// Go trough all functions that use the given arg variable
|
||||
// Go through all functions that use the given arg variable
|
||||
for _, ref := range *refs {
|
||||
// Iterate trough the functions we are interested
|
||||
// Iterate through the functions we are interested
|
||||
for trackedFunc := range funcsToTrack {
|
||||
|
||||
// Split the functions we are interested in, by the '.' because we will use the function name to do the comparison
|
||||
@@ -62,6 +62,10 @@ func newIssue(analyzerID string, desc string, fileSet *token.FileSet,
|
||||
pos token.Pos, severity, confidence issue.Score,
|
||||
) *issue.Issue {
|
||||
file := fileSet.File(pos)
|
||||
// This can occur when there is a compilation issue into the code.
|
||||
if file == nil {
|
||||
return &issue.Issue{}
|
||||
}
|
||||
line := file.Line(pos)
|
||||
col := file.Position(pos).Column
|
||||
|
||||
|
||||
@@ -76,8 +76,8 @@ func (w *genAIGenerativeModelWrapper) GenerateContent(ctx context.Context, promp
|
||||
}
|
||||
|
||||
// NewGenAIClient creates a new gemini API client.
|
||||
func NewGenAIClient(ctx context.Context, aiApiKey, endpoint string) (GenAIClient, error) {
|
||||
clientOptions := []option.ClientOption{option.WithAPIKey(aiApiKey)}
|
||||
func NewGenAIClient(ctx context.Context, aiAPIKey, endpoint string) (GenAIClient, error) {
|
||||
clientOptions := []option.ClientOption{option.WithAPIKey(aiAPIKey)}
|
||||
if endpoint != "" {
|
||||
clientOptions = append(clientOptions, option.WithEndpoint(endpoint))
|
||||
}
|
||||
@@ -119,16 +119,16 @@ func generateSolutionByGemini(client GenAIClient, issues []*issue.Issue) error {
|
||||
}
|
||||
|
||||
// GenerateSolution generates a solution for the given issues using the specified AI provider
|
||||
func GenerateSolution(aiApiProvider, aiApiKey, endpoint string, issues []*issue.Issue) error {
|
||||
func GenerateSolution(aiAPIProvider, aiAPIKey, endpoint string, issues []*issue.Issue) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
||||
var client GenAIClient
|
||||
|
||||
switch aiApiProvider {
|
||||
switch aiAPIProvider {
|
||||
case GeminiProvider:
|
||||
var err error
|
||||
client, err = NewGenAIClient(ctx, aiApiKey, endpoint)
|
||||
client, err = NewGenAIClient(ctx, aiAPIKey, endpoint)
|
||||
if err != nil {
|
||||
return fmt.Errorf("generating autofix: %w", err)
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/securego/gosec/v2/issue"
|
||||
)
|
||||
@@ -44,17 +45,16 @@ func TestGenerateSolutionByGemini_Success(t *testing.T) {
|
||||
|
||||
mockClient := new(MockGenAIClient)
|
||||
mockModel := new(MockGenAIGenerativeModel)
|
||||
mockClient.On("GenerativeModel", GeminiModel).Return(mockModel)
|
||||
mockModel.On("GenerateContent", mock.Anything, mock.Anything).Return("Autofix for issue 1", nil)
|
||||
mockClient.On("GenerativeModel", GeminiModel).Return(mockModel).Once()
|
||||
mockModel.On("GenerateContent", mock.Anything, mock.Anything).Return("Autofix for issue 1", nil).Once()
|
||||
|
||||
// Act
|
||||
err := generateSolutionByGemini(mockClient, issues)
|
||||
|
||||
// Assert
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "Autofix for issue 1", issues[0].Autofix)
|
||||
mockClient.AssertExpectations(t)
|
||||
mockModel.AssertExpectations(t)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []*issue.Issue{{What: "Example issue 1", Autofix: "Autofix for issue 1"}}, issues)
|
||||
mock.AssertExpectationsForObjects(t, mockClient, mockModel)
|
||||
}
|
||||
|
||||
func TestGenerateSolutionByGemini_NoCandidates(t *testing.T) {
|
||||
@@ -65,17 +65,15 @@ func TestGenerateSolutionByGemini_NoCandidates(t *testing.T) {
|
||||
|
||||
mockClient := new(MockGenAIClient)
|
||||
mockModel := new(MockGenAIGenerativeModel)
|
||||
mockClient.On("GenerativeModel", GeminiModel).Return(mockModel)
|
||||
mockModel.On("GenerateContent", mock.Anything, mock.Anything).Return("", nil)
|
||||
mockClient.On("GenerativeModel", GeminiModel).Return(mockModel).Once()
|
||||
mockModel.On("GenerateContent", mock.Anything, mock.Anything).Return("", nil).Once()
|
||||
|
||||
// Act
|
||||
err := generateSolutionByGemini(mockClient, issues)
|
||||
|
||||
// Assert
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "no autofix returned by gemini", err.Error())
|
||||
mockClient.AssertExpectations(t)
|
||||
mockModel.AssertExpectations(t)
|
||||
require.EqualError(t, err, "no autofix returned by gemini")
|
||||
mock.AssertExpectationsForObjects(t, mockClient, mockModel)
|
||||
}
|
||||
|
||||
func TestGenerateSolutionByGemini_APIError(t *testing.T) {
|
||||
@@ -86,17 +84,15 @@ func TestGenerateSolutionByGemini_APIError(t *testing.T) {
|
||||
|
||||
mockClient := new(MockGenAIClient)
|
||||
mockModel := new(MockGenAIGenerativeModel)
|
||||
mockClient.On("GenerativeModel", GeminiModel).Return(mockModel)
|
||||
mockModel.On("GenerateContent", mock.Anything, mock.Anything).Return("", errors.New("API error"))
|
||||
mockClient.On("GenerativeModel", GeminiModel).Return(mockModel).Once()
|
||||
mockModel.On("GenerateContent", mock.Anything, mock.Anything).Return("", errors.New("API error")).Once()
|
||||
|
||||
// Act
|
||||
err := generateSolutionByGemini(mockClient, issues)
|
||||
|
||||
// Assert
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "generating autofix with gemini: API error", err.Error())
|
||||
mockClient.AssertExpectations(t)
|
||||
mockModel.AssertExpectations(t)
|
||||
require.EqualError(t, err, "generating autofix with gemini: API error")
|
||||
mock.AssertExpectationsForObjects(t, mockClient, mockModel)
|
||||
}
|
||||
|
||||
func TestGenerateSolution_UnsupportedProvider(t *testing.T) {
|
||||
@@ -109,6 +105,5 @@ func TestGenerateSolution_UnsupportedProvider(t *testing.T) {
|
||||
err := GenerateSolution("unsupported-provider", "test-api-key", "", issues)
|
||||
|
||||
// Assert
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "ai provider not supported", err.Error())
|
||||
require.EqualError(t, err, "ai provider not supported")
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ USAGE:
|
||||
|
||||
`
|
||||
// Environment variable for AI API key.
|
||||
aiApiKeyEnv = "GOSEC_AI_API_KEY" // #nosec G101
|
||||
aiAPIKeyEnv = "GOSEC_AI_API_KEY" // #nosec G101
|
||||
)
|
||||
|
||||
type arrayFlags []string
|
||||
@@ -154,13 +154,13 @@ var (
|
||||
flagTerse = flag.Bool("terse", false, "Shows only the results and summary")
|
||||
|
||||
// AI platform provider to generate solutions to issues
|
||||
flagAiApiProvider = flag.String("ai-api-provider", "", "AI API provider to generate auto fixes to issues.\nValid options are: gemini")
|
||||
flagAiAPIProvider = flag.String("ai-api-provider", "", "AI API provider to generate auto fixes to issues.\nValid options are: gemini")
|
||||
|
||||
// key to implementing AI provider services
|
||||
flagAiApiKey = flag.String("ai-api-key", "", "key to access the AI API")
|
||||
flagAiAPIKey = flag.String("ai-api-key", "", "Key to access the AI API")
|
||||
|
||||
// endpoint to the AI provider
|
||||
flagAiEndpoint = flag.String("ai-endpoint", "", "endpoint AI API.\nThis is optional, the default API endpoint will be used when not provided.")
|
||||
flagAiEndpoint = flag.String("ai-endpoint", "", "Endpoint AI API.\nThis is optional, the default API endpoint will be used when not provided.")
|
||||
|
||||
// exclude the folders from scan
|
||||
flagDirsExclude arrayFlags
|
||||
@@ -224,11 +224,11 @@ func loadConfig(configFile string) (gosec.Config, error) {
|
||||
if *flagEnableAudit {
|
||||
config.SetGlobal(gosec.Audit, "true")
|
||||
}
|
||||
// set global option IncludeRules ,when flag set or global option IncludeRules is nil
|
||||
// set global option IncludeRules, when flag set or global option IncludeRules is nil
|
||||
if v, _ := config.GetGlobal(gosec.IncludeRules); *flagRulesInclude != "" || v == "" {
|
||||
config.SetGlobal(gosec.IncludeRules, *flagRulesInclude)
|
||||
}
|
||||
// set global option ExcludeRules ,when flag set or global option IncludeRules is nil
|
||||
// set global option ExcludeRules, when flag set or global option ExcludeRules is nil
|
||||
if v, _ := config.GetGlobal(gosec.ExcludeRules); flagRulesExclude.String() != "" || v == "" {
|
||||
config.SetGlobal(gosec.ExcludeRules, flagRulesExclude.String())
|
||||
}
|
||||
@@ -438,12 +438,13 @@ func main() {
|
||||
}
|
||||
|
||||
ruleList := loadRules(includeRules, excludeRules)
|
||||
if len(ruleList.Rules) == 0 {
|
||||
logger.Fatal("No rules are configured")
|
||||
}
|
||||
|
||||
analyzerList := loadAnalyzers(includeRules, excludeRules)
|
||||
|
||||
if len(ruleList.Rules) == 0 && len(analyzerList.Analyzers) == 0 {
|
||||
logger.Fatal("No rules/analyzers are configured")
|
||||
}
|
||||
|
||||
// Create the analyzer
|
||||
analyzer := gosec.NewAnalyzer(config, *flagScanTests, *flagExcludeGenerated, *flagTrackSuppressions, *flagConcurrency, logger)
|
||||
analyzer.LoadRules(ruleList.RulesInfo())
|
||||
@@ -503,12 +504,12 @@ func main() {
|
||||
reportInfo := gosec.NewReportInfo(issues, metrics, errors).WithVersion(Version)
|
||||
|
||||
// Call AI request to solve the issues
|
||||
aiApiKey := os.Getenv(aiApiKeyEnv)
|
||||
if aiApiKeyEnv == "" {
|
||||
aiApiKey = *flagAiApiKey
|
||||
aiAPIKey := os.Getenv(aiAPIKeyEnv)
|
||||
if aiAPIKey == "" {
|
||||
aiAPIKey = *flagAiAPIKey
|
||||
}
|
||||
if *flagAiApiProvider != "" && aiApiKey != "" {
|
||||
err := autofix.GenerateSolution(*flagAiApiProvider, aiApiKey, *flagAiEndpoint, issues)
|
||||
if *flagAiAPIProvider != "" && aiAPIKey != "" {
|
||||
err := autofix.GenerateSolution(*flagAiAPIProvider, aiAPIKey, *flagAiEndpoint, issues)
|
||||
if err != nil {
|
||||
logger.Print(err)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"cmp"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -14,26 +15,14 @@ func extractLineNumber(s string) int {
|
||||
return lineNumber
|
||||
}
|
||||
|
||||
type sortBySeverity []*issue.Issue
|
||||
|
||||
func (s sortBySeverity) Len() int { return len(s) }
|
||||
|
||||
func (s sortBySeverity) Less(i, j int) bool {
|
||||
if s[i].Severity == s[j].Severity {
|
||||
if s[i].What == s[j].What {
|
||||
if s[i].File == s[j].File {
|
||||
return extractLineNumber(s[i].Line) > extractLineNumber(s[j].Line)
|
||||
}
|
||||
return s[i].File > s[j].File
|
||||
}
|
||||
return s[i].What > s[j].What
|
||||
}
|
||||
return s[i].Severity > s[j].Severity
|
||||
}
|
||||
|
||||
func (s sortBySeverity) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
|
||||
// sortIssues sorts the issues by severity in descending order
|
||||
func sortIssues(issues []*issue.Issue) {
|
||||
sort.Sort(sortBySeverity(issues))
|
||||
slices.SortFunc(issues, func(i, j *issue.Issue) int {
|
||||
return -cmp.Or(
|
||||
cmp.Compare(i.Severity, j.Severity),
|
||||
cmp.Compare(i.What, j.What),
|
||||
cmp.Compare(i.File, j.File),
|
||||
cmp.Compare(extractLineNumber(i.Line), extractLineNumber(j.Line)),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ func getGoCipherConfig(name string, sstls ServerSideTLSJson) (goCipherConfigurat
|
||||
cipherConf.MinVersion = fmt.Sprintf("0x%04x", versions[0])
|
||||
cipherConf.MaxVersion = fmt.Sprintf("0x%04x", versions[len(versions)-1])
|
||||
} else {
|
||||
return cipherConf, fmt.Errorf("No TLS versions found for configuration '%s'", name)
|
||||
return cipherConf, fmt.Errorf("no TLS versions found for configuration '%s'", name)
|
||||
}
|
||||
return cipherConf, nil
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ func (c Config) WriteTo(w io.Writer) (int64, error) {
|
||||
func (c Config) Get(section string) (interface{}, error) {
|
||||
settings, found := c[section]
|
||||
if !found {
|
||||
return nil, fmt.Errorf("Section %s not in configuration", section)
|
||||
return nil, fmt.Errorf("section %s not in configuration", section)
|
||||
}
|
||||
return settings, nil
|
||||
}
|
||||
|
||||
84
go.mod
84
go.mod
@@ -1,63 +1,59 @@
|
||||
module github.com/securego/gosec/v2
|
||||
|
||||
require (
|
||||
github.com/ccojocar/zxcvbn-go v1.0.2
|
||||
github.com/google/generative-ai-go v0.17.0
|
||||
github.com/ccojocar/zxcvbn-go v1.0.4
|
||||
github.com/google/generative-ai-go v0.20.1
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/gookit/color v1.5.4
|
||||
github.com/lib/pq v1.10.9
|
||||
github.com/mozilla/tls-observatory v0.0.0-20210609171429-7bc42856d2e5
|
||||
github.com/onsi/ginkgo/v2 v2.20.2
|
||||
github.com/onsi/gomega v1.34.2
|
||||
github.com/stretchr/testify v1.9.0
|
||||
golang.org/x/crypto v0.26.0
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616
|
||||
golang.org/x/text v0.17.0
|
||||
golang.org/x/tools v0.24.0
|
||||
google.golang.org/api v0.195.0
|
||||
github.com/onsi/ginkgo/v2 v2.23.4
|
||||
github.com/onsi/gomega v1.37.0
|
||||
github.com/stretchr/testify v1.10.0
|
||||
golang.org/x/crypto v0.40.0
|
||||
golang.org/x/text v0.27.0
|
||||
golang.org/x/tools v0.35.0
|
||||
google.golang.org/api v0.242.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.115.1 // indirect
|
||||
cloud.google.com/go/ai v0.8.0 // indirect
|
||||
cloud.google.com/go/auth v0.9.1 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.4 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.5.0 // indirect
|
||||
cloud.google.com/go/longrunning v0.5.7 // indirect
|
||||
cloud.google.com/go v0.121.2 // indirect
|
||||
cloud.google.com/go/ai v0.12.1 // indirect
|
||||
cloud.google.com/go/auth v0.16.2 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.7.0 // indirect
|
||||
cloud.google.com/go/longrunning v0.6.7 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 // indirect
|
||||
github.com/google/s2a-go v0.1.8 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.13.0 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a // indirect
|
||||
github.com/google/s2a-go v0.1.9 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.14.2 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 // indirect
|
||||
go.opentelemetry.io/otel v1.26.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.26.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.26.0 // indirect
|
||||
golang.org/x/mod v0.20.0 // indirect
|
||||
golang.org/x/net v0.28.0 // indirect
|
||||
golang.org/x/oauth2 v0.22.0 // indirect
|
||||
golang.org/x/sync v0.8.0 // indirect
|
||||
golang.org/x/sys v0.24.0 // indirect
|
||||
golang.org/x/time v0.6.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240725223205-93522f1f2a9f // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240823204242-4ba0660f739c // indirect
|
||||
google.golang.org/grpc v1.65.0 // indirect
|
||||
google.golang.org/protobuf v1.34.2 // indirect
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
|
||||
go.opentelemetry.io/otel v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.36.0 // indirect
|
||||
go.uber.org/automaxprocs v1.6.0 // indirect
|
||||
golang.org/x/mod v0.26.0 // indirect
|
||||
golang.org/x/net v0.42.0 // indirect
|
||||
golang.org/x/oauth2 v0.30.0 // indirect
|
||||
golang.org/x/sync v0.16.0 // indirect
|
||||
golang.org/x/sys v0.34.0 // indirect
|
||||
golang.org/x/time v0.12.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
|
||||
google.golang.org/grpc v1.73.0 // indirect
|
||||
google.golang.org/protobuf v1.36.6 // indirect
|
||||
)
|
||||
|
||||
go 1.22
|
||||
|
||||
toolchain go1.22.0
|
||||
go 1.23.0
|
||||
|
||||
194
go.sum
194
go.sum
@@ -13,26 +13,26 @@ cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bP
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.60.0/go.mod h1:yw2G51M9IfRboUH61Us8GqCeF1PzPblB823Mn2q2eAU=
|
||||
cloud.google.com/go v0.115.1 h1:Jo0SM9cQnSkYfp44+v+NQXHpcHqlnRJk2qxh6yvxxxQ=
|
||||
cloud.google.com/go v0.115.1/go.mod h1:DuujITeaufu3gL68/lOFIirVNJwQeyf5UXyi+Wbgknc=
|
||||
cloud.google.com/go/ai v0.8.0 h1:rXUEz8Wp2OlrM8r1bfmpF2+VKqc1VJpafE3HgzRnD/w=
|
||||
cloud.google.com/go/ai v0.8.0/go.mod h1:t3Dfk4cM61sytiggo2UyGsDVW3RF1qGZaUKDrZFyqkE=
|
||||
cloud.google.com/go/auth v0.9.1 h1:+pMtLEV2k0AXKvs/tGZojuj6QaioxfUjOpMsG5Gtx+w=
|
||||
cloud.google.com/go/auth v0.9.1/go.mod h1:Sw8ocT5mhhXxFklyhT12Eiy0ed6tTrPMCJjSI8KhYLk=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.4 h1:0GWE/FUsXhf6C+jAkWgYm7X9tK8cuEIfy19DBn6B6bY=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.4/go.mod h1:jC/jOpwFP6JBxhB3P5Rr0a9HLMC/Pe3eaL4NmdvqPtc=
|
||||
cloud.google.com/go v0.121.2 h1:v2qQpN6Dx9x2NmwrqlesOt3Ys4ol5/lFZ6Mg1B7OJCg=
|
||||
cloud.google.com/go v0.121.2/go.mod h1:nRFlrHq39MNVWu+zESP2PosMWA0ryJw8KUBZ2iZpxbw=
|
||||
cloud.google.com/go/ai v0.12.1 h1:m1n/VjUuHS+pEO/2R4/VbuuEIkgk0w67fDQvFaMngM0=
|
||||
cloud.google.com/go/ai v0.12.1/go.mod h1:5vIPNe1ZQsVZqCliXIPL4QnhObQQY4d9hAGHdVc4iw4=
|
||||
cloud.google.com/go/auth v0.16.2 h1:QvBAGFPLrDeoiNjyfVunhQ10HKNYuOwZ5noee0M5df4=
|
||||
cloud.google.com/go/auth v0.16.2/go.mod h1:sRBas2Y1fB1vZTdurouM0AzuYQBMZinrUYL8EufhtEA=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY=
|
||||
cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY=
|
||||
cloud.google.com/go/compute/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU=
|
||||
cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/longrunning v0.5.7 h1:WLbHekDbjK1fVFD3ibpFFVoyizlLRl73I7YKuAKilhU=
|
||||
cloud.google.com/go/longrunning v0.5.7/go.mod h1:8GClkudohy1Fxm3owmBGid8W0pSgodEMwEAztp38Xng=
|
||||
cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE=
|
||||
cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
@@ -66,8 +66,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/ccojocar/zxcvbn-go v1.0.2 h1:na/czXU8RrhXO4EZme6eQJLR4PzcGsahsBOAwU6I3Vg=
|
||||
github.com/ccojocar/zxcvbn-go v1.0.2/go.mod h1:g1qkXtUSvHP8lhHp5GrSmTz6uWALGRMQdw6Qnz/hi60=
|
||||
github.com/ccojocar/zxcvbn-go v1.0.4 h1:FWnCIRMXPj43ukfX000kvBZvV6raSxakYr1nzyNrUcc=
|
||||
github.com/ccojocar/zxcvbn-go v1.0.4/go.mod h1:3GxGX+rHmueTUMvm5ium7irpyjmm7ikxYFOSJB21Das=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
@@ -115,8 +115,8 @@ github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-redis/redis v6.15.8+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
@@ -133,8 +133,6 @@ github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4er
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
@@ -156,24 +154,22 @@ 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.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg=
|
||||
github.com/google/certificate-transparency-go v1.1.1/go.mod h1:FDKqPvSXawb2ecErVRrD+nfy23RCzyl7eqVCEmlT1Zs=
|
||||
github.com/google/generative-ai-go v0.17.0 h1:kUmCXUIwJouD7I7ev3OmxzzQVICyhIWAxaXk2yblCMY=
|
||||
github.com/google/generative-ai-go v0.17.0/go.mod h1:JYolL13VG7j79kM5BtHz4qwONHkeJQzOCkKXnpqtS/E=
|
||||
github.com/google/generative-ai-go v0.20.1 h1:6dEIujpgN2V0PgLhr6c/M1ynRdc7ARtiIDPFzj45uNQ=
|
||||
github.com/google/generative-ai-go v0.20.1/go.mod h1:TjOnZJmZKzarWbjUJgy+r3Ee7HGBRVLhOIgupnwR4Bg=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
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=
|
||||
@@ -183,24 +179,23 @@ 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-20240827171923-fa2c70bbbfe5 h1:5iH8iuqE5apketRbSFBy+X1V0o+l+8NF1avt4HWl7cA=
|
||||
github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||
github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a h1://KbezygeMJZCSHH+HgUZiTeSoiuFspbMg1ge+eFj18=
|
||||
github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM=
|
||||
github.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA=
|
||||
github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
|
||||
github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
|
||||
github.com/google/trillian v1.3.11/go.mod h1:0tPraVHrSDkA3BO6vKX67zgLXs6SsOAbHEivX+9mPgw=
|
||||
github.com/google/uuid v0.0.0-20161128191214-064e2069ce9c/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
|
||||
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/googleapis/gax-go/v2 v2.13.0 h1:yitjD5f7jQHhyDsnhKEBU52NdvvdSeGzlAnDPT0hH1s=
|
||||
github.com/googleapis/gax-go/v2 v2.13.0/go.mod h1:Z/fvTZXF8/uw7Xu5GuslPw+bplx6SS338j1Is2S+B7A=
|
||||
github.com/googleapis/gax-go/v2 v2.14.2 h1:eBLnkZ9635krYIPD+ag1USrOAI0Nr0QYF3+/3GqO0k0=
|
||||
github.com/googleapis/gax-go/v2 v2.14.2/go.mod h1:ON64QhlJkhVtSqp4v1uaK92VyZ2gmvDQsweuyLV+8+w=
|
||||
github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0=
|
||||
github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w=
|
||||
github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU=
|
||||
@@ -245,11 +240,13 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/letsencrypt/pkcs11key/v4 v4.0.0/go.mod h1:EFUvBDay26dErnNb70Nd0/VW3tJiIbETBPTl9ATXQag=
|
||||
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
@@ -293,11 +290,11 @@ github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXW
|
||||
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/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4=
|
||||
github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag=
|
||||
github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
|
||||
github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8=
|
||||
github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc=
|
||||
github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y=
|
||||
github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
|
||||
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=
|
||||
@@ -307,6 +304,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
||||
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
|
||||
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
@@ -324,6 +323,8 @@ github.com/pseudomuto/protokit v0.2.0/go.mod h1:2PdH30hxVHsup8KpBTOXTBeMVhJZVio3
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
@@ -344,8 +345,6 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v0.0.0-20170130113145-4d4bfba8f1d1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
@@ -353,11 +352,8 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
|
||||
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.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
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=
|
||||
@@ -367,8 +363,8 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/viki-org/dnscache v0.0.0-20130720023526-c70c1f23c5d8/go.mod h1:dniwbG03GafCjFohMDmz6Zc6oCuiqgH6tGNyXTkHzXE=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8=
|
||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=
|
||||
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
|
||||
@@ -385,21 +381,27 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 h1:A3SayB3rNyt+1S6qpI9mHPkeHTZbD7XILEqWnYZb2l0=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0/go.mod h1:27iA5uvhuRNmalO+iEUdVn5ZMj2qy10Mm+XRIpRmyuU=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 h1:Xs2Ncz0gNihqu9iosIZ5SkBbWo5T8JhhLJFMQL1qmLI=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0/go.mod h1:vy+2G/6NvVMpwGX/NyLqcC41fxepnuKHk16E6IZUcJc=
|
||||
go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs=
|
||||
go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4=
|
||||
go.opentelemetry.io/otel/metric v1.26.0 h1:7S39CLuY5Jgg9CrnA9HHiEjGMF/X2VHvoXGgSllRz30=
|
||||
go.opentelemetry.io/otel/metric v1.26.0/go.mod h1:SY+rHOI4cEawI9a7N1A4nIg/nTQXe1ccCNWYOJUrpX4=
|
||||
go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA=
|
||||
go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
|
||||
go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
|
||||
go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
|
||||
go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
|
||||
go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
|
||||
go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=
|
||||
go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4=
|
||||
go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
|
||||
go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
|
||||
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
@@ -415,8 +417,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.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
|
||||
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
|
||||
golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
|
||||
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
|
||||
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=
|
||||
@@ -428,8 +430,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
|
||||
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E=
|
||||
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
@@ -442,8 +444,6 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
@@ -452,8 +452,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.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
|
||||
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=
|
||||
golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
|
||||
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=
|
||||
@@ -486,15 +486,15 @@ golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/
|
||||
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-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
|
||||
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
||||
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
|
||||
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA=
|
||||
golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
|
||||
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -504,8 +504,8 @@ 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.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
||||
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
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=
|
||||
@@ -546,25 +546,25 @@ 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.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
|
||||
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
|
||||
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU=
|
||||
golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
|
||||
golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg=
|
||||
golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0=
|
||||
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.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
|
||||
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
|
||||
golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
|
||||
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
|
||||
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@@ -611,8 +611,8 @@ 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.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
|
||||
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
|
||||
golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=
|
||||
golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
|
||||
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=
|
||||
@@ -632,8 +632,8 @@ google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/api v0.195.0 h1:Ude4N8FvTKnnQJHU48RFI40jOBgIrL8Zqr3/QeST6yU=
|
||||
google.golang.org/api v0.195.0/go.mod h1:DOGRWuv3P8TU8Lnz7uQc4hyNqrBpMtD9ppW3wBJurgc=
|
||||
google.golang.org/api v0.242.0 h1:7Lnb1nfnpvbkCiZek6IXKdJ0MFuAZNAJKQfA1ws62xg=
|
||||
google.golang.org/api v0.242.0/go.mod h1:cOVEm2TpdAGHL2z+UwyS+kmlGr3bVWQQ6sYEqkKje50=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
@@ -672,10 +672,12 @@ google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1m
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200626011028-ee7919e894b5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200707001353-8e8330bf89df/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240725223205-93522f1f2a9f h1:b1Ln/PG8orm0SsBbHZWke8dDp2lrCD4jSmfglFpTZbk=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240725223205-93522f1f2a9f/go.mod h1:AHT0dDg3SoMOgZGnZk29b5xTbPHMoEC8qthmBLJCpys=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240823204242-4ba0660f739c h1:Kqjm4WpoWvwhMPcrAczoTyMySQmYa9Wy2iL6Con4zn8=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240823204242-4ba0660f739c/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
|
||||
google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 h1:1tXaIXCracvtsRxSBsYDiSBN0cuJvM7QYW+MrpIRY78=
|
||||
google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:49MsLSx0oWMOZqcpB3uL8ZOkAh1+TndpJ8ONoCBWiZk=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
||||
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
@@ -690,9 +692,8 @@ google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.29.0/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
|
||||
google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
|
||||
google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok=
|
||||
google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
@@ -703,13 +704,14 @@ 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.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
|
||||
@@ -83,7 +83,7 @@ func GetInt(n ast.Node) (int64, error) {
|
||||
if node, ok := n.(*ast.BasicLit); ok && node.Kind == token.INT {
|
||||
return strconv.ParseInt(node.Value, 0, 64)
|
||||
}
|
||||
return 0, fmt.Errorf("Unexpected AST node type: %T", n)
|
||||
return 0, fmt.Errorf("unexpected AST node type: %T", n)
|
||||
}
|
||||
|
||||
// GetFloat will read and return a float value from an ast.BasicLit
|
||||
@@ -91,7 +91,7 @@ func GetFloat(n ast.Node) (float64, error) {
|
||||
if node, ok := n.(*ast.BasicLit); ok && node.Kind == token.FLOAT {
|
||||
return strconv.ParseFloat(node.Value, 64)
|
||||
}
|
||||
return 0.0, fmt.Errorf("Unexpected AST node type: %T", n)
|
||||
return 0.0, fmt.Errorf("unexpected AST node type: %T", n)
|
||||
}
|
||||
|
||||
// GetChar will read and return a char value from an ast.BasicLit
|
||||
@@ -99,7 +99,7 @@ func GetChar(n ast.Node) (byte, error) {
|
||||
if node, ok := n.(*ast.BasicLit); ok && node.Kind == token.CHAR {
|
||||
return node.Value[0], nil
|
||||
}
|
||||
return 0, fmt.Errorf("Unexpected AST node type: %T", n)
|
||||
return 0, fmt.Errorf("unexpected AST node type: %T", n)
|
||||
}
|
||||
|
||||
// GetStringRecursive will recursively walk down a tree of *ast.BinaryExpr. It will then concat the results, and return.
|
||||
@@ -142,7 +142,7 @@ func GetString(n ast.Node) (string, error) {
|
||||
return strconv.Unquote(node.Value)
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("Unexpected AST node type: %T", n)
|
||||
return "", fmt.Errorf("unexpected AST node type: %T", n)
|
||||
}
|
||||
|
||||
// GetCallObject returns the object and call expression and associated
|
||||
|
||||
@@ -17,14 +17,8 @@ var _ = Describe("Helpers", func() {
|
||||
Context("when listing package paths", func() {
|
||||
var dir string
|
||||
JustBeforeEach(func() {
|
||||
var err error
|
||||
dir, err = os.MkdirTemp("", "gosec")
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
_, err = os.MkdirTemp(dir, "test*.go")
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
})
|
||||
AfterEach(func() {
|
||||
err := os.RemoveAll(dir)
|
||||
dir = GinkgoT().TempDir()
|
||||
_, err := os.MkdirTemp(dir, "test*.go")
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
})
|
||||
It("should return the root directory as package path", func() {
|
||||
|
||||
@@ -65,7 +65,6 @@ var ruleToCWE = map[string]string{
|
||||
"G110": "409",
|
||||
"G111": "22",
|
||||
"G112": "400",
|
||||
"G113": "190",
|
||||
"G114": "676",
|
||||
"G115": "190",
|
||||
"G201": "89",
|
||||
|
||||
@@ -51,9 +51,9 @@ func createReportInfo(rule string, weakness *cwe.Weakness) gosec.ReportInfo {
|
||||
}
|
||||
|
||||
func stripString(str string) string {
|
||||
ret := strings.Replace(str, "\n", "", -1)
|
||||
ret = strings.Replace(ret, " ", "", -1)
|
||||
ret = strings.Replace(ret, "\t", "", -1)
|
||||
ret := strings.ReplaceAll(str, "\n", "")
|
||||
ret = strings.ReplaceAll(ret, " ", "")
|
||||
ret = strings.ReplaceAll(ret, "\t", "")
|
||||
return ret
|
||||
}
|
||||
|
||||
@@ -278,11 +278,40 @@ var _ = Describe("Formatter", func() {
|
||||
})
|
||||
Context("When using different report formats", func() {
|
||||
grules := []string{
|
||||
"G101", "G102", "G103", "G104", "G106", "G107", "G109",
|
||||
"G110", "G111", "G112", "G113", "G201", "G202", "G203",
|
||||
"G204", "G301", "G302", "G303", "G304", "G305", "G401",
|
||||
"G402", "G403", "G404", "G405", "G406", "G407", "G501",
|
||||
"G502", "G503", "G504", "G505", "G506", "G507", "G601",
|
||||
"G101",
|
||||
"G102",
|
||||
"G103",
|
||||
"G104",
|
||||
"G106",
|
||||
"G107",
|
||||
"G109",
|
||||
"G110",
|
||||
"G111",
|
||||
"G112",
|
||||
"G201",
|
||||
"G202",
|
||||
"G203",
|
||||
"G204",
|
||||
"G301",
|
||||
"G302",
|
||||
"G303",
|
||||
"G304",
|
||||
"G305",
|
||||
"G401",
|
||||
"G402",
|
||||
"G403",
|
||||
"G404",
|
||||
"G405",
|
||||
"G406",
|
||||
"G407",
|
||||
"G501",
|
||||
"G502",
|
||||
"G503",
|
||||
"G504",
|
||||
"G505",
|
||||
"G506",
|
||||
"G507",
|
||||
"G601",
|
||||
}
|
||||
|
||||
It("csv formatted report should contain the CWE mapping", func() {
|
||||
|
||||
@@ -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/1.0.2/css/bulma.min.css" integrity="sha512-RpeJZX3aH5oZN3U3JhE7Sd+HG8XQsqmP3clIbu4G28p668yNsRNj3zMASKe1ATjl/W80wuEtCx2dFA8xaebG5w==" crossorigin="anonymous"/>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/styles/default.min.css" integrity="sha512-hasIneQUHlh06VNBe7f6ZcHmeRTLIaQWFd43YriJ0UND19bvYRauxthDg8E4eVNPm9bRUhr5JGeqH7FRFXQu5g==" crossorigin="anonymous"/>
|
||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/highlight.min.js" integrity="sha512-6yoqbrcLAHDWAdQmiRlHG4+m0g/CT/V9AGyxabG8j7Jk8j3r3K6due7oqpiRMZqcYe9WM2gPcaNNxnl2ux+3tA==" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/languages/go.min.js" integrity="sha512-k7OybVx0SC719WXdukEkoxjgQBdxeRIFuMIBO2LffEGfE7v/cgRvQp/0UrF9MiHBGzVOol2yuvaV1TAW2zAFJA==" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/1.0.4/css/bulma.min.css" integrity="sha512-yh2RE0wZCVZeysGiqTwDTO/dKelCbS9bP2L94UvOFtl/FKXcNAje3Y2oBg/ZMZ3LS1sicYk4dYVGtDex75fvvA==" crossorigin="anonymous"/>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/default.min.css" integrity="sha512-hasIneQUHlh06VNBe7f6ZcHmeRTLIaQWFd43YriJ0UND19bvYRauxthDg8E4eVNPm9bRUhr5JGeqH7FRFXQu5g==" crossorigin="anonymous"/>
|
||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js" integrity="sha512-EBLzUL8XLl+va/zAsmXwS7Z2B1F9HUHkZwyS/VKwh3S7T/U0nF4BaU29EP/ZSf6zgiIxYAnKLu6bJ8dqpmX5uw==" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/languages/go.min.js" integrity="sha512-weC0VNVf2qQR6OY675qO0AEL92gt3h5f2VGjhMUvi/UqFHaWzIEL5S/8Dt763fWfKftchzb7GryvEj/2HC9Exw==" 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/7.25.6/babel.min.js" integrity="sha512-8M1WWEzuftS49rfh63fHz354qx+Pzvp3kcQVVTOxIdFSzjYC3I3vk5zgN0guAook97MQIZTfEdl9pUQTov9V6A==" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.28.1/babel.min.js" integrity="sha512-SSqlwbIuz75Gz/tzPjqnxeFSMChqliTzO0op6pmAWyMiu9JGCsoVlJKflK4HrJNBH4SjryMrmLV4gGFn5qru/w==" crossorigin="anonymous"></script>
|
||||
<style>
|
||||
.field-label {
|
||||
min-width: 80px;
|
||||
@@ -73,7 +73,7 @@
|
||||
var current = ReactDOM.findDOMNode(this);
|
||||
hljs.highlightElement(current);
|
||||
},
|
||||
render: function() {
|
||||
render: function() {
|
||||
return (
|
||||
<pre className="go"><code >{ this.props.code }</code></pre>
|
||||
);
|
||||
@@ -407,14 +407,14 @@
|
||||
<div className="column is-one-quarter">
|
||||
<Navigation
|
||||
data={ this.props.data }
|
||||
severity={ this.state.severity }
|
||||
severity={ this.state.severity }
|
||||
confidence={ this.state.confidence }
|
||||
issueType={ this.state.issueType }
|
||||
allSeverities={ this.state.allSeverities }
|
||||
allSeverities={ this.state.allSeverities }
|
||||
allConfidences={ this.state.allConfidences }
|
||||
allIssueTypes={ this.state.allIssueTypes }
|
||||
onSeverity={ this.handleSeverity }
|
||||
onConfidence={ this.handleConfidence }
|
||||
onSeverity={ this.handleSeverity }
|
||||
onConfidence={ this.handleConfidence }
|
||||
onIssueType={ this.handleIssueType }
|
||||
/>
|
||||
</div>
|
||||
@@ -437,4 +437,4 @@
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@@ -80,20 +80,23 @@ func NewTool(driver *ToolComponent) *Tool {
|
||||
|
||||
// NewResult instantiate a Result
|
||||
func NewResult(ruleID string, ruleIndex int, level Level, message string, suppressions []*Suppression, autofix string) *Result {
|
||||
return &Result{
|
||||
result := &Result{
|
||||
RuleID: ruleID,
|
||||
RuleIndex: ruleIndex,
|
||||
Level: level,
|
||||
Message: NewMessage(message),
|
||||
Suppressions: suppressions,
|
||||
Fixes: []*Fix{
|
||||
}
|
||||
if len(autofix) > 0 {
|
||||
result.Fixes = []*Fix{
|
||||
{
|
||||
Description: &Message{
|
||||
Markdown: autofix,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// NewMessage instantiate a Message
|
||||
|
||||
@@ -18,5 +18,5 @@ const (
|
||||
// Version : SARIF Schema version
|
||||
Version = "2.1.0"
|
||||
// Schema : SARIF Schema URL
|
||||
Schema = "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.json"
|
||||
Schema = "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/main/sarif-2.1/schema/sarif-schema-2.1.0.json"
|
||||
)
|
||||
|
||||
@@ -105,7 +105,7 @@ func NewNoErrorCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
ID: id,
|
||||
Severity: issue.Low,
|
||||
Confidence: issue.High,
|
||||
What: "Errors unhandled.",
|
||||
What: "Errors unhandled",
|
||||
},
|
||||
whitelist: whitelist,
|
||||
}, []ast.Node{(*ast.AssignStmt)(nil), (*ast.ExprStmt)(nil)}
|
||||
|
||||
@@ -157,7 +157,7 @@ func (r *osCreatePermissions) Match(n ast.Node, c *gosec.Context) (*issue.Issue,
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// NewOsCreatePerms reates a rule to detect file creation with a more permissive than configured
|
||||
// NewOsCreatePerms creates a rule to detect file creation with a more permissive than configured
|
||||
// permission mask.
|
||||
func NewOsCreatePerms(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
mode := getConfiguredMode(conf, id, 0o666)
|
||||
|
||||
@@ -47,7 +47,7 @@ func doGetIdentExpr(expr ast.Expr, hasSelector bool) (*ast.Ident, bool) {
|
||||
}
|
||||
|
||||
func (r *implicitAliasing) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) {
|
||||
// This rule does not apply for Go 1.22, see https://tip.golang.org/doc/go1.22#language.
|
||||
// This rule does not apply for Go 1.22, see https://go.dev/doc/go1.22#language.
|
||||
major, minor, _ := gosec.GoVersion()
|
||||
if major >= 1 && minor >= 22 {
|
||||
return nil, nil
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
package rules
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
|
||||
"github.com/securego/gosec/v2"
|
||||
"github.com/securego/gosec/v2/issue"
|
||||
)
|
||||
|
||||
type usingOldMathBig struct {
|
||||
issue.MetaData
|
||||
calls gosec.CallList
|
||||
}
|
||||
|
||||
func (r *usingOldMathBig) ID() string {
|
||||
return r.MetaData.ID
|
||||
}
|
||||
|
||||
func (r *usingOldMathBig) Match(node ast.Node, ctx *gosec.Context) (gi *issue.Issue, err error) {
|
||||
if callExpr := r.calls.ContainsPkgCallExpr(node, ctx, false); callExpr == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
confidence := issue.Low
|
||||
major, minor, build := gosec.GoVersion()
|
||||
if major == 1 && (minor == 16 && build < 14 || minor == 17 && build < 7) {
|
||||
confidence = issue.Medium
|
||||
}
|
||||
|
||||
return ctx.NewIssue(node, r.ID(), r.What, r.Severity, confidence), nil
|
||||
}
|
||||
|
||||
// NewUsingOldMathBig rule detects the use of Rat.SetString from math/big.
|
||||
func NewUsingOldMathBig(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
|
||||
calls := gosec.NewCallList()
|
||||
calls.Add("math/big.Rat", "SetString")
|
||||
return &usingOldMathBig{
|
||||
calls: calls,
|
||||
MetaData: issue.MetaData{
|
||||
ID: id,
|
||||
What: "Potential uncontrolled memory consumption in Rat.SetString (CVE-2022-23772)",
|
||||
Severity: issue.High,
|
||||
},
|
||||
}, []ast.Node{(*ast.CallExpr)(nil)}
|
||||
}
|
||||
@@ -75,7 +75,6 @@ func Generate(trackSuppressions bool, filters ...RuleFilter) RuleList {
|
||||
{"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
|
||||
|
||||
@@ -103,10 +103,6 @@ var _ = Describe("gosec rules", 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)
|
||||
})
|
||||
|
||||
@@ -32,6 +32,12 @@ type sqlStatement struct {
|
||||
}
|
||||
|
||||
var sqlCallIdents = map[string]map[string]int{
|
||||
"*database/sql.Conn": {
|
||||
"ExecContext": 1,
|
||||
"QueryContext": 1,
|
||||
"QueryRowContext": 1,
|
||||
"PrepareContext": 1,
|
||||
},
|
||||
"*database/sql.DB": {
|
||||
"Exec": 0,
|
||||
"ExecContext": 1,
|
||||
|
||||
@@ -321,6 +321,50 @@ func main() {
|
||||
fmt.Printf("%s\n", ConfigLearnerTokenAuth)
|
||||
}
|
||||
|
||||
`}, 0, gosec.NewConfig()},
|
||||
{[]string{`
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
//gosec:disable G101
|
||||
const (
|
||||
ConfigLearnerTokenAuth string = "learner_auth_token_config" //gosec:disable G101
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Printf("%s\n", ConfigLearnerTokenAuth)
|
||||
}
|
||||
|
||||
`}, 0, gosec.NewConfig()},
|
||||
{[]string{`
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
//gosec:disable G101
|
||||
const (
|
||||
ConfigLearnerTokenAuth string = "learner_auth_token_config"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Printf("%s\n", ConfigLearnerTokenAuth)
|
||||
}
|
||||
|
||||
`}, 0, gosec.NewConfig()},
|
||||
{[]string{`
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
const (
|
||||
ConfigLearnerTokenAuth string = "learner_auth_token_config" //gosec:disable G101
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Printf("%s\n", ConfigLearnerTokenAuth)
|
||||
}
|
||||
|
||||
`}, 0, gosec.NewConfig()},
|
||||
}
|
||||
|
||||
|
||||
@@ -98,6 +98,38 @@ func New(listenAddr string) *Server {
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Print("test")
|
||||
}
|
||||
`}, 0, gosec.NewConfig()},
|
||||
{[]string{`
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
hs *http.Server
|
||||
mux *http.ServeMux
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
func New(listenAddr string) *Server {
|
||||
mux := http.NewServeMux()
|
||||
|
||||
return &Server{
|
||||
hs: &http.Server{ //gosec:disable G112 - Not publicly exposed
|
||||
Addr: listenAddr,
|
||||
Handler: mux,
|
||||
},
|
||||
mux: mux,
|
||||
mu: sync.Mutex{},
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Print("test")
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
package testutils
|
||||
|
||||
import "github.com/securego/gosec/v2"
|
||||
|
||||
// SampleCodeG113 - Usage of Rat.SetString in math/big with an overflow
|
||||
var SampleCodeG113 = []CodeSample{
|
||||
{[]string{`
|
||||
package main
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func main() {
|
||||
r := big.Rat{}
|
||||
r.SetString("13e-9223372036854775808")
|
||||
|
||||
fmt.Println(r)
|
||||
}
|
||||
`}, 1, gosec.NewConfig()},
|
||||
}
|
||||
@@ -426,6 +426,40 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var a string = "13"
|
||||
b, _ := strconv.ParseUint(a, 10, 16)
|
||||
c := int(b)
|
||||
fmt.Printf("%d\n", c)
|
||||
}
|
||||
`,
|
||||
}, 0, gosec.NewConfig()},
|
||||
{[]string{
|
||||
`
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var a string = "13"
|
||||
b, _ := strconv.ParseUint(a, 10, 31)
|
||||
c := int32(b)
|
||||
fmt.Printf("%d\n", c)
|
||||
}
|
||||
`,
|
||||
}, 0, gosec.NewConfig()},
|
||||
{[]string{
|
||||
`
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var a string = "13"
|
||||
b, _ := strconv.ParseInt(a, 10, 8)
|
||||
@@ -716,4 +750,116 @@ func main() {
|
||||
}
|
||||
`,
|
||||
}, 0, gosec.NewConfig()},
|
||||
{[]string{
|
||||
`
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
type CustomStruct struct {
|
||||
Value int
|
||||
}
|
||||
|
||||
func main() {
|
||||
results := CustomStruct{Value: 0}
|
||||
if results.Value < math.MinInt32 || results.Value > math.MaxInt32 {
|
||||
panic("value out of range for int32")
|
||||
}
|
||||
convertedValue := int32(results.Value)
|
||||
|
||||
fmt.Println(convertedValue)
|
||||
}
|
||||
`,
|
||||
}, 0, gosec.NewConfig()},
|
||||
{[]string{
|
||||
`
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
type CustomStruct struct {
|
||||
Value int
|
||||
}
|
||||
|
||||
func main() {
|
||||
results := CustomStruct{Value: 0}
|
||||
if results.Value >= math.MinInt32 && results.Value <= math.MaxInt32 {
|
||||
convertedValue := int32(results.Value)
|
||||
fmt.Println(convertedValue)
|
||||
}
|
||||
panic("value out of range for int32")
|
||||
}
|
||||
`,
|
||||
}, 0, gosec.NewConfig()},
|
||||
{[]string{
|
||||
`
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
type CustomStruct struct {
|
||||
Value int
|
||||
}
|
||||
|
||||
func main() {
|
||||
results := CustomStruct{Value: 0}
|
||||
if results.Value < math.MinInt32 || results.Value > math.MaxInt32 {
|
||||
panic("value out of range for int32")
|
||||
}
|
||||
// checked value is decremented by 1 before conversion which is unsafe
|
||||
convertedValue := int32(results.Value-1)
|
||||
|
||||
fmt.Println(convertedValue)
|
||||
}
|
||||
`,
|
||||
}, 1, gosec.NewConfig()},
|
||||
{[]string{
|
||||
`
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
func main() {
|
||||
a := rand.Int63()
|
||||
if a < math.MinInt32 || a > math.MaxInt32 {
|
||||
panic("out of range")
|
||||
}
|
||||
// checked value is incremented by 1 before conversion which is unsafe
|
||||
b := int32(a+1)
|
||||
fmt.Printf("%d\n", b)
|
||||
}
|
||||
`,
|
||||
}, 1, gosec.NewConfig()},
|
||||
{[]string{
|
||||
`
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
a, err := strconv.ParseUint("100", 10, 16)
|
||||
if err != nil {
|
||||
panic("parse error")
|
||||
}
|
||||
b := uint16(a)
|
||||
fmt.Printf("%d\n", b)
|
||||
}
|
||||
`,
|
||||
}, 0, gosec.NewConfig()},
|
||||
}
|
||||
|
||||
@@ -103,6 +103,36 @@ func main(){
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
`}, 1, gosec.NewConfig()},
|
||||
{[]string{`
|
||||
// Format string without proper quoting with connection
|
||||
package main
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main(){
|
||||
db, err := sql.Open("sqlite3", ":memory:")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
conn, err := db.Conn(context.Background())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
q := fmt.Sprintf("select * from foo where name = '%s'", os.Args[1])
|
||||
rows, err := conn.QueryContext(context.Background(), q)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer rows.Close()
|
||||
if err := conn.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
`}, 1, gosec.NewConfig()},
|
||||
{[]string{`
|
||||
// Format string false positive, safe string spec.
|
||||
|
||||
@@ -119,6 +119,35 @@ func main(){
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
`}, 1, gosec.NewConfig()},
|
||||
{[]string{`
|
||||
// DB connection check
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main(){
|
||||
db, err := sql.Open("sqlite3", ":memory:")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
conn, err := db.Conn(context.Background())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
rows, err := conn.QueryContext(context.Background(), "select * from foo where name = " + os.Args[1])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer rows.Close()
|
||||
if err := conn.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
`}, 1, gosec.NewConfig()},
|
||||
{[]string{`
|
||||
// multiple string concatenation
|
||||
|
||||
@@ -20,7 +20,7 @@ func main() {
|
||||
}
|
||||
|
||||
client := &http.Client{Transport: tr}
|
||||
_, err := client.Get("https://golang.org/")
|
||||
_, err := client.Get("https://go.dev/")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
@@ -54,7 +54,7 @@ func main() {
|
||||
TLSClientConfig: &tls.Config{MinVersion: 0},
|
||||
}
|
||||
client := &http.Client{Transport: tr}
|
||||
_, err := client.Get("https://golang.org/")
|
||||
_, err := client.Get("https://go.dev/")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
@@ -164,7 +164,7 @@ func main() {
|
||||
TLSClientConfig: &tls.Config{MinVersion: theValue},
|
||||
}
|
||||
client := &http.Client{Transport: tr}
|
||||
_, err := client.Get("https://golang.org/")
|
||||
_, err := client.Get("https://go.dev/")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
@@ -185,7 +185,7 @@ func main() {
|
||||
TLSClientConfig: &tls.Config{MaxVersion: 0},
|
||||
}
|
||||
client := &http.Client{Transport: tr}
|
||||
_, err := client.Get("https://golang.org/")
|
||||
_, err := client.Get("https://go.dev/")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
@@ -211,7 +211,7 @@ func main() {
|
||||
},
|
||||
}
|
||||
client := &http.Client{Transport: tr}
|
||||
_, err := client.Get("https://golang.org/")
|
||||
_, err := client.Get("https://go.dev/")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
@@ -230,12 +230,12 @@ import (
|
||||
func main() {
|
||||
tr := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
MaxVersion: 0,
|
||||
MaxVersion: 0,
|
||||
MinVersion: tls.VersionTLS13,
|
||||
},
|
||||
}
|
||||
client := &http.Client{Transport: tr}
|
||||
_, err := client.Get("https://golang.org/")
|
||||
_, err := client.Get("https://go.dev/")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ func main() {
|
||||
cipherText, _ = aesGCM.Open(nil, []byte("ILoveMyNonce"), cipherText, nil)
|
||||
fmt.Println(string(cipherText))
|
||||
}
|
||||
`}, 2, gosec.NewConfig()},
|
||||
`}, 1, gosec.NewConfig()},
|
||||
|
||||
{[]string{`package main
|
||||
|
||||
@@ -193,7 +193,7 @@ func main() {
|
||||
cipherText, _ = aesGCM.Open(nil, []byte{}, cipherText, nil)
|
||||
fmt.Println(string(cipherText))
|
||||
}
|
||||
`}, 2, gosec.NewConfig()},
|
||||
`}, 1, gosec.NewConfig()},
|
||||
|
||||
{[]string{`package main
|
||||
|
||||
@@ -214,7 +214,7 @@ func main() {
|
||||
cipherText, _ = aesGCM.Open(nil, []byte{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, cipherText, nil)
|
||||
fmt.Println(string(cipherText))
|
||||
}
|
||||
`}, 2, gosec.NewConfig()},
|
||||
`}, 1, gosec.NewConfig()},
|
||||
|
||||
{[]string{`package main
|
||||
|
||||
@@ -248,7 +248,7 @@ func main() {
|
||||
|
||||
fmt.Println(string(cipherText))
|
||||
}
|
||||
`}, 2, gosec.NewConfig()},
|
||||
`}, 1, gosec.NewConfig()},
|
||||
|
||||
{[]string{`package main
|
||||
|
||||
@@ -281,7 +281,7 @@ func main() {
|
||||
}(), cipherText, nil)
|
||||
fmt.Println(string(cipherText))
|
||||
}
|
||||
`}, 2, gosec.NewConfig()},
|
||||
`}, 1, gosec.NewConfig()},
|
||||
|
||||
{[]string{`package main
|
||||
|
||||
@@ -301,7 +301,7 @@ func main() {
|
||||
fmt.Println(string(cipheredText))
|
||||
|
||||
}
|
||||
`}, 2, gosec.NewConfig()},
|
||||
`}, 1, gosec.NewConfig()},
|
||||
|
||||
{[]string{`package main
|
||||
|
||||
@@ -321,7 +321,7 @@ func main() {
|
||||
fmt.Println(string(cipheredText))
|
||||
|
||||
}
|
||||
`}, 2, gosec.NewConfig()},
|
||||
`}, 1, gosec.NewConfig()},
|
||||
|
||||
{[]string{`package main
|
||||
|
||||
@@ -342,7 +342,7 @@ func main() {
|
||||
aesCFB.XORKeyStream(output, output)
|
||||
fmt.Println(string(output))
|
||||
|
||||
}`}, 2, gosec.NewConfig()},
|
||||
}`}, 1, gosec.NewConfig()},
|
||||
|
||||
{[]string{`package main
|
||||
|
||||
@@ -363,7 +363,7 @@ func main() {
|
||||
aesCFB.XORKeyStream(output, output)
|
||||
fmt.Println(string(output))
|
||||
|
||||
}`}, 2, gosec.NewConfig()},
|
||||
}`}, 1, gosec.NewConfig()},
|
||||
|
||||
{[]string{`package main
|
||||
|
||||
@@ -386,7 +386,7 @@ func main() {
|
||||
aesCBC.CryptBlocks(output, output)
|
||||
fmt.Println(string(output))
|
||||
|
||||
}`}, 2, gosec.NewConfig()},
|
||||
}`}, 1, gosec.NewConfig()},
|
||||
|
||||
{[]string{`package main
|
||||
|
||||
@@ -410,7 +410,7 @@ func main() {
|
||||
fmt.Println(string(output))
|
||||
|
||||
}
|
||||
`}, 2, gosec.NewConfig()},
|
||||
`}, 1, gosec.NewConfig()},
|
||||
|
||||
{[]string{`package main
|
||||
|
||||
|
||||
@@ -7,6 +7,5 @@ package tools
|
||||
import (
|
||||
_ "github.com/lib/pq"
|
||||
_ "golang.org/x/crypto/ssh"
|
||||
_ "golang.org/x/lint/golint"
|
||||
_ "golang.org/x/text"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user