diff options
| author | Taras Madan <tarasmadan@google.com> | 2023-07-20 10:46:22 +0200 |
|---|---|---|
| committer | Taras Madan <tarasmadan@google.com> | 2023-07-20 12:32:54 +0000 |
| commit | 1b601bfed3244691624357968d5d018b50bffc5a (patch) | |
| tree | 2b7ff934678209301df15f54f56e942284837108 /vendor/github.com/securego | |
| parent | 75ccff38aa5f5663fd1280a4a78cc0e34212e4db (diff) | |
go.mod: update golangci-lint to 1.53.3
Diffstat (limited to 'vendor/github.com/securego')
45 files changed, 663 insertions, 450 deletions
diff --git a/vendor/github.com/securego/gosec/v2/.golangci.yml b/vendor/github.com/securego/gosec/v2/.golangci.yml index 64e4e4515..b12140a25 100644 --- a/vendor/github.com/securego/gosec/v2/.golangci.yml +++ b/vendor/github.com/securego/gosec/v2/.golangci.yml @@ -1,33 +1,41 @@ linters: enable: - - asciicheck - - bodyclose - - deadcode - - depguard - - dogsled - - durationcheck - - errcheck - - errorlint - - exportloopref - - gci - - gofmt - - gofumpt - - goimports - - gosec - - gosimple - - govet - - importas - - ineffassign - - megacheck - - misspell - - nakedret - - nolintlint - - revive - - staticcheck - - structcheck - - typecheck - - unconvert - - unparam - - unused - - varcheck - - wastedassign + - asciicheck + - bodyclose + - depguard + - dogsled + - durationcheck + - errcheck + - errorlint + - exportloopref + - gci + - ginkgolinter + - gofmt + - gofumpt + - goimports + - gosec + - gosimple + - govet + - importas + - ineffassign + - megacheck + - misspell + - nakedret + - nolintlint + - revive + - staticcheck + - typecheck + - unconvert + - unparam + - unused + - wastedassign + +linters-settings: + gci: + sections: + - standard + - default + - prefix(github.com/securego) + +run: + timeout: 5m diff --git a/vendor/github.com/securego/gosec/v2/.goreleaser.yml b/vendor/github.com/securego/gosec/v2/.goreleaser.yml index 25a81b529..e3c903e7a 100644 --- a/vendor/github.com/securego/gosec/v2/.goreleaser.yml +++ b/vendor/github.com/securego/gosec/v2/.goreleaser.yml @@ -26,6 +26,11 @@ builds: signs: - cmd: cosign stdin: '{{ .Env.COSIGN_PASSWORD}}' - args: ["sign-blob", "--key=/tmp/cosign.key", "--output=${signature}", "${artifact}"] + args: + - "sign-blob" + - "--key=/tmp/cosign.key" + - "--output=${signature}" + - "${artifact}" + - "--yes" artifacts: all diff --git a/vendor/github.com/securego/gosec/v2/Dockerfile b/vendor/github.com/securego/gosec/v2/Dockerfile index b57c981fb..1bf94da7d 100644 --- a/vendor/github.com/securego/gosec/v2/Dockerfile +++ b/vendor/github.com/securego/gosec/v2/Dockerfile @@ -1,11 +1,11 @@ ARG GO_VERSION FROM golang:${GO_VERSION}-alpine AS builder -RUN apk add --no-cache ca-certificates make git curl gcc libc-dev -RUN mkdir -p /build +RUN apk add --no-cache ca-certificates make git curl gcc libc-dev \ + && mkdir -p /build WORKDIR /build COPY . /build/ -RUN go mod download -RUN make build-linux +RUN go mod download \ + && make build-linux FROM golang:${GO_VERSION}-alpine RUN apk add --no-cache ca-certificates bash git gcc libc-dev openssh diff --git a/vendor/github.com/securego/gosec/v2/Makefile b/vendor/github.com/securego/gosec/v2/Makefile index 093c8a99c..09303d11a 100644 --- a/vendor/github.com/securego/gosec/v2/Makefile +++ b/vendor/github.com/securego/gosec/v2/Makefile @@ -87,4 +87,7 @@ image-push: image docker push $(IMAGE_REPO)/$(BIN):$(GIT_TAG) docker push $(IMAGE_REPO)/$(BIN):latest -.PHONY: test build clean release image image-push +tlsconfig: + go generate ./... + +.PHONY: test build clean release image image-push tlsconfig diff --git a/vendor/github.com/securego/gosec/v2/README.md b/vendor/github.com/securego/gosec/v2/README.md index bf7aa0887..71e032d80 100644 --- a/vendor/github.com/securego/gosec/v2/README.md +++ b/vendor/github.com/securego/gosec/v2/README.md @@ -68,7 +68,7 @@ jobs: GO111MODULE: on steps: - name: Checkout Source - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Run Gosec Security Scanner uses: securego/gosec@master with: @@ -98,7 +98,7 @@ jobs: GO111MODULE: on steps: - name: Checkout Source - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Run Gosec Security Scanner uses: securego/gosec@master with: @@ -157,7 +157,6 @@ directory you can supply `./...` as the input argument. - G304: File path provided as taint input - G305: File traversal when extracting zip/tar archive - G306: Poor file permissions used when writing to a new file -- G307: Deferring a method which returns an error - G401: Detect the usage of DES, RC4, MD5 or SHA1 - G402: Look for bad TLS connection settings - G403: Ensure minimum RSA key length of 2048 bits @@ -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) +- 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 @@ -188,7 +188,7 @@ $ gosec -exclude=G303 ./... ### CWE Mapping -Every issue detected by `gosec` is mapped to a [CWE (Common Weakness Enumeration)](http://cwe.mitre.org/data/index.html) which describes in more generic terms the vulnerability. The exact mapping can be found [here](https://github.com/securego/gosec/blob/master/issue.go#L50). +Every issue detected by `gosec` is mapped to a [CWE (Common Weakness Enumeration)](http://cwe.mitre.org/data/index.html) which describes in more generic terms the vulnerability. The exact mapping can be found [here](https://github.com/securego/gosec/blob/master/issue/issue.go#L50). ### Configuration diff --git a/vendor/github.com/securego/gosec/v2/action.yml b/vendor/github.com/securego/gosec/v2/action.yml index aab6c8039..0320f0c21 100644 --- a/vendor/github.com/securego/gosec/v2/action.yml +++ b/vendor/github.com/securego/gosec/v2/action.yml @@ -10,7 +10,7 @@ inputs: runs: using: 'docker' - image: 'docker://securego/gosec' + image: 'docker://securego/gosec:2.15.0' args: - ${{ inputs.args }} diff --git a/vendor/github.com/securego/gosec/v2/analyzer.go b/vendor/github.com/securego/gosec/v2/analyzer.go index 5f778791e..830d338e4 100644 --- a/vendor/github.com/securego/gosec/v2/analyzer.go +++ b/vendor/github.com/securego/gosec/v2/analyzer.go @@ -31,6 +31,10 @@ import ( "strings" "sync" + "github.com/securego/gosec/v2/analyzers" + "github.com/securego/gosec/v2/issue" + "golang.org/x/tools/go/analysis" + "golang.org/x/tools/go/analysis/passes/buildssa" "golang.org/x/tools/go/packages" ) @@ -42,7 +46,10 @@ const LoadMode = packages.NeedName | packages.NeedTypes | packages.NeedTypesSizes | packages.NeedTypesInfo | - packages.NeedSyntax + packages.NeedSyntax | + packages.NeedModule | + packages.NeedEmbedFiles | + packages.NeedEmbedPatterns const externalSuppressionJustification = "Globally suppressed." @@ -60,12 +67,24 @@ type Context struct { Pkg *types.Package PkgFiles []*ast.File Root *ast.File - Config Config Imports *ImportTracker - Ignores []map[string][]SuppressionInfo + Config Config + Ignores []map[string][]issue.SuppressionInfo PassedValues map[string]interface{} } +// GetFileAtNodePos returns the file at the node position in the file set available in the context. +func (ctx *Context) GetFileAtNodePos(node ast.Node) *token.File { + return ctx.FileSet.File(node.Pos()) +} + +// NewIssue creates a new issue +func (ctx *Context) NewIssue(node ast.Node, ruleID, desc string, + severity, confidence issue.Score, +) *issue.Issue { + return issue.New(ctx.GetFileAtNodePos(node), node, ruleID, desc, severity, confidence) +} + // Metrics used when reporting information about a scanning run. type Metrics struct { NumFiles int `json:"files"` @@ -82,7 +101,7 @@ type Analyzer struct { context *Context config Config logger *log.Logger - issues []*Issue + issues []*issue.Issue stats *Metrics errors map[string][]Error // keys are file paths; values are the golang errors in those files tests bool @@ -90,13 +109,7 @@ type Analyzer struct { showIgnored bool trackSuppressions bool concurrency int -} - -// SuppressionInfo object is to record the kind and the justification that used -// to suppress violations. -type SuppressionInfo struct { - Kind string `json:"kind"` - Justification string `json:"justification"` + analyzerList []*analysis.Analyzer } // NewAnalyzer builds a new analyzer. @@ -119,13 +132,14 @@ func NewAnalyzer(conf Config, tests bool, excludeGenerated bool, trackSuppressio context: &Context{}, config: conf, logger: logger, - issues: make([]*Issue, 0, 16), + issues: make([]*issue.Issue, 0, 16), stats: &Metrics{}, errors: make(map[string][]Error), tests: tests, concurrency: concurrency, excludeGenerated: excludeGenerated, trackSuppressions: trackSuppressions, + analyzerList: analyzers.BuildDefaultAnalyzers(), } } @@ -216,7 +230,10 @@ func (gosec *Analyzer) Process(buildTags []string, packagePaths ...string) error wg.Wait() // wait for the goroutines to stop return fmt.Errorf("parsing errors in pkg %q: %w", pkg.Name, err) } - gosec.Check(pkg) + gosec.CheckRules(pkg) + if on, err := gosec.config.IsGlobalEnabled(SSA); err == nil && on { + gosec.CheckAnalyzers(pkg) + } } } } @@ -267,8 +284,8 @@ func (gosec *Analyzer) load(pkgPath string, conf *packages.Config) ([]*packages. return pkgs, nil } -// Check runs analysis on the given package -func (gosec *Analyzer) Check(pkg *packages.Package) { +// CheckRules runs analysis on the given package +func (gosec *Analyzer) CheckRules(pkg *packages.Package) { gosec.logger.Println("Checking package:", pkg.Name) for _, file := range pkg.Syntax { fp := pkg.Fset.File(file.Pos()) @@ -303,6 +320,70 @@ func (gosec *Analyzer) Check(pkg *packages.Package) { } } +// CheckAnalyzers runs analyzers on a given package +func (gosec *Analyzer) CheckAnalyzers(pkg *packages.Package) { + ssaPass := &analysis.Pass{ + Analyzer: buildssa.Analyzer, + Fset: pkg.Fset, + Files: pkg.Syntax, + OtherFiles: pkg.OtherFiles, + IgnoredFiles: pkg.IgnoredFiles, + Pkg: pkg.Types, + TypesInfo: pkg.TypesInfo, + TypesSizes: pkg.TypesSizes, + ResultOf: nil, + Report: nil, + ImportObjectFact: nil, + ExportObjectFact: nil, + ImportPackageFact: nil, + ExportPackageFact: nil, + AllObjectFacts: nil, + AllPackageFacts: nil, + } + ssaResult, err := ssaPass.Analyzer.Run(ssaPass) + if err != nil { + gosec.logger.Printf("Error running SSA analyser on package %q: %s", pkg.Name, err) + return + } + resultMap := map[*analysis.Analyzer]interface{}{ + buildssa.Analyzer: &analyzers.SSAAnalyzerResult{ + Config: gosec.Config(), + Logger: gosec.logger, + SSA: ssaResult.(*buildssa.SSA), + }, + } + for _, analyzer := range gosec.analyzerList { + pass := &analysis.Pass{ + Analyzer: analyzer, + Fset: pkg.Fset, + Files: pkg.Syntax, + OtherFiles: pkg.OtherFiles, + IgnoredFiles: pkg.IgnoredFiles, + Pkg: pkg.Types, + TypesInfo: pkg.TypesInfo, + TypesSizes: pkg.TypesSizes, + ResultOf: resultMap, + Report: func(d analysis.Diagnostic) {}, + ImportObjectFact: nil, + ExportObjectFact: nil, + ImportPackageFact: nil, + ExportPackageFact: nil, + AllObjectFacts: nil, + AllPackageFacts: nil, + } + result, err := pass.Analyzer.Run(pass) + if err != nil { + gosec.logger.Printf("Error running analyzer %s: %s\n", analyzer.Name, err) + continue + } + if result != nil { + if aissue, ok := result.(*issue.Issue); ok { + gosec.updateIssues(aissue, false, []issue.SuppressionInfo{}) + } + } + } +} + func isGeneratedFile(file *ast.File) bool { for _, comment := range file.Comments { for _, row := range comment.List { @@ -364,7 +445,7 @@ func (gosec *Analyzer) AppendError(file string, err error) { } // ignore a node (and sub-tree) if it is tagged with a nosec tag comment -func (gosec *Analyzer) ignore(n ast.Node) map[string]SuppressionInfo { +func (gosec *Analyzer) ignore(n ast.Node) map[string]issue.SuppressionInfo { if groups, ok := gosec.context.Comments[n]; ok && !gosec.ignoreNosec { // Checks if an alternative for #nosec is set and, if not, uses the default. @@ -401,13 +482,13 @@ func (gosec *Analyzer) ignore(n ast.Node) map[string]SuppressionInfo { re := regexp.MustCompile(`(G\d{3})`) matches := re.FindAllStringSubmatch(directive, -1) - suppression := SuppressionInfo{ + suppression := issue.SuppressionInfo{ Kind: "inSource", Justification: justification, } // Find the rule IDs to ignore. - ignores := make(map[string]SuppressionInfo) + ignores := make(map[string]issue.SuppressionInfo) for _, v := range matches { ignores[v[1]] = suppression } @@ -426,25 +507,42 @@ func (gosec *Analyzer) ignore(n ast.Node) map[string]SuppressionInfo { // Visit runs the gosec visitor logic over an AST created by parsing go code. // Rule methods added with AddRule will be invoked as necessary. func (gosec *Analyzer) Visit(n ast.Node) ast.Visitor { - // If we've reached the end of this branch, pop off the ignores stack. - if n == nil { - if len(gosec.context.Ignores) > 0 { - gosec.context.Ignores = gosec.context.Ignores[1:] - } + ignores, ok := gosec.updateIgnoredRules(n) + if !ok { return gosec } + + // Using ast.File instead of ast.ImportSpec, so that we can track all imports at once. switch i := n.(type) { case *ast.File: - // Using ast.File instead of ast.ImportSpec, so that we can track - // all imports at once. gosec.context.Imports.TrackFile(i) } + for _, rule := range gosec.ruleset.RegisteredFor(n) { + suppressions, ignored := gosec.updateSuppressions(rule.ID(), ignores) + issue, err := rule.Match(n, gosec.context) + if err != nil { + file, line := GetLocation(n, gosec.context) + file = path.Base(file) + gosec.logger.Printf("Rule error: %v => %s (%s:%d)\n", reflect.TypeOf(rule), err, file, line) + } + gosec.updateIssues(issue, ignored, suppressions) + } + return gosec +} + +func (gosec *Analyzer) updateIgnoredRules(n ast.Node) (map[string][]issue.SuppressionInfo, bool) { + if n == nil { + if len(gosec.context.Ignores) > 0 { + gosec.context.Ignores = gosec.context.Ignores[1:] + } + return nil, false + } // Get any new rule exclusions. ignoredRules := gosec.ignore(n) // Now create the union of exclusions. - ignores := map[string][]SuppressionInfo{} + ignores := map[string][]issue.SuppressionInfo{} if len(gosec.context.Ignores) > 0 { for k, v := range gosec.context.Ignores[0] { ignores[k] = v @@ -456,59 +554,57 @@ func (gosec *Analyzer) Visit(n ast.Node) ast.Visitor { } // Push the new set onto the stack. - gosec.context.Ignores = append([]map[string][]SuppressionInfo{ignores}, gosec.context.Ignores...) + gosec.context.Ignores = append([]map[string][]issue.SuppressionInfo{ignores}, gosec.context.Ignores...) - for _, rule := range gosec.ruleset.RegisteredFor(n) { - // Check if all rules are ignored. - generalSuppressions, generalIgnored := ignores[aliasOfAllRules] - // Check if the specific rule is ignored - ruleSuppressions, ruleIgnored := ignores[rule.ID()] - - ignored := generalIgnored || ruleIgnored - suppressions := append(generalSuppressions, ruleSuppressions...) - - // Track external suppressions. - if gosec.ruleset.IsRuleSuppressed(rule.ID()) { - ignored = true - suppressions = append(suppressions, SuppressionInfo{ - Kind: "external", - Justification: externalSuppressionJustification, - }) - } + return ignores, true +} - issue, err := rule.Match(n, gosec.context) - if err != nil { - file, line := GetLocation(n, gosec.context) - file = path.Base(file) - gosec.logger.Printf("Rule error: %v => %s (%s:%d)\n", reflect.TypeOf(rule), err, file, line) +func (gosec *Analyzer) updateSuppressions(id string, ignores map[string][]issue.SuppressionInfo) ([]issue.SuppressionInfo, bool) { + // Check if all rules are ignored. + generalSuppressions, generalIgnored := ignores[aliasOfAllRules] + // Check if the specific rule is ignored + ruleSuppressions, ruleIgnored := ignores[id] + + ignored := generalIgnored || ruleIgnored + suppressions := append(generalSuppressions, ruleSuppressions...) + + // Track external suppressions. + if gosec.ruleset.IsRuleSuppressed(id) { + ignored = true + suppressions = append(suppressions, issue.SuppressionInfo{ + Kind: "external", + Justification: externalSuppressionJustification, + }) + } + return suppressions, ignored +} + +func (gosec *Analyzer) updateIssues(issue *issue.Issue, ignored bool, suppressions []issue.SuppressionInfo) { + if issue != nil { + if gosec.showIgnored { + issue.NoSec = ignored } - if issue != nil { - if gosec.showIgnored { - issue.NoSec = ignored - } - if !ignored || !gosec.showIgnored { - gosec.stats.NumFound++ - } - if ignored && gosec.trackSuppressions { - issue.WithSuppressions(suppressions) - gosec.issues = append(gosec.issues, issue) - } else if !ignored || gosec.showIgnored || gosec.ignoreNosec { - gosec.issues = append(gosec.issues, issue) - } + if !ignored || !gosec.showIgnored { + gosec.stats.NumFound++ + } + if ignored && gosec.trackSuppressions { + issue.WithSuppressions(suppressions) + gosec.issues = append(gosec.issues, issue) + } else if !ignored || gosec.showIgnored || gosec.ignoreNosec { + gosec.issues = append(gosec.issues, issue) } } - return gosec } // Report returns the current issues discovered and the metrics about the scan -func (gosec *Analyzer) Report() ([]*Issue, *Metrics, map[string][]Error) { +func (gosec *Analyzer) Report() ([]*issue.Issue, *Metrics, map[string][]Error) { return gosec.issues, gosec.stats, gosec.errors } // Reset clears state such as context, issues and metrics from the configured analyzer func (gosec *Analyzer) Reset() { gosec.context = &Context{} - gosec.issues = make([]*Issue, 0, 16) + gosec.issues = make([]*issue.Issue, 0, 16) gosec.stats = &Metrics{} gosec.ruleset = NewRuleSet() } diff --git a/vendor/github.com/securego/gosec/v2/analyzers/ssrf.go b/vendor/github.com/securego/gosec/v2/analyzers/ssrf.go new file mode 100644 index 000000000..a9dbd9500 --- /dev/null +++ b/vendor/github.com/securego/gosec/v2/analyzers/ssrf.go @@ -0,0 +1,57 @@ +// (c) Copyright gosec's authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package analyzers + +import ( + "golang.org/x/tools/go/analysis" + "golang.org/x/tools/go/analysis/passes/buildssa" + "golang.org/x/tools/go/ssa" + + "github.com/securego/gosec/v2/issue" +) + +func newSSRFAnalyzer(id string, description string) *analysis.Analyzer { + return &analysis.Analyzer{ + Name: id, + Doc: description, + Run: runSSRF, + Requires: []*analysis.Analyzer{buildssa.Analyzer}, + } +} + +func runSSRF(pass *analysis.Pass) (interface{}, error) { + ssaResult, err := getSSAResult(pass) + if err != nil { + return nil, err + } + // TODO: implement the analysis + for _, fn := range ssaResult.SSA.SrcFuncs { + for _, block := range fn.DomPreorder() { + for _, instr := range block.Instrs { + switch instr := instr.(type) { + case *ssa.Call: + callee := instr.Call.StaticCallee() + if callee != nil { + ssaResult.Logger.Printf("callee: %s\n", callee) + return newIssue(pass.Analyzer.Name, + "not implemeted", + pass.Fset, instr.Call.Pos(), issue.Low, issue.High), nil + } + } + } + } + } + return nil, nil +} diff --git a/vendor/github.com/securego/gosec/v2/analyzers/util.go b/vendor/github.com/securego/gosec/v2/analyzers/util.go new file mode 100644 index 000000000..b090a3e45 --- /dev/null +++ b/vendor/github.com/securego/gosec/v2/analyzers/util.go @@ -0,0 +1,98 @@ +// (c) Copyright gosec's authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package analyzers + +import ( + "fmt" + "go/token" + "log" + "os" + "strconv" + + "golang.org/x/tools/go/analysis" + "golang.org/x/tools/go/analysis/passes/buildssa" + + "github.com/securego/gosec/v2/issue" +) + +// SSAAnalyzerResult contains various information returned by the +// SSA analysis along with some configuraion +type SSAAnalyzerResult struct { + Config map[string]interface{} + Logger *log.Logger + SSA *buildssa.SSA +} + +// BuildDefaultAnalyzers returns the default list of analyzers +func BuildDefaultAnalyzers() []*analysis.Analyzer { + return []*analysis.Analyzer{ + newSSRFAnalyzer("G107", "URL provided to HTTP request as taint input"), + } +} + +// getSSAResult retrives the SSA result from analysis pass +func getSSAResult(pass *analysis.Pass) (*SSAAnalyzerResult, error) { + result, ok := pass.ResultOf[buildssa.Analyzer] + if !ok { + return nil, fmt.Errorf("no SSA result found in the analysis pass") + } + ssaResult, ok := result.(*SSAAnalyzerResult) + if !ok { + return nil, fmt.Errorf("the analysis pass result is not of type SSA") + } + return ssaResult, nil +} + +// newIssue creates a new gosec issue +func newIssue(analyzerID string, desc string, fileSet *token.FileSet, + pos token.Pos, severity, confidence issue.Score, +) *issue.Issue { + file := fileSet.File(pos) + line := file.Line(pos) + col := file.Position(pos).Column + + return &issue.Issue{ + RuleID: analyzerID, + File: file.Name(), + Line: strconv.Itoa(line), + Col: strconv.Itoa(col), + Severity: severity, + Confidence: confidence, + What: desc, + Cwe: issue.GetCweByRule(analyzerID), + Code: issueCodeSnippet(fileSet, pos), + } +} + +func issueCodeSnippet(fileSet *token.FileSet, pos token.Pos) string { + file := fileSet.File(pos) + + start := (int64)(file.Line(pos)) + if start-issue.SnippetOffset > 0 { + start = start - issue.SnippetOffset + } + end := (int64)(file.Line(pos)) + end = end + issue.SnippetOffset + + var code string + if file, err := os.Open(file.Name()); err == nil { + defer file.Close() // #nosec + code, err = issue.CodeSnippet(file, start, end) + if err != nil { + return err.Error() + } + } + return code +} diff --git a/vendor/github.com/securego/gosec/v2/config.go b/vendor/github.com/securego/gosec/v2/config.go index 443d45f78..ca4cf2175 100644 --- a/vendor/github.com/securego/gosec/v2/config.go +++ b/vendor/github.com/securego/gosec/v2/config.go @@ -29,6 +29,8 @@ const ( ExcludeRules GlobalOption = "exclude" // IncludeRules global option for should be load IncludeRules GlobalOption = "include" + // SSA global option to enable go analysis framework with SSA support + SSA GlobalOption = "ssa" ) // Config is used to provide configuration and customization to each of the rules. diff --git a/vendor/github.com/securego/gosec/v2/helpers.go b/vendor/github.com/securego/gosec/v2/helpers.go index 62ede0549..08b7893eb 100644 --- a/vendor/github.com/securego/gosec/v2/helpers.go +++ b/vendor/github.com/securego/gosec/v2/helpers.go @@ -182,7 +182,7 @@ func GetCallInfo(n ast.Node, ctx *Context) (string, string, error) { } // GetCallStringArgsValues returns the values of strings arguments if they can be resolved -func GetCallStringArgsValues(n ast.Node, ctx *Context) []string { +func GetCallStringArgsValues(n ast.Node, _ *Context) []string { values := []string{} switch node := n.(type) { case *ast.CallExpr: diff --git a/vendor/github.com/securego/gosec/v2/import_tracker.go b/vendor/github.com/securego/gosec/v2/import_tracker.go index 30e7c009b..7984e99f4 100644 --- a/vendor/github.com/securego/gosec/v2/import_tracker.go +++ b/vendor/github.com/securego/gosec/v2/import_tracker.go @@ -51,9 +51,7 @@ func (t *ImportTracker) TrackPackages(pkgs ...*types.Package) { func (t *ImportTracker) TrackImport(imported *ast.ImportSpec) { importPath := strings.Trim(imported.Path.Value, `"`) if imported.Name != nil { - if imported.Name.Name == "_" { - // Initialization only import - } else { + if imported.Name.Name != "_" { // Aliased import t.Imported[importPath] = append(t.Imported[importPath], imported.Name.String()) } diff --git a/vendor/github.com/securego/gosec/v2/issue.go b/vendor/github.com/securego/gosec/v2/issue/issue.go index d8faf4bf9..5bf00dec2 100644 --- a/vendor/github.com/securego/gosec/v2/issue.go +++ b/vendor/github.com/securego/gosec/v2/issue/issue.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package gosec +package issue import ( "bufio" @@ -77,7 +77,6 @@ var ruleToCWE = map[string]string{ "G304": "22", "G305": "22", "G306": "276", - "G307": "703", "G401": "326", "G402": "295", "G403": "310", @@ -105,8 +104,15 @@ type Issue struct { Suppressions []SuppressionInfo `json:"suppressions"` // Suppression info of the issue } +// SuppressionInfo object is to record the kind and the justification that used +// to suppress violations. +type SuppressionInfo struct { + Kind string `json:"kind"` + Justification string `json:"justification"` +} + // FileLocation point out the file path and line number in file -func (i Issue) FileLocation() string { +func (i *Issue) FileLocation() string { return fmt.Sprintf("%s:%s", i.File, i.Line) } @@ -137,11 +143,8 @@ func (c Score) String() string { return "UNDEFINED" } -// codeSnippet extracts a code snippet based on the ast reference -func codeSnippet(file *os.File, start int64, end int64, n ast.Node) (string, error) { - if n == nil { - return "", fmt.Errorf("invalid AST node provided") - } +// CodeSnippet extracts a code snippet based on the ast reference +func CodeSnippet(file *os.File, start int64, end int64) (string, error) { var pos int64 var buf bytes.Buffer scanner := bufio.NewScanner(file) @@ -171,9 +174,8 @@ func codeSnippetEndLine(node ast.Node, fobj *token.File) int64 { return e + SnippetOffset } -// NewIssue creates a new Issue -func NewIssue(ctx *Context, node ast.Node, ruleID, desc string, severity Score, confidence Score) *Issue { - fobj := ctx.FileSet.File(node.Pos()) +// New creates a new Issue +func New(fobj *token.File, node ast.Node, ruleID, desc string, severity, confidence Score) *Issue { name := fobj.Name() start, end := fobj.Line(node.Pos()), fobj.Line(node.End()) line := strconv.Itoa(start) @@ -183,11 +185,14 @@ func NewIssue(ctx *Context, node ast.Node, ruleID, desc string, severity Score, col := strconv.Itoa(fobj.Position(node.Pos()).Column) var code string - if file, err := os.Open(fobj.Name()); err == nil { + if node == nil { + code = "invalid AST node provided" + } + if file, err := os.Open(fobj.Name()); err == nil && node != nil { defer file.Close() // #nosec s := codeSnippetStartLine(node, fobj) e := codeSnippetEndLine(node, fobj) - code, err = codeSnippet(file, s, e, node) + code, err = CodeSnippet(file, s, e) if err != nil { code = err.Error() } diff --git a/vendor/github.com/securego/gosec/v2/report.go b/vendor/github.com/securego/gosec/v2/report.go index 96b1466d5..4fdeea520 100644 --- a/vendor/github.com/securego/gosec/v2/report.go +++ b/vendor/github.com/securego/gosec/v2/report.go @@ -1,15 +1,19 @@ package gosec +import ( + "github.com/securego/gosec/v2/issue" +) + // ReportInfo this is report information type ReportInfo struct { Errors map[string][]Error `json:"Golang errors"` - Issues []*Issue + Issues []*issue.Issue Stats *Metrics GosecVersion string } // NewReportInfo instantiate a ReportInfo -func NewReportInfo(issues []*Issue, metrics *Metrics, errors map[string][]Error) *ReportInfo { +func NewReportInfo(issues []*issue.Issue, metrics *Metrics, errors map[string][]Error) *ReportInfo { return &ReportInfo{ Errors: errors, Issues: issues, diff --git a/vendor/github.com/securego/gosec/v2/resolve.go b/vendor/github.com/securego/gosec/v2/resolve.go index cdc287e8e..a201b8d32 100644 --- a/vendor/github.com/securego/gosec/v2/resolve.go +++ b/vendor/github.com/securego/gosec/v2/resolve.go @@ -66,7 +66,7 @@ func resolveBinExpr(n *ast.BinaryExpr, c *Context) bool { return (TryResolve(n.X, c) && TryResolve(n.Y, c)) } -func resolveCallExpr(n *ast.CallExpr, c *Context) bool { +func resolveCallExpr(_ *ast.CallExpr, _ *Context) bool { // TODO(tkelsey): next step, full function resolution return false } diff --git a/vendor/github.com/securego/gosec/v2/rule.go b/vendor/github.com/securego/gosec/v2/rule.go index c0429c4c2..5e973b6ac 100644 --- a/vendor/github.com/securego/gosec/v2/rule.go +++ b/vendor/github.com/securego/gosec/v2/rule.go @@ -15,12 +15,14 @@ package gosec import ( "go/ast" "reflect" + + "github.com/securego/gosec/v2/issue" ) // The Rule interface used by all rules supported by gosec. type Rule interface { ID() string - Match(ast.Node, *Context) (*Issue, error) + Match(ast.Node, *Context) (*issue.Issue, error) } // RuleBuilder is used to register a rule definition with the analyzer diff --git a/vendor/github.com/securego/gosec/v2/rules/archive.go b/vendor/github.com/securego/gosec/v2/rules/archive.go index 92c7e4481..987047435 100644 --- a/vendor/github.com/securego/gosec/v2/rules/archive.go +++ b/vendor/github.com/securego/gosec/v2/rules/archive.go @@ -5,10 +5,11 @@ import ( "go/types" "github.com/securego/gosec/v2" + "github.com/securego/gosec/v2/issue" ) type archive struct { - gosec.MetaData + issue.MetaData calls gosec.CallList argTypes []string } @@ -18,7 +19,7 @@ func (a *archive) ID() string { } // Match inspects AST nodes to determine if the filepath.Joins uses any argument derived from type zip.File or tar.Header -func (a *archive) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { +func (a *archive) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { if node := a.calls.ContainsPkgCallExpr(n, c, false); node != nil { for _, arg := range node.Args { var argType types.Type @@ -38,7 +39,7 @@ func (a *archive) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { if argType != nil { for _, t := range a.argTypes { if argType.String() == t { - return gosec.NewIssue(c, n, a.ID(), a.What, a.Severity, a.Confidence), nil + return c.NewIssue(n, a.ID(), a.What, a.Severity, a.Confidence), nil } } } @@ -48,17 +49,17 @@ func (a *archive) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { } // NewArchive creates a new rule which detects the file traversal when extracting zip/tar archives -func NewArchive(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { +func NewArchive(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { calls := gosec.NewCallList() calls.Add("path/filepath", "Join") calls.Add("path", "Join") return &archive{ calls: calls, argTypes: []string{"*archive/zip.File", "*archive/tar.Header"}, - MetaData: gosec.MetaData{ + MetaData: issue.MetaData{ ID: id, - Severity: gosec.Medium, - Confidence: gosec.High, + Severity: issue.Medium, + Confidence: issue.High, What: "File traversal when extracting zip/tar archive", }, }, []ast.Node{(*ast.CallExpr)(nil)} diff --git a/vendor/github.com/securego/gosec/v2/rules/bad_defer.go b/vendor/github.com/securego/gosec/v2/rules/bad_defer.go deleted file mode 100644 index 141a4a939..000000000 --- a/vendor/github.com/securego/gosec/v2/rules/bad_defer.go +++ /dev/null @@ -1,96 +0,0 @@ -package rules - -import ( - "fmt" - "go/ast" - "strings" - - "github.com/securego/gosec/v2" -) - -type deferType struct { - typ string - methods []string -} - -type badDefer struct { - gosec.MetaData - types []deferType -} - -func (r *badDefer) ID() string { - return r.MetaData.ID -} - -func normalize(typ string) string { - return strings.TrimPrefix(typ, "*") -} - -func contains(methods []string, method string) bool { - for _, m := range methods { - if m == method { - return true - } - } - return false -} - -func (r *badDefer) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { - if deferStmt, ok := n.(*ast.DeferStmt); ok { - for _, deferTyp := range r.types { - if typ, method, err := gosec.GetCallInfo(deferStmt.Call, c); err == nil { - if normalize(typ) == deferTyp.typ && contains(deferTyp.methods, method) { - return gosec.NewIssue(c, n, r.ID(), fmt.Sprintf(r.What, method, typ), r.Severity, r.Confidence), nil - } - } - } - } - - return nil, nil -} - -// NewDeferredClosing detects unsafe defer of error returning methods -func NewDeferredClosing(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { - return &badDefer{ - types: []deferType{ - { - typ: "os.File", - methods: []string{"Close"}, - }, - { - typ: "io.ReadCloser", - methods: []string{"Close"}, - }, - { - typ: "io.WriteCloser", - methods: []string{"Close"}, - }, - { - typ: "io.ReadWriteCloser", - methods: []string{"Close"}, - }, - { - typ: "io.ReadSeekCloser", - methods: []string{"Close"}, - }, - { - typ: "io.Closer", - methods: []string{"Close"}, - }, - { - typ: "net.Conn", - methods: []string{"Close"}, - }, - { - typ: "net.Listener", - methods: []string{"Close"}, - }, - }, - MetaData: gosec.MetaData{ - ID: id, - Severity: gosec.Medium, - Confidence: gosec.High, - What: "Deferring unsafe method %q on type %q", - }, - }, []ast.Node{(*ast.DeferStmt)(nil)} -} diff --git a/vendor/github.com/securego/gosec/v2/rules/bind.go b/vendor/github.com/securego/gosec/v2/rules/bind.go index 8f6af067a..fef760c80 100644 --- a/vendor/github.com/securego/gosec/v2/rules/bind.go +++ b/vendor/github.com/securego/gosec/v2/rules/bind.go @@ -19,11 +19,12 @@ import ( "regexp" "github.com/securego/gosec/v2" + "github.com/securego/gosec/v2/issue" ) // Looks for net.Listen("0.0.0.0") or net.Listen(":8080") type bindsToAllNetworkInterfaces struct { - gosec.MetaData + issue.MetaData calls gosec.CallList pattern *regexp.Regexp } @@ -32,7 +33,7 @@ func (r *bindsToAllNetworkInterfaces) ID() string { return r.MetaData.ID } -func (r *bindsToAllNetworkInterfaces) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { +func (r *bindsToAllNetworkInterfaces) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { callExpr := r.calls.ContainsPkgCallExpr(n, c, false) if callExpr == nil { return nil, nil @@ -42,14 +43,14 @@ func (r *bindsToAllNetworkInterfaces) Match(n ast.Node, c *gosec.Context) (*gose if bl, ok := arg.(*ast.BasicLit); ok { if arg, err := gosec.GetString(bl); err == nil { if r.pattern.MatchString(arg) { - return gosec.NewIssue(c, n, r.ID(), r.What, r.Severity, r.Confidence), nil + return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil } } } else if ident, ok := arg.(*ast.Ident); ok { values := gosec.GetIdentStringValues(ident) for _, value := range values { if r.pattern.MatchString(value) { - return gosec.NewIssue(c, n, r.ID(), r.What, r.Severity, r.Confidence), nil + return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil } } } @@ -57,7 +58,7 @@ func (r *bindsToAllNetworkInterfaces) Match(n ast.Node, c *gosec.Context) (*gose values := gosec.GetCallStringArgsValues(callExpr.Args[0], c) for _, value := range values { if r.pattern.MatchString(value) { - return gosec.NewIssue(c, n, r.ID(), r.What, r.Severity, r.Confidence), nil + return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil } } } @@ -66,17 +67,17 @@ func (r *bindsToAllNetworkInterfaces) Match(n ast.Node, c *gosec.Context) (*gose // NewBindsToAllNetworkInterfaces detects socket connections that are setup to // listen on all network interfaces. -func NewBindsToAllNetworkInterfaces(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { +func NewBindsToAllNetworkInterfaces(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { calls := gosec.NewCallList() calls.Add("net", "Listen") calls.Add("crypto/tls", "Listen") return &bindsToAllNetworkInterfaces{ calls: calls, pattern: regexp.MustCompile(`^(0.0.0.0|:).*$`), - MetaData: gosec.MetaData{ + MetaData: issue.MetaData{ ID: id, - Severity: gosec.Medium, - Confidence: gosec.High, + Severity: issue.Medium, + Confidence: issue.High, What: "Binds to all network interfaces", }, }, []ast.Node{(*ast.CallExpr)(nil)} diff --git a/vendor/github.com/securego/gosec/v2/rules/blocklist.go b/vendor/github.com/securego/gosec/v2/rules/blocklist.go index afd4ee56b..5e03cf7a0 100644 --- a/vendor/github.com/securego/gosec/v2/rules/blocklist.go +++ b/vendor/github.com/securego/gosec/v2/rules/blocklist.go @@ -19,27 +19,28 @@ import ( "strings" "github.com/securego/gosec/v2" + "github.com/securego/gosec/v2/issue" ) type blocklistedImport struct { - gosec.MetaData + issue.MetaData Blocklisted map[string]string } func unquote(original string) string { - copy := strings.TrimSpace(original) - copy = strings.TrimLeft(copy, `"`) - return strings.TrimRight(copy, `"`) + cleaned := strings.TrimSpace(original) + cleaned = strings.TrimLeft(cleaned, `"`) + return strings.TrimRight(cleaned, `"`) } func (r *blocklistedImport) ID() string { return r.MetaData.ID } -func (r *blocklistedImport) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { +func (r *blocklistedImport) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { if node, ok := n.(*ast.ImportSpec); ok { if description, ok := r.Blocklisted[unquote(node.Path.Value)]; ok { - return gosec.NewIssue(c, node, r.ID(), description, r.Severity, r.Confidence), nil + return c.NewIssue(node, r.ID(), description, r.Severity, r.Confidence), nil } } return nil, nil @@ -47,12 +48,12 @@ func (r *blocklistedImport) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, e // NewBlocklistedImports reports when a blocklisted import is being used. // Typically when a deprecated technology is being used. -func NewBlocklistedImports(id string, conf gosec.Config, blocklist map[string]string) (gosec.Rule, []ast.Node) { +func NewBlocklistedImports(id string, _ gosec.Config, blocklist map[string]string) (gosec.Rule, []ast.Node) { return &blocklistedImport{ - MetaData: gosec.MetaData{ + MetaData: issue.MetaData{ ID: id, - Severity: gosec.Medium, - Confidence: gosec.High, + Severity: issue.Medium, + Confidence: issue.High, }, Blocklisted: blocklist, }, []ast.Node{(*ast.ImportSpec)(nil)} diff --git a/vendor/github.com/securego/gosec/v2/rules/decompression-bomb.go b/vendor/github.com/securego/gosec/v2/rules/decompression-bomb.go index 02256faa9..7e57f1a5b 100644 --- a/vendor/github.com/securego/gosec/v2/rules/decompression-bomb.go +++ b/vendor/github.com/securego/gosec/v2/rules/decompression-bomb.go @@ -19,10 +19,11 @@ import ( "go/ast" "github.com/securego/gosec/v2" + "github.com/securego/gosec/v2/issue" ) type decompressionBombCheck struct { - gosec.MetaData + issue.MetaData readerCalls gosec.CallList copyCalls gosec.CallList } @@ -40,7 +41,7 @@ func containsReaderCall(node ast.Node, ctx *gosec.Context, list gosec.CallList) return list.Contains(s, idt) } -func (d *decompressionBombCheck) Match(node ast.Node, ctx *gosec.Context) (*gosec.Issue, error) { +func (d *decompressionBombCheck) Match(node ast.Node, ctx *gosec.Context) (*issue.Issue, error) { var readerVarObj map[*ast.Object]struct{} // To check multiple lines, ctx.PassedValues is used to store temporary data. @@ -72,7 +73,7 @@ func (d *decompressionBombCheck) Match(node ast.Node, ctx *gosec.Context) (*gose if idt, ok := n.Args[1].(*ast.Ident); ok { if _, ok := readerVarObj[idt.Obj]; ok { // Detect io.Copy(x, r) - return gosec.NewIssue(ctx, n, d.ID(), d.What, d.Severity, d.Confidence), nil + return ctx.NewIssue(n, d.ID(), d.What, d.Severity, d.Confidence), nil } } } @@ -82,7 +83,7 @@ func (d *decompressionBombCheck) Match(node ast.Node, ctx *gosec.Context) (*gose } // NewDecompressionBombCheck detects if there is potential DoS vulnerability via decompression bomb -func NewDecompressionBombCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { +func NewDecompressionBombCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { readerCalls := gosec.NewCallList() readerCalls.Add("compress/gzip", "NewReader") readerCalls.AddAll("compress/zlib", "NewReader", "NewReaderDict") @@ -98,10 +99,10 @@ func NewDecompressionBombCheck(id string, conf gosec.Config) (gosec.Rule, []ast. copyCalls.Add("io", "CopyBuffer") return &decompressionBombCheck{ - MetaData: gosec.MetaData{ + MetaData: issue.MetaData{ ID: id, - Severity: gosec.Medium, - Confidence: gosec.Medium, + Severity: issue.Medium, + Confidence: issue.Medium, What: "Potential DoS vulnerability via decompression bomb", }, readerCalls: readerCalls, diff --git a/vendor/github.com/securego/gosec/v2/rules/directory-traversal.go b/vendor/github.com/securego/gosec/v2/rules/directory-traversal.go index c373427b8..47bcb2dc4 100644 --- a/vendor/github.com/securego/gosec/v2/rules/directory-traversal.go +++ b/vendor/github.com/securego/gosec/v2/rules/directory-traversal.go @@ -5,18 +5,19 @@ import ( "regexp" "github.com/securego/gosec/v2" + "github.com/securego/gosec/v2/issue" ) type traversal struct { pattern *regexp.Regexp - gosec.MetaData + issue.MetaData } func (r *traversal) ID() string { return r.MetaData.ID } -func (r *traversal) Match(n ast.Node, ctx *gosec.Context) (*gosec.Issue, error) { +func (r *traversal) Match(n ast.Node, ctx *gosec.Context) (*issue.Issue, error) { switch node := n.(type) { case *ast.CallExpr: return r.matchCallExpr(node, ctx) @@ -24,14 +25,14 @@ func (r *traversal) Match(n ast.Node, ctx *gosec.Context) (*gosec.Issue, error) return nil, nil } -func (r *traversal) matchCallExpr(assign *ast.CallExpr, ctx *gosec.Context) (*gosec.Issue, error) { +func (r *traversal) matchCallExpr(assign *ast.CallExpr, ctx *gosec.Context) (*issue.Issue, error) { for _, i := range assign.Args { if basiclit, ok1 := i.(*ast.BasicLit); ok1 { if fun, ok2 := assign.Fun.(*ast.SelectorExpr); ok2 { if x, ok3 := fun.X.(*ast.Ident); ok3 { - string := x.Name + "." + fun.Sel.Name + "(" + basiclit.Value + ")" - if r.pattern.MatchString(string) { - return gosec.NewIssue(ctx, assign, r.ID(), r.What, r.Severity, r.Confidence), nil + str := x.Name + "." + fun.Sel.Name + "(" + basiclit.Value + ")" + if r.pattern.MatchString(str) { + return ctx.NewIssue(assign, r.ID(), r.What, r.Severity, r.Confidence), nil } } } @@ -54,11 +55,11 @@ func NewDirectoryTraversal(id string, conf gosec.Config) (gosec.Rule, []ast.Node return &traversal{ pattern: regexp.MustCompile(pattern), - MetaData: gosec.MetaData{ + MetaData: issue.MetaData{ ID: id, What: "Potential directory traversal", - Confidence: gosec.Medium, - Severity: gosec.Medium, + Confidence: issue.Medium, + Severity: issue.Medium, }, }, []ast.Node{(*ast.CallExpr)(nil)} } diff --git a/vendor/github.com/securego/gosec/v2/rules/errors.go b/vendor/github.com/securego/gosec/v2/rules/errors.go index 0838382b3..d31248ccb 100644 --- a/vendor/github.com/securego/gosec/v2/rules/errors.go +++ b/vendor/github.com/securego/gosec/v2/rules/errors.go @@ -19,10 +19,11 @@ import ( "go/types" "github.com/securego/gosec/v2" + "github.com/securego/gosec/v2/issue" ) type noErrorCheck struct { - gosec.MetaData + issue.MetaData whitelist gosec.CallList } @@ -49,7 +50,7 @@ func returnsError(callExpr *ast.CallExpr, ctx *gosec.Context) int { return -1 } -func (r *noErrorCheck) Match(n ast.Node, ctx *gosec.Context) (*gosec.Issue, error) { +func (r *noErrorCheck) Match(n ast.Node, ctx *gosec.Context) (*issue.Issue, error) { switch stmt := n.(type) { case *ast.AssignStmt: cfg := ctx.Config @@ -61,7 +62,7 @@ func (r *noErrorCheck) Match(n ast.Node, ctx *gosec.Context) (*gosec.Issue, erro return nil, nil } if id, ok := stmt.Lhs[pos].(*ast.Ident); ok && id.Name == "_" { - return gosec.NewIssue(ctx, n, r.ID(), r.What, r.Severity, r.Confidence), nil + return ctx.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil } } } @@ -70,7 +71,7 @@ func (r *noErrorCheck) Match(n ast.Node, ctx *gosec.Context) (*gosec.Issue, erro if callExpr, ok := stmt.X.(*ast.CallExpr); ok && r.whitelist.ContainsCallExpr(stmt.X, ctx) == nil { pos := returnsError(callExpr, ctx) if pos >= 0 { - return gosec.NewIssue(ctx, n, r.ID(), r.What, r.Severity, r.Confidence), nil + return ctx.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil } } } @@ -100,10 +101,10 @@ func NewNoErrorCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { } return &noErrorCheck{ - MetaData: gosec.MetaData{ + MetaData: issue.MetaData{ ID: id, - Severity: gosec.Low, - Confidence: gosec.High, + Severity: issue.Low, + Confidence: issue.High, What: "Errors unhandled.", }, whitelist: whitelist, diff --git a/vendor/github.com/securego/gosec/v2/rules/fileperms.go b/vendor/github.com/securego/gosec/v2/rules/fileperms.go index e89b56369..0376b6a03 100644 --- a/vendor/github.com/securego/gosec/v2/rules/fileperms.go +++ b/vendor/github.com/securego/gosec/v2/rules/fileperms.go @@ -20,10 +20,11 @@ import ( "strconv" "github.com/securego/gosec/v2" + "github.com/securego/gosec/v2/issue" ) type filePermissions struct { - gosec.MetaData + issue.MetaData mode int64 pkgs []string calls []string @@ -54,12 +55,12 @@ func modeIsSubset(subset int64, superset int64) bool { return (subset | superset) == superset } -func (r *filePermissions) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { +func (r *filePermissions) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { for _, pkg := range r.pkgs { if callexpr, matched := gosec.MatchCallByPackage(n, c, pkg, r.calls...); matched { modeArg := callexpr.Args[len(callexpr.Args)-1] if mode, err := gosec.GetInt(modeArg); err == nil && !modeIsSubset(mode, r.mode) { - return gosec.NewIssue(c, n, r.ID(), r.What, r.Severity, r.Confidence), nil + return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil } } } @@ -73,10 +74,10 @@ func NewWritePerms(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { mode: mode, pkgs: []string{"io/ioutil", "os"}, calls: []string{"WriteFile"}, - MetaData: gosec.MetaData{ + MetaData: issue.MetaData{ ID: id, - Severity: gosec.Medium, - Confidence: gosec.High, + Severity: issue.Medium, + Confidence: issue.High, What: fmt.Sprintf("Expect WriteFile permissions to be %#o or less", mode), }, }, []ast.Node{(*ast.CallExpr)(nil)} @@ -90,10 +91,10 @@ func NewFilePerms(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { mode: mode, pkgs: []string{"os"}, calls: []string{"OpenFile", "Chmod"}, - MetaData: gosec.MetaData{ + MetaData: issue.MetaData{ ID: id, - Severity: gosec.Medium, - Confidence: gosec.High, + Severity: issue.Medium, + Confidence: issue.High, What: fmt.Sprintf("Expect file permissions to be %#o or less", mode), }, }, []ast.Node{(*ast.CallExpr)(nil)} @@ -107,10 +108,10 @@ func NewMkdirPerms(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { mode: mode, pkgs: []string{"os"}, calls: []string{"Mkdir", "MkdirAll"}, - MetaData: gosec.MetaData{ + MetaData: issue.MetaData{ ID: id, - Severity: gosec.Medium, - Confidence: gosec.High, + Severity: issue.Medium, + Confidence: issue.High, What: fmt.Sprintf("Expect directory permissions to be %#o or less", mode), }, }, []ast.Node{(*ast.CallExpr)(nil)} diff --git a/vendor/github.com/securego/gosec/v2/rules/hardcoded_credentials.go b/vendor/github.com/securego/gosec/v2/rules/hardcoded_credentials.go index b9e575654..eac50d7c9 100644 --- a/vendor/github.com/securego/gosec/v2/rules/hardcoded_credentials.go +++ b/vendor/github.com/securego/gosec/v2/rules/hardcoded_credentials.go @@ -21,11 +21,13 @@ import ( "strconv" zxcvbn "github.com/nbutton23/zxcvbn-go" + "github.com/securego/gosec/v2" + "github.com/securego/gosec/v2/issue" ) type credentials struct { - gosec.MetaData + issue.MetaData pattern *regexp.Regexp entropyThreshold float64 perCharThreshold float64 @@ -53,7 +55,7 @@ func (r *credentials) isHighEntropyString(str string) bool { entropyPerChar >= r.perCharThreshold)) } -func (r *credentials) Match(n ast.Node, ctx *gosec.Context) (*gosec.Issue, error) { +func (r *credentials) Match(n ast.Node, ctx *gosec.Context) (*issue.Issue, error) { switch node := n.(type) { case *ast.AssignStmt: return r.matchAssign(node, ctx) @@ -65,14 +67,14 @@ func (r *credentials) Match(n ast.Node, ctx *gosec.Context) (*gosec.Issue, error return nil, nil } -func (r *credentials) matchAssign(assign *ast.AssignStmt, ctx *gosec.Context) (*gosec.Issue, error) { +func (r *credentials) matchAssign(assign *ast.AssignStmt, ctx *gosec.Context) (*issue.Issue, error) { for _, i := range assign.Lhs { if ident, ok := i.(*ast.Ident); ok { if r.pattern.MatchString(ident.Name) { for _, e := range assign.Rhs { if val, err := gosec.GetString(e); err == nil { if r.ignoreEntropy || (!r.ignoreEntropy && r.isHighEntropyString(val)) { - return gosec.NewIssue(ctx, assign, r.ID(), r.What, r.Severity, r.Confidence), nil + return ctx.NewIssue(assign, r.ID(), r.What, r.Severity, r.Confidence), nil } } } @@ -82,7 +84,7 @@ func (r *credentials) matchAssign(assign *ast.AssignStmt, ctx *gosec.Context) (* return nil, nil } -func (r *credentials) matchValueSpec(valueSpec *ast.ValueSpec, ctx *gosec.Context) (*gosec.Issue, error) { +func (r *credentials) matchValueSpec(valueSpec *ast.ValueSpec, ctx *gosec.Context) (*issue.Issue, error) { for index, ident := range valueSpec.Names { if r.pattern.MatchString(ident.Name) && valueSpec.Values != nil { // const foo, bar = "same value" @@ -91,7 +93,7 @@ func (r *credentials) matchValueSpec(valueSpec *ast.ValueSpec, ctx *gosec.Contex } if val, err := gosec.GetString(valueSpec.Values[index]); err == nil { if r.ignoreEntropy || (!r.ignoreEntropy && r.isHighEntropyString(val)) { - return gosec.NewIssue(ctx, valueSpec, r.ID(), r.What, r.Severity, r.Confidence), nil + return ctx.NewIssue(valueSpec, r.ID(), r.What, r.Severity, r.Confidence), nil } } } @@ -99,7 +101,7 @@ func (r *credentials) matchValueSpec(valueSpec *ast.ValueSpec, ctx *gosec.Contex return nil, nil } -func (r *credentials) matchEqualityCheck(binaryExpr *ast.BinaryExpr, ctx *gosec.Context) (*gosec.Issue, error) { +func (r *credentials) matchEqualityCheck(binaryExpr *ast.BinaryExpr, ctx *gosec.Context) (*issue.Issue, error) { if binaryExpr.Op == token.EQL || binaryExpr.Op == token.NEQ { ident, ok := binaryExpr.X.(*ast.Ident) if !ok { @@ -113,7 +115,7 @@ func (r *credentials) matchEqualityCheck(binaryExpr *ast.BinaryExpr, ctx *gosec. } if val, err := gosec.GetString(valueNode); err == nil { if r.ignoreEntropy || (!r.ignoreEntropy && r.isHighEntropyString(val)) { - return gosec.NewIssue(ctx, binaryExpr, r.ID(), r.What, r.Severity, r.Confidence), nil + return ctx.NewIssue(binaryExpr, r.ID(), r.What, r.Severity, r.Confidence), nil } } } @@ -170,11 +172,11 @@ func NewHardcodedCredentials(id string, conf gosec.Config) (gosec.Rule, []ast.No perCharThreshold: perCharThreshold, ignoreEntropy: ignoreEntropy, truncate: truncateString, - MetaData: gosec.MetaData{ + MetaData: issue.MetaData{ ID: id, What: "Potential hardcoded credentials", - Confidence: gosec.Low, - Severity: gosec.High, + Confidence: issue.Low, + Severity: issue.High, }, }, []ast.Node{(*ast.AssignStmt)(nil), (*ast.ValueSpec)(nil), (*ast.BinaryExpr)(nil)} } diff --git a/vendor/github.com/securego/gosec/v2/rules/http_serve.go b/vendor/github.com/securego/gosec/v2/rules/http_serve.go index e460b3a68..525ed4ebc 100644 --- a/vendor/github.com/securego/gosec/v2/rules/http_serve.go +++ b/vendor/github.com/securego/gosec/v2/rules/http_serve.go @@ -4,10 +4,11 @@ import ( "go/ast" "github.com/securego/gosec/v2" + "github.com/securego/gosec/v2/issue" ) type httpServeWithoutTimeouts struct { - gosec.MetaData + issue.MetaData pkg string calls []string } @@ -16,23 +17,23 @@ func (r *httpServeWithoutTimeouts) ID() string { return r.MetaData.ID } -func (r *httpServeWithoutTimeouts) Match(n ast.Node, c *gosec.Context) (gi *gosec.Issue, err error) { +func (r *httpServeWithoutTimeouts) Match(n ast.Node, c *gosec.Context) (gi *issue.Issue, err error) { if _, matches := gosec.MatchCallByPackage(n, c, r.pkg, r.calls...); matches { - return gosec.NewIssue(c, n, r.ID(), r.What, r.Severity, r.Confidence), nil + return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil } return nil, nil } // NewHTTPServeWithoutTimeouts detects use of net/http serve functions that have no support for setting timeouts. -func NewHTTPServeWithoutTimeouts(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { +func NewHTTPServeWithoutTimeouts(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { return &httpServeWithoutTimeouts{ pkg: "net/http", calls: []string{"ListenAndServe", "ListenAndServeTLS", "Serve", "ServeTLS"}, - MetaData: gosec.MetaData{ + MetaData: issue.MetaData{ ID: id, What: "Use of net/http serve function that has no support for setting timeouts", - Severity: gosec.Medium, - Confidence: gosec.High, + Severity: issue.Medium, + Confidence: issue.High, }, }, []ast.Node{(*ast.CallExpr)(nil)} } diff --git a/vendor/github.com/securego/gosec/v2/rules/implicit_aliasing.go b/vendor/github.com/securego/gosec/v2/rules/implicit_aliasing.go index b2668dec8..70678e29a 100644 --- a/vendor/github.com/securego/gosec/v2/rules/implicit_aliasing.go +++ b/vendor/github.com/securego/gosec/v2/rules/implicit_aliasing.go @@ -5,10 +5,11 @@ import ( "go/token" "github.com/securego/gosec/v2" + "github.com/securego/gosec/v2/issue" ) type implicitAliasing struct { - gosec.MetaData + issue.MetaData aliases map[*ast.Object]struct{} rightBrace token.Pos acceptableAlias []*ast.UnaryExpr @@ -27,7 +28,7 @@ func containsUnary(exprs []*ast.UnaryExpr, expr *ast.UnaryExpr) bool { return false } -func (r *implicitAliasing) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { +func (r *implicitAliasing) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { switch node := n.(type) { case *ast.RangeStmt: // When presented with a range statement, get the underlying Object bound to @@ -73,7 +74,7 @@ func (r *implicitAliasing) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, er // If we find a unary op of & (reference) of an object within r.aliases, complain. if ident, ok := node.X.(*ast.Ident); ok && node.Op.String() == "&" { if _, contains := r.aliases[ident.Obj]; contains { - return gosec.NewIssue(c, n, r.ID(), r.What, r.Severity, r.Confidence), nil + return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil } } case *ast.ReturnStmt: @@ -89,15 +90,15 @@ func (r *implicitAliasing) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, er } // NewImplicitAliasing detects implicit memory aliasing of type: for blah := SomeCall() {... SomeOtherCall(&blah) ...} -func NewImplicitAliasing(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { +func NewImplicitAliasing(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { return &implicitAliasing{ aliases: make(map[*ast.Object]struct{}), rightBrace: token.NoPos, acceptableAlias: make([]*ast.UnaryExpr, 0), - MetaData: gosec.MetaData{ + MetaData: issue.MetaData{ ID: id, - Severity: gosec.Medium, - Confidence: gosec.Medium, + Severity: issue.Medium, + Confidence: issue.Medium, What: "Implicit memory aliasing in for loop.", }, }, []ast.Node{(*ast.RangeStmt)(nil), (*ast.UnaryExpr)(nil), (*ast.ReturnStmt)(nil)} diff --git a/vendor/github.com/securego/gosec/v2/rules/integer_overflow.go b/vendor/github.com/securego/gosec/v2/rules/integer_overflow.go index f55211a92..1d5790664 100644 --- a/vendor/github.com/securego/gosec/v2/rules/integer_overflow.go +++ b/vendor/github.com/securego/gosec/v2/rules/integer_overflow.go @@ -19,10 +19,11 @@ import ( "go/ast" "github.com/securego/gosec/v2" + "github.com/securego/gosec/v2/issue" ) type integerOverflowCheck struct { - gosec.MetaData + issue.MetaData calls gosec.CallList } @@ -30,7 +31,7 @@ func (i *integerOverflowCheck) ID() string { return i.MetaData.ID } -func (i *integerOverflowCheck) Match(node ast.Node, ctx *gosec.Context) (*gosec.Issue, error) { +func (i *integerOverflowCheck) Match(node ast.Node, ctx *gosec.Context) (*issue.Issue, error) { var atoiVarObj map[*ast.Object]ast.Node // To check multiple lines, ctx.PassedValues is used to store temporary data. @@ -63,7 +64,7 @@ func (i *integerOverflowCheck) Match(node ast.Node, ctx *gosec.Context) (*gosec. if idt, ok := n.Args[0].(*ast.Ident); ok { if _, ok := atoiVarObj[idt.Obj]; ok { // Detect int32(v) and int16(v) - return gosec.NewIssue(ctx, n, i.ID(), i.What, i.Severity, i.Confidence), nil + return ctx.NewIssue(n, i.ID(), i.What, i.Severity, i.Confidence), nil } } } @@ -74,14 +75,14 @@ func (i *integerOverflowCheck) Match(node ast.Node, ctx *gosec.Context) (*gosec. } // NewIntegerOverflowCheck detects if there is potential Integer OverFlow -func NewIntegerOverflowCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { +func NewIntegerOverflowCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { calls := gosec.NewCallList() calls.Add("strconv", "Atoi") return &integerOverflowCheck{ - MetaData: gosec.MetaData{ + MetaData: issue.MetaData{ ID: id, - Severity: gosec.High, - Confidence: gosec.Medium, + Severity: issue.High, + Confidence: issue.Medium, What: "Potential Integer overflow made by strconv.Atoi result conversion to int16/32", }, calls: calls, diff --git a/vendor/github.com/securego/gosec/v2/rules/math_big_rat.go b/vendor/github.com/securego/gosec/v2/rules/math_big_rat.go index 69037e18f..1aac1fa20 100644 --- a/vendor/github.com/securego/gosec/v2/rules/math_big_rat.go +++ b/vendor/github.com/securego/gosec/v2/rules/math_big_rat.go @@ -4,10 +4,11 @@ import ( "go/ast" "github.com/securego/gosec/v2" + "github.com/securego/gosec/v2/issue" ) type usingOldMathBig struct { - gosec.MetaData + issue.MetaData calls gosec.CallList } @@ -15,18 +16,18 @@ func (r *usingOldMathBig) ID() string { return r.MetaData.ID } -func (r *usingOldMathBig) Match(node ast.Node, ctx *gosec.Context) (gi *gosec.Issue, err error) { +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 := gosec.Low + confidence := issue.Low major, minor, build := gosec.GoVersion() if major == 1 && (minor == 16 && build < 14 || minor == 17 && build < 7) { - confidence = gosec.Medium + confidence = issue.Medium } - return gosec.NewIssue(ctx, node, r.ID(), r.What, r.Severity, confidence), nil + return ctx.NewIssue(node, r.ID(), r.What, r.Severity, confidence), nil } // NewUsingOldMathBig rule detects the use of Rat.SetString from math/big. @@ -35,10 +36,10 @@ func NewUsingOldMathBig(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { calls.Add("math/big.Rat", "SetString") return &usingOldMathBig{ calls: calls, - MetaData: gosec.MetaData{ + MetaData: issue.MetaData{ ID: id, What: "Potential uncontrolled memory consumption in Rat.SetString (CVE-2022-23772)", - Severity: gosec.High, + Severity: issue.High, }, }, []ast.Node{(*ast.CallExpr)(nil)} } diff --git a/vendor/github.com/securego/gosec/v2/rules/pprof.go b/vendor/github.com/securego/gosec/v2/rules/pprof.go index 4c99af752..68498dd5e 100644 --- a/vendor/github.com/securego/gosec/v2/rules/pprof.go +++ b/vendor/github.com/securego/gosec/v2/rules/pprof.go @@ -4,10 +4,11 @@ import ( "go/ast" "github.com/securego/gosec/v2" + "github.com/securego/gosec/v2/issue" ) type pprofCheck struct { - gosec.MetaData + issue.MetaData importPath string importName string } @@ -18,22 +19,22 @@ func (p *pprofCheck) ID() string { } // Match checks for pprof imports -func (p *pprofCheck) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { +func (p *pprofCheck) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { if node, ok := n.(*ast.ImportSpec); ok { if p.importPath == unquote(node.Path.Value) && node.Name != nil && p.importName == node.Name.Name { - return gosec.NewIssue(c, node, p.ID(), p.What, p.Severity, p.Confidence), nil + return c.NewIssue(node, p.ID(), p.What, p.Severity, p.Confidence), nil } } return nil, nil } // NewPprofCheck detects when the profiling endpoint is automatically exposed -func NewPprofCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { +func NewPprofCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { return &pprofCheck{ - MetaData: gosec.MetaData{ + MetaData: issue.MetaData{ ID: id, - Severity: gosec.High, - Confidence: gosec.High, + Severity: issue.High, + Confidence: issue.High, What: "Profiling endpoint is automatically exposed on /debug/pprof", }, importPath: "net/http/pprof", diff --git a/vendor/github.com/securego/gosec/v2/rules/rand.go b/vendor/github.com/securego/gosec/v2/rules/rand.go index 055adce4d..4491fd928 100644 --- a/vendor/github.com/securego/gosec/v2/rules/rand.go +++ b/vendor/github.com/securego/gosec/v2/rules/rand.go @@ -18,10 +18,11 @@ import ( "go/ast" "github.com/securego/gosec/v2" + "github.com/securego/gosec/v2/issue" ) type weakRand struct { - gosec.MetaData + issue.MetaData funcNames []string packagePath string } @@ -30,10 +31,10 @@ func (w *weakRand) ID() string { return w.MetaData.ID } -func (w *weakRand) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { +func (w *weakRand) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { for _, funcName := range w.funcNames { if _, matched := gosec.MatchCallByPackage(n, c, w.packagePath, funcName); matched { - return gosec.NewIssue(c, n, w.ID(), w.What, w.Severity, w.Confidence), nil + return c.NewIssue(n, w.ID(), w.What, w.Severity, w.Confidence), nil } } @@ -41,17 +42,17 @@ func (w *weakRand) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { } // NewWeakRandCheck detects the use of random number generator that isn't cryptographically secure -func NewWeakRandCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { +func NewWeakRandCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { return &weakRand{ funcNames: []string{ "New", "Read", "Float32", "Float64", "Int", "Int31", "Int31n", "Int63", "Int63n", "Intn", "NormalFloat64", "Uint32", "Uint64", }, packagePath: "math/rand", - MetaData: gosec.MetaData{ + MetaData: issue.MetaData{ ID: id, - Severity: gosec.High, - Confidence: gosec.Medium, + Severity: issue.High, + Confidence: issue.Medium, What: "Use of weak random number generator (math/rand instead of crypto/rand)", }, }, []ast.Node{(*ast.CallExpr)(nil)} diff --git a/vendor/github.com/securego/gosec/v2/rules/readfile.go b/vendor/github.com/securego/gosec/v2/rules/readfile.go index 8dcf05329..7ef4bbad1 100644 --- a/vendor/github.com/securego/gosec/v2/rules/readfile.go +++ b/vendor/github.com/securego/gosec/v2/rules/readfile.go @@ -19,10 +19,11 @@ import ( "go/types" "github.com/securego/gosec/v2" + "github.com/securego/gosec/v2/issue" ) type readfile struct { - gosec.MetaData + issue.MetaData gosec.CallList pathJoin gosec.CallList clean gosec.CallList @@ -80,13 +81,17 @@ func (r *readfile) isFilepathClean(n *ast.Ident, c *gosec.Context) bool { func (r *readfile) trackFilepathClean(n ast.Node) { if clean, ok := n.(*ast.CallExpr); ok && len(clean.Args) > 0 { if ident, ok := clean.Args[0].(*ast.Ident); ok { - r.cleanedVar[ident.Obj.Decl] = n + // ident.Obj may be nil if the referenced declaration is in another file. It also may be incorrect. + // if it is nil, do not follow it. + if ident.Obj != nil { + r.cleanedVar[ident.Obj.Decl] = n + } } } } // Match inspects AST nodes to determine if the match the methods `os.Open` or `ioutil.ReadFile` -func (r *readfile) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { +func (r *readfile) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { if node := r.clean.ContainsPkgCallExpr(n, c, false); node != nil { r.trackFilepathClean(n) return nil, nil @@ -96,14 +101,14 @@ func (r *readfile) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { // eg. os.Open(filepath.Join("/tmp/", file)) if callExpr, ok := arg.(*ast.CallExpr); ok { if r.isJoinFunc(callExpr, c) { - return gosec.NewIssue(c, n, r.ID(), r.What, r.Severity, r.Confidence), nil + return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil } } // handles binary string concatenation eg. ioutil.Readfile("/tmp/" + file + "/blob") if binExp, ok := arg.(*ast.BinaryExpr); ok { // resolve all found identities from the BinaryExpr if _, ok := gosec.FindVarIdentities(binExp, c); ok { - return gosec.NewIssue(c, n, r.ID(), r.What, r.Severity, r.Confidence), nil + return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil } } @@ -112,7 +117,7 @@ func (r *readfile) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { if _, ok := obj.(*types.Var); ok && !gosec.TryResolve(ident, c) && !r.isFilepathClean(ident, c) { - return gosec.NewIssue(c, n, r.ID(), r.What, r.Severity, r.Confidence), nil + return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil } } } @@ -121,16 +126,16 @@ func (r *readfile) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { } // NewReadFile detects cases where we read files -func NewReadFile(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { +func NewReadFile(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { rule := &readfile{ pathJoin: gosec.NewCallList(), clean: gosec.NewCallList(), CallList: gosec.NewCallList(), - MetaData: gosec.MetaData{ + MetaData: issue.MetaData{ ID: id, What: "Potential file inclusion via variable", - Severity: gosec.Medium, - Confidence: gosec.High, + Severity: issue.Medium, + Confidence: issue.High, }, cleanedVar: map[any]ast.Node{}, } diff --git a/vendor/github.com/securego/gosec/v2/rules/rsa.go b/vendor/github.com/securego/gosec/v2/rules/rsa.go index f2ed5db53..331e7fc80 100644 --- a/vendor/github.com/securego/gosec/v2/rules/rsa.go +++ b/vendor/github.com/securego/gosec/v2/rules/rsa.go @@ -19,10 +19,11 @@ import ( "go/ast" "github.com/securego/gosec/v2" + "github.com/securego/gosec/v2/issue" ) type weakKeyStrength struct { - gosec.MetaData + issue.MetaData calls gosec.CallList bits int } @@ -31,27 +32,27 @@ func (w *weakKeyStrength) ID() string { return w.MetaData.ID } -func (w *weakKeyStrength) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { +func (w *weakKeyStrength) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { if callExpr := w.calls.ContainsPkgCallExpr(n, c, false); callExpr != nil { if bits, err := gosec.GetInt(callExpr.Args[1]); err == nil && bits < (int64)(w.bits) { - return gosec.NewIssue(c, n, w.ID(), w.What, w.Severity, w.Confidence), nil + return c.NewIssue(n, w.ID(), w.What, w.Severity, w.Confidence), nil } } return nil, nil } // NewWeakKeyStrength builds a rule that detects RSA keys < 2048 bits -func NewWeakKeyStrength(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { +func NewWeakKeyStrength(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { calls := gosec.NewCallList() calls.Add("crypto/rsa", "GenerateKey") bits := 2048 return &weakKeyStrength{ calls: calls, bits: bits, - MetaData: gosec.MetaData{ + MetaData: issue.MetaData{ ID: id, - Severity: gosec.Medium, - Confidence: gosec.High, + Severity: issue.Medium, + Confidence: issue.High, What: fmt.Sprintf("RSA keys should be at least %d bits", bits), }, }, []ast.Node{(*ast.CallExpr)(nil)} diff --git a/vendor/github.com/securego/gosec/v2/rules/rulelist.go b/vendor/github.com/securego/gosec/v2/rules/rulelist.go index b97813ed0..d856eccad 100644 --- a/vendor/github.com/securego/gosec/v2/rules/rulelist.go +++ b/vendor/github.com/securego/gosec/v2/rules/rulelist.go @@ -91,7 +91,6 @@ func Generate(trackSuppressions bool, filters ...RuleFilter) RuleList { {"G304", "File path provided as taint input", NewReadFile}, {"G305", "File path traversal when extracting zip archive", NewArchive}, {"G306", "Poor file permissions used when writing to a file", NewWritePerms}, - {"G307", "Unsafe defer call of a method returning an error", NewDeferredClosing}, // crypto {"G401", "Detect the usage of DES, RC4, MD5 or SHA1", NewUsesWeakCryptography}, diff --git a/vendor/github.com/securego/gosec/v2/rules/slowloris.go b/vendor/github.com/securego/gosec/v2/rules/slowloris.go index 60b5e9521..70db73f5f 100644 --- a/vendor/github.com/securego/gosec/v2/rules/slowloris.go +++ b/vendor/github.com/securego/gosec/v2/rules/slowloris.go @@ -18,10 +18,11 @@ import ( "go/ast" "github.com/securego/gosec/v2" + "github.com/securego/gosec/v2/issue" ) type slowloris struct { - gosec.MetaData + issue.MetaData } func (r *slowloris) ID() string { @@ -44,13 +45,13 @@ func containsReadHeaderTimeout(node *ast.CompositeLit) bool { return false } -func (r *slowloris) Match(n ast.Node, ctx *gosec.Context) (*gosec.Issue, error) { +func (r *slowloris) Match(n ast.Node, ctx *gosec.Context) (*issue.Issue, error) { switch node := n.(type) { case *ast.CompositeLit: actualType := ctx.Info.TypeOf(node.Type) if actualType != nil && actualType.String() == "net/http.Server" { if !containsReadHeaderTimeout(node) { - return gosec.NewIssue(ctx, node, r.ID(), r.What, r.Severity, r.Confidence), nil + return ctx.NewIssue(node, r.ID(), r.What, r.Severity, r.Confidence), nil } } } @@ -58,13 +59,13 @@ func (r *slowloris) Match(n ast.Node, ctx *gosec.Context) (*gosec.Issue, error) } // NewSlowloris attempts to find the http.Server struct and check if the ReadHeaderTimeout is configured. -func NewSlowloris(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { +func NewSlowloris(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { return &slowloris{ - MetaData: gosec.MetaData{ + MetaData: issue.MetaData{ ID: id, What: "Potential Slowloris Attack because ReadHeaderTimeout is not configured in the http.Server", - Confidence: gosec.Low, - Severity: gosec.Medium, + Confidence: issue.Low, + Severity: issue.Medium, }, }, []ast.Node{(*ast.CompositeLit)(nil)} } diff --git a/vendor/github.com/securego/gosec/v2/rules/sql.go b/vendor/github.com/securego/gosec/v2/rules/sql.go index ee99737d6..4085b5d26 100644 --- a/vendor/github.com/securego/gosec/v2/rules/sql.go +++ b/vendor/github.com/securego/gosec/v2/rules/sql.go @@ -20,10 +20,11 @@ import ( "regexp" "github.com/securego/gosec/v2" + "github.com/securego/gosec/v2/issue" ) type sqlStatement struct { - gosec.MetaData + issue.MetaData gosec.CallList // Contains a list of patterns which must all match for the rule to match. @@ -113,7 +114,7 @@ func (s *sqlStrConcat) checkObject(n *ast.Ident, c *gosec.Context) bool { } // checkQuery verifies if the query parameters is a string concatenation -func (s *sqlStrConcat) checkQuery(call *ast.CallExpr, ctx *gosec.Context) (*gosec.Issue, error) { +func (s *sqlStrConcat) checkQuery(call *ast.CallExpr, ctx *gosec.Context) (*issue.Issue, error) { query, err := findQueryArg(call, ctx) if err != nil { return nil, err @@ -134,7 +135,7 @@ func (s *sqlStrConcat) checkQuery(call *ast.CallExpr, ctx *gosec.Context) (*gose if op, ok := op.(*ast.Ident); ok && s.checkObject(op, ctx) { continue } - return gosec.NewIssue(ctx, be, s.ID(), s.What, s.Severity, s.Confidence), nil + return ctx.NewIssue(be, s.ID(), s.What, s.Severity, s.Confidence), nil } } } @@ -143,7 +144,7 @@ func (s *sqlStrConcat) checkQuery(call *ast.CallExpr, ctx *gosec.Context) (*gose } // Checks SQL query concatenation issues such as "SELECT * FROM table WHERE " + " ' OR 1=1" -func (s *sqlStrConcat) Match(n ast.Node, ctx *gosec.Context) (*gosec.Issue, error) { +func (s *sqlStrConcat) Match(n ast.Node, ctx *gosec.Context) (*issue.Issue, error) { switch stmt := n.(type) { case *ast.AssignStmt: for _, expr := range stmt.Rhs { @@ -160,16 +161,16 @@ func (s *sqlStrConcat) Match(n ast.Node, ctx *gosec.Context) (*gosec.Issue, erro } // NewSQLStrConcat looks for cases where we are building SQL strings via concatenation -func NewSQLStrConcat(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { +func NewSQLStrConcat(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { rule := &sqlStrConcat{ sqlStatement: sqlStatement{ patterns: []*regexp.Regexp{ regexp.MustCompile(`(?i)(SELECT|DELETE|INSERT|UPDATE|INTO|FROM|WHERE) `), }, - MetaData: gosec.MetaData{ + MetaData: issue.MetaData{ ID: id, - Severity: gosec.Medium, - Confidence: gosec.High, + Severity: issue.Medium, + Confidence: issue.High, What: "SQL string concatenation", }, CallList: gosec.NewCallList(), @@ -212,7 +213,7 @@ func (s *sqlStrFormat) constObject(e ast.Expr, c *gosec.Context) bool { return false } -func (s *sqlStrFormat) checkQuery(call *ast.CallExpr, ctx *gosec.Context) (*gosec.Issue, error) { +func (s *sqlStrFormat) checkQuery(call *ast.CallExpr, ctx *gosec.Context) (*issue.Issue, error) { query, err := findQueryArg(call, ctx) if err != nil { return nil, err @@ -233,7 +234,7 @@ func (s *sqlStrFormat) checkQuery(call *ast.CallExpr, ctx *gosec.Context) (*gose return nil, nil } -func (s *sqlStrFormat) checkFormatting(n ast.Node, ctx *gosec.Context) *gosec.Issue { +func (s *sqlStrFormat) checkFormatting(n ast.Node, ctx *gosec.Context) *issue.Issue { // argIndex changes the function argument which gets matched to the regex argIndex := 0 if node := s.fmtCalls.ContainsPkgCallExpr(n, ctx, false); node != nil { @@ -286,14 +287,14 @@ func (s *sqlStrFormat) checkFormatting(n ast.Node, ctx *gosec.Context) *gosec.Is } } if s.MatchPatterns(formatter) { - return gosec.NewIssue(ctx, n, s.ID(), s.What, s.Severity, s.Confidence) + return ctx.NewIssue(n, s.ID(), s.What, s.Severity, s.Confidence) } } return nil } // Check SQL query formatting issues such as "fmt.Sprintf("SELECT * FROM foo where '%s', userInput)" -func (s *sqlStrFormat) Match(n ast.Node, ctx *gosec.Context) (*gosec.Issue, error) { +func (s *sqlStrFormat) Match(n ast.Node, ctx *gosec.Context) (*issue.Issue, error) { switch stmt := n.(type) { case *ast.AssignStmt: for _, expr := range stmt.Rhs { @@ -323,7 +324,7 @@ func (s *sqlStrFormat) Match(n ast.Node, ctx *gosec.Context) (*gosec.Issue, erro } // NewSQLStrFormat looks for cases where we're building SQL query strings using format strings -func NewSQLStrFormat(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { +func NewSQLStrFormat(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { rule := &sqlStrFormat{ CallList: gosec.NewCallList(), fmtCalls: gosec.NewCallList(), @@ -334,10 +335,10 @@ func NewSQLStrFormat(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { regexp.MustCompile("(?i)(SELECT|DELETE|INSERT|UPDATE|INTO|FROM|WHERE)( |\n|\r|\t)"), regexp.MustCompile("%[^bdoxXfFp]"), }, - MetaData: gosec.MetaData{ + MetaData: issue.MetaData{ ID: id, - Severity: gosec.Medium, - Confidence: gosec.High, + Severity: issue.Medium, + Confidence: issue.High, What: "SQL string formatting", }, }, diff --git a/vendor/github.com/securego/gosec/v2/rules/ssh.go b/vendor/github.com/securego/gosec/v2/rules/ssh.go index 01f37da51..e2ba5a3f4 100644 --- a/vendor/github.com/securego/gosec/v2/rules/ssh.go +++ b/vendor/github.com/securego/gosec/v2/rules/ssh.go @@ -4,10 +4,11 @@ import ( "go/ast" "github.com/securego/gosec/v2" + "github.com/securego/gosec/v2/issue" ) type sshHostKey struct { - gosec.MetaData + issue.MetaData pkg string calls []string } @@ -16,23 +17,23 @@ func (r *sshHostKey) ID() string { return r.MetaData.ID } -func (r *sshHostKey) Match(n ast.Node, c *gosec.Context) (gi *gosec.Issue, err error) { +func (r *sshHostKey) Match(n ast.Node, c *gosec.Context) (gi *issue.Issue, err error) { if _, matches := gosec.MatchCallByPackage(n, c, r.pkg, r.calls...); matches { - return gosec.NewIssue(c, n, r.ID(), r.What, r.Severity, r.Confidence), nil + return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil } return nil, nil } // NewSSHHostKey rule detects the use of insecure ssh HostKeyCallback. -func NewSSHHostKey(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { +func NewSSHHostKey(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { return &sshHostKey{ pkg: "golang.org/x/crypto/ssh", calls: []string{"InsecureIgnoreHostKey"}, - MetaData: gosec.MetaData{ + MetaData: issue.MetaData{ ID: id, What: "Use of ssh InsecureIgnoreHostKey should be audited", - Severity: gosec.Medium, - Confidence: gosec.High, + Severity: issue.Medium, + Confidence: issue.High, }, }, []ast.Node{(*ast.CallExpr)(nil)} } diff --git a/vendor/github.com/securego/gosec/v2/rules/ssrf.go b/vendor/github.com/securego/gosec/v2/rules/ssrf.go index 86bb8278d..dbf01081b 100644 --- a/vendor/github.com/securego/gosec/v2/rules/ssrf.go +++ b/vendor/github.com/securego/gosec/v2/rules/ssrf.go @@ -5,10 +5,11 @@ import ( "go/types" "github.com/securego/gosec/v2" + "github.com/securego/gosec/v2/issue" ) type ssrf struct { - gosec.MetaData + issue.MetaData gosec.CallList } @@ -40,25 +41,25 @@ func (r *ssrf) ResolveVar(n *ast.CallExpr, c *gosec.Context) bool { } // Match inspects AST nodes to determine if certain net/http methods are called with variable input -func (r *ssrf) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { +func (r *ssrf) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { // Call expression is using http package directly if node := r.ContainsPkgCallExpr(n, c, false); node != nil { if r.ResolveVar(node, c) { - return gosec.NewIssue(c, n, r.ID(), r.What, r.Severity, r.Confidence), nil + return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil } } return nil, nil } // NewSSRFCheck detects cases where HTTP requests are sent -func NewSSRFCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { +func NewSSRFCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { rule := &ssrf{ CallList: gosec.NewCallList(), - MetaData: gosec.MetaData{ + MetaData: issue.MetaData{ ID: id, What: "Potential HTTP request made with variable url", - Severity: gosec.Medium, - Confidence: gosec.Medium, + Severity: issue.Medium, + Confidence: issue.Medium, }, } rule.AddAll("net/http", "Do", "Get", "Head", "Post", "PostForm", "RoundTrip") diff --git a/vendor/github.com/securego/gosec/v2/rules/subproc.go b/vendor/github.com/securego/gosec/v2/rules/subproc.go index 2b6cb186c..ea50d692d 100644 --- a/vendor/github.com/securego/gosec/v2/rules/subproc.go +++ b/vendor/github.com/securego/gosec/v2/rules/subproc.go @@ -19,10 +19,11 @@ import ( "go/types" "github.com/securego/gosec/v2" + "github.com/securego/gosec/v2/issue" ) type subprocess struct { - gosec.MetaData + issue.MetaData gosec.CallList } @@ -39,7 +40,7 @@ func (r *subprocess) ID() string { // is unsafe. For example: // // syscall.Exec("echo", "foobar" + tainted) -func (r *subprocess) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { +func (r *subprocess) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { if node := r.ContainsPkgCallExpr(n, c, false); node != nil { args := node.Args if r.isContext(n, c) { @@ -64,7 +65,7 @@ func (r *subprocess) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { _, assignment := ident.Obj.Decl.(*ast.AssignStmt) if variable && assignment { if !gosec.TryResolve(ident, c) { - return gosec.NewIssue(c, n, r.ID(), "Subprocess launched with variable", gosec.Medium, gosec.High), nil + return c.NewIssue(n, r.ID(), "Subprocess launched with variable", issue.Medium, issue.High), nil } } case *ast.Field: @@ -74,21 +75,21 @@ func (r *subprocess) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { vv, vvok := obj.(*types.Var) if vvok && vv.Parent().Lookup(ident.Name) == nil { - return gosec.NewIssue(c, n, r.ID(), "Subprocess launched with variable", gosec.Medium, gosec.High), nil + return c.NewIssue(n, r.ID(), "Subprocess launched with variable", issue.Medium, issue.High), nil } } case *ast.ValueSpec: _, valueSpec := ident.Obj.Decl.(*ast.ValueSpec) if variable && valueSpec { if !gosec.TryResolve(ident, c) { - return gosec.NewIssue(c, n, r.ID(), "Subprocess launched with variable", gosec.Medium, gosec.High), nil + return c.NewIssue(n, r.ID(), "Subprocess launched with variable", issue.Medium, issue.High), nil } } } } } else if !gosec.TryResolve(arg, c) { // the arg is not a constant or a variable but instead a function call or os.Args[i] - return gosec.NewIssue(c, n, r.ID(), "Subprocess launched with a potential tainted input or cmd arguments", gosec.Medium, gosec.High), nil + return c.NewIssue(n, r.ID(), "Subprocess launched with a potential tainted input or cmd arguments", issue.Medium, issue.High), nil } } } @@ -109,8 +110,8 @@ func (r *subprocess) isContext(n ast.Node, ctx *gosec.Context) bool { } // NewSubproc detects cases where we are forking out to an external process -func NewSubproc(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { - rule := &subprocess{gosec.MetaData{ID: id}, gosec.NewCallList()} +func NewSubproc(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { + rule := &subprocess{issue.MetaData{ID: id}, gosec.NewCallList()} rule.Add("os/exec", "Command") rule.Add("os/exec", "CommandContext") rule.Add("syscall", "Exec") diff --git a/vendor/github.com/securego/gosec/v2/rules/tempfiles.go b/vendor/github.com/securego/gosec/v2/rules/tempfiles.go index 63822c093..6fef52a2c 100644 --- a/vendor/github.com/securego/gosec/v2/rules/tempfiles.go +++ b/vendor/github.com/securego/gosec/v2/rules/tempfiles.go @@ -19,10 +19,11 @@ import ( "regexp" "github.com/securego/gosec/v2" + "github.com/securego/gosec/v2/issue" ) type badTempFile struct { - gosec.MetaData + issue.MetaData calls gosec.CallList args *regexp.Regexp argCalls gosec.CallList @@ -33,15 +34,15 @@ func (t *badTempFile) ID() string { return t.MetaData.ID } -func (t *badTempFile) findTempDirArgs(n ast.Node, c *gosec.Context, suspect ast.Node) *gosec.Issue { +func (t *badTempFile) findTempDirArgs(n ast.Node, c *gosec.Context, suspect ast.Node) *issue.Issue { if s, e := gosec.GetString(suspect); e == nil { if t.args.MatchString(s) { - return gosec.NewIssue(c, n, t.ID(), t.What, t.Severity, t.Confidence) + return c.NewIssue(n, t.ID(), t.What, t.Severity, t.Confidence) } return nil } if ce := t.argCalls.ContainsPkgCallExpr(suspect, c, false); ce != nil { - return gosec.NewIssue(c, n, t.ID(), t.What, t.Severity, t.Confidence) + return c.NewIssue(n, t.ID(), t.What, t.Severity, t.Confidence) } if be, ok := suspect.(*ast.BinaryExpr); ok { if ops := gosec.GetBinaryExprOperands(be); len(ops) != 0 { @@ -55,7 +56,7 @@ func (t *badTempFile) findTempDirArgs(n ast.Node, c *gosec.Context, suspect ast. return nil } -func (t *badTempFile) Match(n ast.Node, c *gosec.Context) (gi *gosec.Issue, err error) { +func (t *badTempFile) Match(n ast.Node, c *gosec.Context) (gi *issue.Issue, err error) { if node := t.calls.ContainsPkgCallExpr(n, c, false); node != nil { return t.findTempDirArgs(n, c, node.Args[0]), nil } @@ -63,7 +64,7 @@ func (t *badTempFile) Match(n ast.Node, c *gosec.Context) (gi *gosec.Issue, err } // NewBadTempFile detects direct writes to predictable path in temporary directory -func NewBadTempFile(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { +func NewBadTempFile(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { calls := gosec.NewCallList() calls.Add("io/ioutil", "WriteFile") calls.AddAll("os", "Create", "WriteFile") @@ -77,10 +78,10 @@ func NewBadTempFile(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { args: regexp.MustCompile(`^(/(usr|var))?/tmp(/.*)?$`), argCalls: argCalls, nestedCalls: nestedCalls, - MetaData: gosec.MetaData{ + MetaData: issue.MetaData{ ID: id, - Severity: gosec.Medium, - Confidence: gosec.High, + Severity: issue.Medium, + Confidence: issue.High, What: "File creation in shared tmp directory without using ioutil.Tempfile", }, }, []ast.Node{(*ast.CallExpr)(nil)} diff --git a/vendor/github.com/securego/gosec/v2/rules/templates.go b/vendor/github.com/securego/gosec/v2/rules/templates.go index 1eec7fba1..728766f45 100644 --- a/vendor/github.com/securego/gosec/v2/rules/templates.go +++ b/vendor/github.com/securego/gosec/v2/rules/templates.go @@ -18,10 +18,11 @@ import ( "go/ast" "github.com/securego/gosec/v2" + "github.com/securego/gosec/v2/issue" ) type templateCheck struct { - gosec.MetaData + issue.MetaData calls gosec.CallList } @@ -29,11 +30,11 @@ func (t *templateCheck) ID() string { return t.MetaData.ID } -func (t *templateCheck) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { +func (t *templateCheck) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { if node := t.calls.ContainsPkgCallExpr(n, c, false); node != nil { for _, arg := range node.Args { if _, ok := arg.(*ast.BasicLit); !ok { // basic lits are safe - return gosec.NewIssue(c, n, t.ID(), t.What, t.Severity, t.Confidence), nil + return c.NewIssue(n, t.ID(), t.What, t.Severity, t.Confidence), nil } } } @@ -42,7 +43,7 @@ func (t *templateCheck) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error // NewTemplateCheck constructs the template check rule. This rule is used to // find use of templates where HTML/JS escaping is not being used -func NewTemplateCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { +func NewTemplateCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { calls := gosec.NewCallList() calls.Add("html/template", "HTML") calls.Add("html/template", "HTMLAttr") @@ -50,10 +51,10 @@ func NewTemplateCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { calls.Add("html/template", "URL") return &templateCheck{ calls: calls, - MetaData: gosec.MetaData{ + MetaData: issue.MetaData{ ID: id, - Severity: gosec.Medium, - Confidence: gosec.Low, + Severity: issue.Medium, + Confidence: issue.Low, What: "The used method does not auto-escape HTML. This can potentially lead to 'Cross-site Scripting' vulnerabilities, in case the attacker controls the input.", }, }, []ast.Node{(*ast.CallExpr)(nil)} diff --git a/vendor/github.com/securego/gosec/v2/rules/tls.go b/vendor/github.com/securego/gosec/v2/rules/tls.go index 1cc3a298f..65a0b5a33 100644 --- a/vendor/github.com/securego/gosec/v2/rules/tls.go +++ b/vendor/github.com/securego/gosec/v2/rules/tls.go @@ -24,10 +24,11 @@ import ( "strconv" "github.com/securego/gosec/v2" + "github.com/securego/gosec/v2/issue" ) type insecureConfigTLS struct { - gosec.MetaData + issue.MetaData MinVersion int64 MaxVersion int64 requiredType string @@ -49,13 +50,13 @@ func stringInSlice(a string, list []string) bool { return false } -func (t *insecureConfigTLS) processTLSCipherSuites(n ast.Node, c *gosec.Context) *gosec.Issue { +func (t *insecureConfigTLS) processTLSCipherSuites(n ast.Node, c *gosec.Context) *issue.Issue { if ciphers, ok := n.(*ast.CompositeLit); ok { for _, cipher := range ciphers.Elts { if ident, ok := cipher.(*ast.SelectorExpr); ok { if !stringInSlice(ident.Sel.Name, t.goodCiphers) { err := fmt.Sprintf("TLS Bad Cipher Suite: %s", ident.Sel.Name) - return gosec.NewIssue(c, ident, t.ID(), err, gosec.High, gosec.High) + return c.NewIssue(ident, t.ID(), err, issue.High, issue.High) } } } @@ -63,7 +64,7 @@ func (t *insecureConfigTLS) processTLSCipherSuites(n ast.Node, c *gosec.Context) return nil } -func (t *insecureConfigTLS) processTLSConf(n ast.Node, c *gosec.Context) *gosec.Issue { +func (t *insecureConfigTLS) processTLSConf(n ast.Node, c *gosec.Context) *issue.Issue { if kve, ok := n.(*ast.KeyValueExpr); ok { issue := t.processTLSConfVal(kve.Key, kve.Value, c) if issue != nil { @@ -83,27 +84,27 @@ func (t *insecureConfigTLS) processTLSConf(n ast.Node, c *gosec.Context) *gosec. return nil } -func (t *insecureConfigTLS) processTLSConfVal(key ast.Expr, value ast.Expr, c *gosec.Context) *gosec.Issue { +func (t *insecureConfigTLS) processTLSConfVal(key ast.Expr, value ast.Expr, c *gosec.Context) *issue.Issue { if ident, ok := key.(*ast.Ident); ok { switch ident.Name { case "InsecureSkipVerify": if node, ok := value.(*ast.Ident); ok { if node.Name != "false" { - return gosec.NewIssue(c, value, t.ID(), "TLS InsecureSkipVerify set true.", gosec.High, gosec.High) + return c.NewIssue(value, t.ID(), "TLS InsecureSkipVerify set true.", issue.High, issue.High) } } else { // TODO(tk): symbol tab look up to get the actual value - return gosec.NewIssue(c, value, t.ID(), "TLS InsecureSkipVerify may be true.", gosec.High, gosec.Low) + return c.NewIssue(value, t.ID(), "TLS InsecureSkipVerify may be true.", issue.High, issue.Low) } case "PreferServerCipherSuites": if node, ok := value.(*ast.Ident); ok { if node.Name == "false" { - return gosec.NewIssue(c, value, t.ID(), "TLS PreferServerCipherSuites set false.", gosec.Medium, gosec.High) + return c.NewIssue(value, t.ID(), "TLS PreferServerCipherSuites set false.", issue.Medium, issue.High) } } else { // TODO(tk): symbol tab look up to get the actual value - return gosec.NewIssue(c, value, t.ID(), "TLS PreferServerCipherSuites may be false.", gosec.Medium, gosec.Low) + return c.NewIssue(value, t.ID(), "TLS PreferServerCipherSuites may be false.", issue.Medium, issue.Low) } case "MinVersion": @@ -188,16 +189,16 @@ func (t *insecureConfigTLS) mapVersion(version string) int64 { return v } -func (t *insecureConfigTLS) checkVersion(n ast.Node, c *gosec.Context) *gosec.Issue { +func (t *insecureConfigTLS) checkVersion(n ast.Node, c *gosec.Context) *issue.Issue { if t.actualMaxVersion == 0 && t.actualMinVersion >= t.MinVersion { // no warning is generated since the min version is greater than the secure min version return nil } if t.actualMinVersion < t.MinVersion { - return gosec.NewIssue(c, n, t.ID(), "TLS MinVersion too low.", gosec.High, gosec.High) + return c.NewIssue(n, t.ID(), "TLS MinVersion too low.", issue.High, issue.High) } if t.actualMaxVersion < t.MaxVersion { - return gosec.NewIssue(c, n, t.ID(), "TLS MaxVersion too low.", gosec.High, gosec.High) + return c.NewIssue(n, t.ID(), "TLS MaxVersion too low.", issue.High, issue.High) } return nil } @@ -207,7 +208,7 @@ func (t *insecureConfigTLS) resetVersion() { t.actualMinVersion = 0 } -func (t *insecureConfigTLS) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { +func (t *insecureConfigTLS) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { if complit, ok := n.(*ast.CompositeLit); ok && complit.Type != nil { actualType := c.Info.TypeOf(complit.Type) if actualType != nil && actualType.String() == t.requiredType { diff --git a/vendor/github.com/securego/gosec/v2/rules/tls_config.go b/vendor/github.com/securego/gosec/v2/rules/tls_config.go index 9bb17c243..cbbdf7983 100644 --- a/vendor/github.com/securego/gosec/v2/rules/tls_config.go +++ b/vendor/github.com/securego/gosec/v2/rules/tls_config.go @@ -4,13 +4,14 @@ import ( "go/ast" "github.com/securego/gosec/v2" + "github.com/securego/gosec/v2/issue" ) // NewModernTLSCheck creates a check for Modern TLS ciphers // DO NOT EDIT - generated by tlsconfig tool -func NewModernTLSCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { +func NewModernTLSCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { return &insecureConfigTLS{ - MetaData: gosec.MetaData{ID: id}, + MetaData: issue.MetaData{ID: id}, requiredType: "crypto/tls.Config", MinVersion: 0x0304, MaxVersion: 0x0304, @@ -24,9 +25,9 @@ func NewModernTLSCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { // NewIntermediateTLSCheck creates a check for Intermediate TLS ciphers // DO NOT EDIT - generated by tlsconfig tool -func NewIntermediateTLSCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { +func NewIntermediateTLSCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { return &insecureConfigTLS{ - MetaData: gosec.MetaData{ID: id}, + MetaData: issue.MetaData{ID: id}, requiredType: "crypto/tls.Config", MinVersion: 0x0303, MaxVersion: 0x0304, @@ -50,9 +51,9 @@ func NewIntermediateTLSCheck(id string, conf gosec.Config) (gosec.Rule, []ast.No // NewOldTLSCheck creates a check for Old TLS ciphers // DO NOT EDIT - generated by tlsconfig tool -func NewOldTLSCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { +func NewOldTLSCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { return &insecureConfigTLS{ - MetaData: gosec.MetaData{ID: id}, + MetaData: issue.MetaData{ID: id}, requiredType: "crypto/tls.Config", MinVersion: 0x0301, MaxVersion: 0x0304, diff --git a/vendor/github.com/securego/gosec/v2/rules/unsafe.go b/vendor/github.com/securego/gosec/v2/rules/unsafe.go index 88a298fb5..e1e8d0231 100644 --- a/vendor/github.com/securego/gosec/v2/rules/unsafe.go +++ b/vendor/github.com/securego/gosec/v2/rules/unsafe.go @@ -18,10 +18,11 @@ import ( "go/ast" "github.com/securego/gosec/v2" + "github.com/securego/gosec/v2/issue" ) type usingUnsafe struct { - gosec.MetaData + issue.MetaData pkg string calls []string } @@ -30,24 +31,24 @@ func (r *usingUnsafe) ID() string { return r.MetaData.ID } -func (r *usingUnsafe) Match(n ast.Node, c *gosec.Context) (gi *gosec.Issue, err error) { +func (r *usingUnsafe) Match(n ast.Node, c *gosec.Context) (gi *issue.Issue, err error) { if _, matches := gosec.MatchCallByPackage(n, c, r.pkg, r.calls...); matches { - return gosec.NewIssue(c, n, r.ID(), r.What, r.Severity, r.Confidence), nil + return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil } return nil, nil } // NewUsingUnsafe rule detects the use of the unsafe package. This is only // really useful for auditing purposes. -func NewUsingUnsafe(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { +func NewUsingUnsafe(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { return &usingUnsafe{ pkg: "unsafe", calls: []string{"Alignof", "Offsetof", "Sizeof", "Pointer"}, - MetaData: gosec.MetaData{ + MetaData: issue.MetaData{ ID: id, What: "Use of unsafe calls should be audited", - Severity: gosec.Low, - Confidence: gosec.High, + Severity: issue.Low, + Confidence: issue.High, }, }, []ast.Node{(*ast.CallExpr)(nil)} } diff --git a/vendor/github.com/securego/gosec/v2/rules/weakcrypto.go b/vendor/github.com/securego/gosec/v2/rules/weakcrypto.go index eecb88f04..4f2ab11d1 100644 --- a/vendor/github.com/securego/gosec/v2/rules/weakcrypto.go +++ b/vendor/github.com/securego/gosec/v2/rules/weakcrypto.go @@ -18,10 +18,11 @@ import ( "go/ast" "github.com/securego/gosec/v2" + "github.com/securego/gosec/v2/issue" ) type usesWeakCryptography struct { - gosec.MetaData + issue.MetaData blocklist map[string][]string } @@ -29,17 +30,17 @@ func (r *usesWeakCryptography) ID() string { return r.MetaData.ID } -func (r *usesWeakCryptography) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) { +func (r *usesWeakCryptography) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { for pkg, funcs := range r.blocklist { if _, matched := gosec.MatchCallByPackage(n, c, pkg, funcs...); matched { - return gosec.NewIssue(c, n, r.ID(), r.What, r.Severity, r.Confidence), nil + return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil } } return nil, nil } // NewUsesWeakCryptography detects uses of des.* md5.* or rc4.* -func NewUsesWeakCryptography(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { +func NewUsesWeakCryptography(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { calls := make(map[string][]string) calls["crypto/des"] = []string{"NewCipher", "NewTripleDESCipher"} calls["crypto/md5"] = []string{"New", "Sum"} @@ -47,10 +48,10 @@ func NewUsesWeakCryptography(id string, conf gosec.Config) (gosec.Rule, []ast.No calls["crypto/rc4"] = []string{"NewCipher"} rule := &usesWeakCryptography{ blocklist: calls, - MetaData: gosec.MetaData{ + MetaData: issue.MetaData{ ID: id, - Severity: gosec.Medium, - Confidence: gosec.High, + Severity: issue.Medium, + Confidence: issue.High, What: "Use of weak cryptographic primitive", }, } |
