Compare commits

..

38 Commits

Author SHA1 Message Date
Cosmin Cojocar
7a92cb5212 Fix crash in hardcoded_nonce analyzer
Change-Id: If5ed3709d6e1ddced1be555477dd0f5451aab901
Signed-off-by: Cosmin Cojocar <ccojocar@google.com>
2025-07-21 15:11:17 +00:00
Cosmin Cojocar
6ea6b35e61 Update go action to use release v2.22.6
Change-Id: I9081035b07d8b254034468af77d65d48c7c06ecb
Signed-off-by: Cosmin Cojocar <ccojocar@google.com>
2025-07-21 10:49:17 +00:00
Cosmin Cojocar
bc3f2145b5 Update go version to 1.24.5 and 1.23.11 in the CI
Change-Id: I56c3576fbda7cc2633dac335c29b2494985978e9
Signed-off-by: Cosmin Cojocar <ccojocar@google.com>
2025-07-21 09:38:01 +00:00
renovate[bot]
925741b7ef chore(deps): update module google.golang.org/api to v0.242.0 2025-07-21 08:06:50 +00:00
renovate[bot]
59ae7e9e27 chore(deps): update all dependencies 2025-07-14 08:59:55 +00:00
renovate[bot]
e7abd9e348 chore(deps): update all dependencies 2025-07-07 10:04:42 +02:00
renovate[bot]
35e7bc1a94 chore(deps): update all dependencies 2025-06-30 10:33:36 +02:00
renovate[bot]
2d1ed95a0b chore(deps): update all dependencies 2025-06-23 11:35:00 +02:00
Oleksandr Redko
4a8cb4609f Do not allow dashes in file names 2025-06-16 14:34:38 +02:00
Cosmin Cojocar
bcc8afbe30 Update gosec to version 2.22.5 in Github action
Change-Id: Ide774b7157678f54e17bd7decad22d0712ff1b40
Signed-off-by: Cosmin Cojocar <ccojocar@google.com>
2025-06-16 12:57:45 +02:00
Cosmin Cojocar
d2d3ae66bd Switch back go.mod to minimum 1.23.0
Change-Id: Ic3f843d866a21a6595e1dc9c97416f2a22172299
Signed-off-by: Cosmin Cojocar <ccojocar@google.com>
2025-06-16 11:50:02 +02:00
Cosmin Cojocar
1e7ed06b15 Update dependencies
Change-Id: Ifccf358fa941a51f6b9e817311dc4a49ee9afb6f
Signed-off-by: Cosmin Cojocar <ccojocar@google.com>
2025-06-16 11:50:02 +02:00
Cosmin Cojocar
1bef91a07f Update go version 1.24.4 and 1.23.10 in CI
Change-Id: I3d7d82da3385d231873a8901132a8a025beb01fc
Signed-off-by: Cosmin Cojocar <ccojocar@google.com>
2025-06-16 11:21:59 +02:00
renovate[bot]
621702f13a chore(deps): update all dependencies 2025-06-10 10:39:08 +02:00
Ilia Mirkin
017d1d655c G201/G202: add checks for injection into sql.Conn methods
We check sql.DB and sql.Tx, but sql.Conn appears to have been missed. It
carries the same issues as DB/Tx in terms of injection.
2025-06-03 16:22:56 +02:00
renovate[bot]
67f63d4781 chore(deps): update module google.golang.org/api to v0.235.0 2025-06-02 10:04:14 +02:00
renovate[bot]
b4eabb1b18 chore(deps): update module google.golang.org/api to v0.234.0 2025-05-26 16:03:16 +03:00
renovate[bot]
52a80ff4bd chore(deps): update module google.golang.org/api to v0.233.0 2025-05-20 10:08:10 +02:00
renovate[bot]
e2a95069d9 chore(deps): update module google.golang.org/api to v0.232.0 2025-05-12 09:48:04 +02:00
Cosmin Cojocar
6decf96c3d Update to go version 1.24.3 and 1.23.9
Change-Id: I51a700de77a580647088f6ac40a725bac5c4e233
Signed-off-by: Cosmin Cojocar <ccojocar@google.com>
2025-05-08 11:19:37 +02:00
codeshaine
d522338364 update: updated the build command to include version metadata 2025-05-08 11:00:06 +02:00
renovate[bot]
270b5ce868 chore(deps): update all dependencies 2025-05-06 09:44:05 +02:00
Cosmin Cojocar
60279264be Update the AI provider API key value when provided as an argument
Change-Id: I9658ff0bc37941d6767144b7df49470452f8f591
Signed-off-by: Cosmin Cojocar <ccojocar@google.com>
2025-04-28 12:45:12 +02:00
renovate[bot]
65d2d9f011 chore(deps): update module google.golang.org/api to v0.230.0 2025-04-28 12:27:29 +02:00
renovate[bot]
dc1c38b861 chore(deps): update module google.golang.org/api to v0.229.0 2025-04-22 10:17:22 +02:00
renovate[bot]
55dbf5ad81 chore(deps): update all dependencies 2025-04-14 10:44:53 +02:00
Cosmin Cojocar
2aaa9c41d6 Comment the reason why the file can be nil when an issue is created
Change-Id: I85295a33f540255f4904e663144b959877d0c38a
Signed-off-by: Cosmin Cojocar <ccojocar@google.com>
2025-04-08 18:19:28 +02:00
Cosmin Cojocar
700e9a9d18 Handle nil file when creating a new issue
This can occur when there is a compilation issue into the code.

Change-Id: I8b028d454d417c33edc687dcffc68c92d18091d6
Signed-off-by: Cosmin Cojocar <ccojocar@google.com>
2025-04-08 18:19:28 +02:00
renovate[bot]
d514c42671 chore(deps): update all dependencies (#1333)
* chore(deps): update all dependencies

* Fix all lint warnings after upgrading golangci-lint action

Change-Id: I7b4162307ae0d6a1c9ec00b7127469c64ed93f64
Signed-off-by: Cosmin Cojocar <ccojocar@google.com>

* Remove the backup file

Signed-off-by: Cosmin Cojocar <ccojocar@google.com>

---------

Signed-off-by: Cosmin Cojocar <ccojocar@google.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Cosmin Cojocar <ccojocar@google.com>
2025-04-07 13:12:14 +02:00
Jenna Schwartz
1d458c50e1 Update version in 'action.yml' to 2.22.3 (anticipating next version (#1332) 2025-04-04 10:36:07 +02:00
Cosmin Cojocar
955a68d0d1 Update go version to 1.24.2 and 1.23.8 (#1331) 2025-04-03 16:53:13 +02:00
Brandon Annin
1336dc6820 remove G113. It only affects old/unsupported versions of Go (#1328)
* don't warn on G113 (big.Rat SetString) if on an unaffected version of Go

Newer versions of go (>=1.16.14, >=1.17.7, 1.18+) are not affected by this. Don't warn at all on those newer versions. See https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-23772

* alert on all known versions

Co-authored-by: ccoVeille <3875889+ccoVeille@users.noreply.github.com>

* remove G113 CVE-2022-23772 which only affects old/unsupport Go versions

* Retire rule

* gofmt

---------

Co-authored-by: ccoVeille <3875889+ccoVeille@users.noreply.github.com>
2025-04-03 16:44:20 +02:00
renovate[bot]
5fd2a37044 chore(deps): update all dependencies (#1325)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-31 15:57:38 +02:00
Govind Malviya
39e4477788 Add SSOJet (#1320) 2025-03-19 10:24:30 +01:00
renovate[bot]
6141d100df chore(deps): update all dependencies (#1319)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-19 09:17:29 +01:00
Cosmin Cojocar
9452efe4ad Update the integrity sha for babel dependency in html report (#1316)
Signed-off-by: Cosmin Cojocar <ccojocar@google.com>
2025-03-10 11:07:47 +01:00
frozenbonito
57ec63392c Add support for //gosec:disable directive (#1314) 2025-03-10 10:09:27 +01:00
renovate[bot]
e5fee17863 chore(deps): update all dependencies (#1315)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-10 09:58:31 +01:00
32 changed files with 1075 additions and 306 deletions

View File

@@ -10,7 +10,7 @@ jobs:
test:
strategy:
matrix:
version: [{go: '1.23.7', golangci: 'latest'}, {go: '1.24.1', 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.24.1'
go-version: '1.24.5'
- name: Checkout Source
uses: actions/checkout@v4
- uses: actions/cache@v4

View File

@@ -17,11 +17,11 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.24.1'
go-version: '1.24.5'
- name: Install Cosign
uses: sigstore/cosign-installer@v3
with:
cosign-release: 'v2.4.3'
cosign-release: 'v2.5.0'
- name: Store Cosign private key in a file
run: 'echo "$COSIGN_KEY" > /tmp/cosign.key'
shell: bash

View File

@@ -1,3 +1,4 @@
version: "2"
linters:
enable:
- asciicheck
@@ -5,50 +6,60 @@ linters:
- copyloopvar
- dogsled
- durationcheck
- errcheck
- errorlint
- gci
- ginkgolinter
- gochecknoinits
- gofmt
- gofumpt
- goimports
- gosec
- gosimple
- govet
- importas
- ineffassign
- misspell
- nakedret
- nolintlint
- revive
- staticcheck
- testifylint
- typecheck
- unconvert
- unparam
- unused
- wastedassign
linters-settings:
gci:
sections:
- standard
- default
- prefix(github.com/securego)
staticcheck:
checks:
- all
- '-SA1019'
testifylint:
enable-all: true
revive:
rules:
- name: dot-imports
disabled: true
- name: redefines-builtin-id
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$

View File

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

View File

@@ -138,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
@@ -172,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
@@ -304,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:

View File

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

View File

@@ -10,7 +10,7 @@ inputs:
runs:
using: 'docker'
image: 'docker://securego/gosec:2.22.1'
image: 'docker://securego/gosec:2.22.6'
args:
- ${{ inputs.args }}

View File

@@ -57,6 +57,8 @@ const externalSuppressionJustification = "Globally suppressed."
const aliasOfAllRules = "*"
var directiveRegexp = regexp.MustCompile("^//gosec:disable(?: (.+))?$")
type ignore struct {
start int
end int
@@ -582,53 +584,77 @@ func (gosec *Analyzer) ignore(n ast.Node) map[string]issue.SuppressionInfo {
}
for _, group := range groups {
comment := strings.TrimSpace(group.Text())
foundDefaultTag := strings.HasPrefix(comment, noSecDefaultTag) || regexp.MustCompile("\n *"+noSecDefaultTag).MatchString(comment)
foundAlternativeTag := strings.HasPrefix(comment, noSecAlternativeTag) || regexp.MustCompile("\n *"+noSecAlternativeTag).MatchString(comment)
if foundDefaultTag || foundAlternativeTag {
gosec.stats.NumNosec++
// Discard what's in front of the nosec tag.
if foundDefaultTag {
comment = strings.SplitN(comment, noSecDefaultTag, 2)[1]
} else {
comment = strings.SplitN(comment, noSecAlternativeTag, 2)[1]
}
// Extract the directive and the justification.
justification := ""
commentParts := regexp.MustCompile(`-{2,}`).Split(comment, 2)
directive := commentParts[0]
if len(commentParts) > 1 {
justification = strings.TrimSpace(strings.TrimRight(commentParts[1], "\n"))
}
// Pull out the specific rules that are listed to be ignored.
re := regexp.MustCompile(`(G\d{3})`)
matches := re.FindAllStringSubmatch(directive, -1)
suppression := issue.SuppressionInfo{
Kind: "inSource",
Justification: justification,
}
// Find the rule IDs to ignore.
ignores := make(map[string]issue.SuppressionInfo)
for _, v := range matches {
ignores[v[1]] = suppression
}
// If no specific rules were given, ignore everything.
if len(matches) == 0 {
ignores[aliasOfAllRules] = suppression
}
return ignores
found, args := findNoSecDirective(group, noSecDefaultTag, noSecAlternativeTag)
if !found {
continue
}
gosec.stats.NumNosec++
// 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 {

View File

@@ -23,11 +23,12 @@ import (
. "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() {
@@ -230,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]
@@ -247,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]
@@ -264,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]
@@ -333,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]
@@ -351,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]
@@ -369,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]
@@ -415,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]
@@ -432,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]
@@ -449,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]
@@ -466,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]
@@ -485,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]
@@ -504,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]
@@ -523,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]
@@ -573,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]
@@ -596,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]
@@ -619,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]
@@ -714,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]
@@ -731,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]
@@ -748,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]
@@ -867,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]
@@ -884,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]
@@ -901,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]
@@ -1365,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]
@@ -1385,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]
@@ -1405,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]
@@ -1425,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]
@@ -1445,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]
@@ -1465,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]
@@ -1618,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
@@ -1632,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())

View File

@@ -197,12 +197,20 @@ func isFuncContainsCryptoRand(funcCall *ssa.Function) (bool, error) {
}
func addToVarsMap(value ssa.Value, mapToAddTo map[string]*ssa.Value) {
key := value.Name() + value.Type().String() + value.String() + value.Parent().String()
var parent string
if value.Parent() != nil {
parent = value.Parent().String()
}
key := value.Name() + value.Type().String() + value.String() + parent
mapToAddTo[key] = &value
}
func isContainedInMap(value ssa.Value, mapToCheck map[string]*ssa.Value) bool {
key := value.Name() + value.Type().String() + value.String() + value.Parent().String()
var parent string
if value.Parent() != nil {
parent = value.Parent().String()
}
key := value.Name() + value.Type().String() + value.String() + parent
_, contained := mapToCheck[key]
return contained
}

View File

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

View File

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

View File

@@ -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,10 +154,10 @@ 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.")
@@ -504,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)
}

View File

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

View File

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

69
go.mod
View File

@@ -1,58 +1,59 @@
module github.com/securego/gosec/v2
require (
github.com/ccojocar/zxcvbn-go v1.0.2
github.com/google/generative-ai-go v0.19.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.22.2
github.com/onsi/gomega v1.36.2
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.35.0
golang.org/x/text v0.22.0
golang.org/x/tools v0.30.0
google.golang.org/api v0.223.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.116.0 // indirect
cloud.google.com/go/ai v0.8.0 // indirect
cloud.google.com/go/auth v0.15.0 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.7 // indirect
cloud.google.com/go/compute/metadata v0.6.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/google/go-cmp v0.7.0 // indirect
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // 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.4 // indirect
github.com/googleapis/gax-go/v2 v2.14.1 // 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
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.59.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 // indirect
go.opentelemetry.io/otel v1.34.0 // indirect
go.opentelemetry.io/otel/metric v1.34.0 // indirect
go.opentelemetry.io/otel/trace v1.34.0 // indirect
golang.org/x/mod v0.23.0 // indirect
golang.org/x/net v0.35.0 // indirect
golang.org/x/oauth2 v0.26.0 // indirect
golang.org/x/sync v0.11.0 // indirect
golang.org/x/sys v0.30.0 // indirect
golang.org/x/time v0.10.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250219182151-9fdb1cabc7b2 // indirect
google.golang.org/grpc v1.70.0 // indirect
google.golang.org/protobuf v1.36.5 // 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.23.0

156
go.sum
View File

@@ -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.116.0 h1:B3fRrSDkLRt5qSHWe40ERJvhvnQwdZiHu0bJOpldweE=
cloud.google.com/go v0.116.0/go.mod h1:cEPSRWPzZEswwdr9BxE6ChEn01dWlTaF05LiC2Xs70U=
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.15.0 h1:Ly0u4aA5vG/fsSsxu98qCQBemXtAtJf+95z9HK+cxps=
cloud.google.com/go/auth v0.15.0/go.mod h1:WJDGqZ1o9E9wKIL+IwStfyn/+s59zl4Bi+1KQNVXLZ8=
cloud.google.com/go/auth/oauth2adapt v0.2.7 h1:/Lc7xODdqcEw8IrZ9SvwnlLX6j9FHQM74z6cBk9Rw6M=
cloud.google.com/go/auth/oauth2adapt v0.2.7/go.mod h1:NTbTTzfvPl1Y3V1nPpOgl2w6d/FjO7NNUQaWSox6ZMc=
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.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I=
cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg=
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=
@@ -160,8 +160,8 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z
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.19.0 h1:R71szggh8wHMCUlEMsW2A/3T+5LdEIkiaHSYgSpUgdg=
github.com/google/generative-ai-go v0.19.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=
@@ -179,8 +179,8 @@ 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-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg=
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/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.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
@@ -190,12 +190,12 @@ github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/google/uuid v1.1.1/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.4 h1:XYIDZApgAnrN1c855gTgghdIA6Stxb52D5RnLI1SLyw=
github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA=
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.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q=
github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA=
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=
@@ -290,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.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU=
github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk=
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.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY=
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=
@@ -304,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=
@@ -361,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=
@@ -381,23 +383,25 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
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.59.0 h1:rgMkmiGfix9vFJDcDi1PK8WEQP4FLQwLDfhp5ZLpFeE=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0/go.mod h1:ijPqXp5P6IRRByFVVg9DY8P5HkxkHE5ARIa+86aXPf4=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I=
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
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=
@@ -413,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.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
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=
@@ -426,6 +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-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=
@@ -446,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.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM=
golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
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=
@@ -480,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.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
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.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE=
golang.org/x/oauth2 v0.26.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=
@@ -498,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.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
golang.org/x/sync v0.11.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=
@@ -540,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.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.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.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
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.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
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.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4=
golang.org/x/time v0.10.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=
@@ -605,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.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=
golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY=
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=
@@ -626,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.223.0 h1:JUTaWEriXmEy5AhvdMgksGGPEFsYfUKaPEYXd4c3Wvc=
google.golang.org/api v0.223.0/go.mod h1:C+RS7Z+dDwds2b+zoAk5hN/eSfsiCn0UDrYof/M4d2M=
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=
@@ -666,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-20241209162323-e6fa225c2576 h1:CkkIfIt50+lT6NHAVoRYEyAvQGFM7xEwXUUywFvEb3Q=
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250219182151-9fdb1cabc7b2 h1:DMTIbak9GhdaSxEjvVzAeNZvyc03I61duqNbnm3SU0M=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250219182151-9fdb1cabc7b2/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
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=
@@ -684,8 +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.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
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=
@@ -696,8 +704,8 @@ 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.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
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=

View File

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

View File

@@ -65,7 +65,6 @@ var ruleToCWE = map[string]string{
"G110": "409",
"G111": "22",
"G112": "400",
"G113": "190",
"G114": "676",
"G115": "190",
"G201": "89",

View File

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

View File

@@ -4,13 +4,13 @@
<meta charset="utf-8">
<title>Golang Security Checker</title>
<link rel="shortcut icon" type="image/png" href="https://securego.io/img/favicon.png">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/1.0.3/css/bulma.min.css" integrity="sha512-4EnjWdm80dyWrJ7rh/tlhNt6fJL52dSDSHNEqfdVmBLpJLPrRYnFa+Kn4ZZL+FRkDL5/7lAXuHylzJkpzkSM2A==" crossorigin="anonymous"/>
<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.26.4/babel.min.js" integrity="sha512-hX7KzoYtNHhNJsz8TAHyddcegokOwhmYiFWCDHqFkcoNVsYwCziO+NISSRlNKpfOYaqyQxm2+MTCJqSaHssJTA==" 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>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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