mirror of
https://github.com/securego/gosec.git
synced 2024-11-05 11:35:51 +00:00
Allow excluding analyzers globally (#1180)
* This change does not exclude analyzers for inline comment * Changed the expected issues count for G103, G109 samples for test. Previously G115 has been included in the issue count * Show analyzers IDs(G115, G602) in gosec usage help * See #1175
This commit is contained in:
parent
18135b439c
commit
81cda2f91f
11 changed files with 301 additions and 26 deletions
18
analyzer.go
18
analyzer.go
|
@ -182,7 +182,7 @@ type Analyzer struct {
|
||||||
showIgnored bool
|
showIgnored bool
|
||||||
trackSuppressions bool
|
trackSuppressions bool
|
||||||
concurrency int
|
concurrency int
|
||||||
analyzerList []*analysis.Analyzer
|
analyzerSet *analyzers.AnalyzerSet
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,7 +213,7 @@ func NewAnalyzer(conf Config, tests bool, excludeGenerated bool, trackSuppressio
|
||||||
concurrency: concurrency,
|
concurrency: concurrency,
|
||||||
excludeGenerated: excludeGenerated,
|
excludeGenerated: excludeGenerated,
|
||||||
trackSuppressions: trackSuppressions,
|
trackSuppressions: trackSuppressions,
|
||||||
analyzerList: analyzers.BuildDefaultAnalyzers(),
|
analyzerSet: analyzers.NewAnalyzerSet(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,6 +236,15 @@ func (gosec *Analyzer) LoadRules(ruleDefinitions map[string]RuleBuilder, ruleSup
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LoadAnalyzers instantiates all the analyzers to be used when analyzing source
|
||||||
|
// packages
|
||||||
|
func (gosec *Analyzer) LoadAnalyzers(analyzerDefinitions map[string]analyzers.AnalyzerDefinition, analyzerSuppressed map[string]bool) {
|
||||||
|
for id, def := range analyzerDefinitions {
|
||||||
|
r := def.Create(def.ID, def.Description)
|
||||||
|
gosec.analyzerSet.Register(r, analyzerSuppressed[id])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Process kicks off the analysis process for a given package
|
// Process kicks off the analysis process for a given package
|
||||||
func (gosec *Analyzer) Process(buildTags []string, packagePaths ...string) error {
|
func (gosec *Analyzer) Process(buildTags []string, packagePaths ...string) error {
|
||||||
config := &packages.Config{
|
config := &packages.Config{
|
||||||
|
@ -415,7 +424,7 @@ func (gosec *Analyzer) CheckAnalyzers(pkg *packages.Package) {
|
||||||
|
|
||||||
generatedFiles := gosec.generatedFiles(pkg)
|
generatedFiles := gosec.generatedFiles(pkg)
|
||||||
|
|
||||||
for _, analyzer := range gosec.analyzerList {
|
for _, analyzer := range gosec.analyzerSet.Analyzers {
|
||||||
pass := &analysis.Pass{
|
pass := &analysis.Pass{
|
||||||
Analyzer: analyzer,
|
Analyzer: analyzer,
|
||||||
Fset: pkg.Fset,
|
Fset: pkg.Fset,
|
||||||
|
@ -666,7 +675,7 @@ func (gosec *Analyzer) getSuppressionsAtLineInFile(file string, line string, id
|
||||||
suppressions := append(generalSuppressions, ruleSuppressions...)
|
suppressions := append(generalSuppressions, ruleSuppressions...)
|
||||||
|
|
||||||
// Track external suppressions of this rule.
|
// Track external suppressions of this rule.
|
||||||
if gosec.ruleset.IsRuleSuppressed(id) {
|
if gosec.ruleset.IsRuleSuppressed(id) || gosec.analyzerSet.IsSuppressed(id) {
|
||||||
ignored = true
|
ignored = true
|
||||||
suppressions = append(suppressions, issue.SuppressionInfo{
|
suppressions = append(suppressions, issue.SuppressionInfo{
|
||||||
Kind: "external",
|
Kind: "external",
|
||||||
|
@ -705,4 +714,5 @@ func (gosec *Analyzer) Reset() {
|
||||||
gosec.issues = make([]*issue.Issue, 0, 16)
|
gosec.issues = make([]*issue.Issue, 0, 16)
|
||||||
gosec.stats = &Metrics{}
|
gosec.stats = &Metrics{}
|
||||||
gosec.ruleset = NewRuleSet()
|
gosec.ruleset = NewRuleSet()
|
||||||
|
gosec.analyzerSet = analyzers.NewAnalyzerSet()
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import (
|
||||||
. "github.com/onsi/ginkgo/v2"
|
. "github.com/onsi/ginkgo/v2"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
"github.com/securego/gosec/v2"
|
"github.com/securego/gosec/v2"
|
||||||
|
"github.com/securego/gosec/v2/analyzers"
|
||||||
"github.com/securego/gosec/v2/rules"
|
"github.com/securego/gosec/v2/rules"
|
||||||
"github.com/securego/gosec/v2/testutils"
|
"github.com/securego/gosec/v2/testutils"
|
||||||
"golang.org/x/tools/go/packages"
|
"golang.org/x/tools/go/packages"
|
||||||
|
@ -1110,6 +1111,7 @@ var _ = Describe("Analyzer", func() {
|
||||||
It("should be able to scan generated files if NOT excluded when using the analyzes", func() {
|
It("should be able to scan generated files if NOT excluded when using the analyzes", func() {
|
||||||
customAnalyzer := gosec.NewAnalyzer(nil, true, false, false, 1, logger)
|
customAnalyzer := gosec.NewAnalyzer(nil, true, false, false, 1, logger)
|
||||||
customAnalyzer.LoadRules(rules.Generate(false).RulesInfo())
|
customAnalyzer.LoadRules(rules.Generate(false).RulesInfo())
|
||||||
|
customAnalyzer.LoadAnalyzers(analyzers.Generate(false).AnalyzersInfo())
|
||||||
pkg := testutils.NewTestPackage()
|
pkg := testutils.NewTestPackage()
|
||||||
defer pkg.Close()
|
defer pkg.Close()
|
||||||
pkg.AddFile("foo.go", `
|
pkg.AddFile("foo.go", `
|
||||||
|
@ -1132,6 +1134,7 @@ var _ = Describe("Analyzer", func() {
|
||||||
It("should be able to skip generated files if excluded when using the analyzes", func() {
|
It("should be able to skip generated files if excluded when using the analyzes", func() {
|
||||||
customAnalyzer := gosec.NewAnalyzer(nil, true, true, false, 1, logger)
|
customAnalyzer := gosec.NewAnalyzer(nil, true, true, false, 1, logger)
|
||||||
customAnalyzer.LoadRules(rules.Generate(false).RulesInfo())
|
customAnalyzer.LoadRules(rules.Generate(false).RulesInfo())
|
||||||
|
customAnalyzer.LoadAnalyzers(analyzers.Generate(false).AnalyzersInfo())
|
||||||
pkg := testutils.NewTestPackage()
|
pkg := testutils.NewTestPackage()
|
||||||
defer pkg.Close()
|
defer pkg.Close()
|
||||||
pkg.AddFile("foo.go", `
|
pkg.AddFile("foo.go", `
|
||||||
|
@ -1499,6 +1502,44 @@ var _ = Describe("Analyzer", func() {
|
||||||
Expect(issues[0].Suppressions[0].Justification).To(Equal("Globally suppressed."))
|
Expect(issues[0].Suppressions[0].Justification).To(Equal("Globally suppressed."))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("should not report an error if the analyzer is not included", func() {
|
||||||
|
sample := testutils.SampleCodeG602[0]
|
||||||
|
source := sample.Code[0]
|
||||||
|
analyzer.LoadAnalyzers(analyzers.Generate(true, analyzers.NewAnalyzerFilter(false, "G115")).AnalyzersInfo())
|
||||||
|
|
||||||
|
controlPackage := testutils.NewTestPackage()
|
||||||
|
defer controlPackage.Close()
|
||||||
|
controlPackage.AddFile("cipher.go", source)
|
||||||
|
err := controlPackage.Build()
|
||||||
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
|
err = analyzer.Process(buildTags, controlPackage.Path)
|
||||||
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
|
controlIssues, _, _ := analyzer.Report()
|
||||||
|
Expect(controlIssues).Should(HaveLen(sample.Errors))
|
||||||
|
Expect(controlIssues[0].Suppressions).To(HaveLen(1))
|
||||||
|
Expect(controlIssues[0].Suppressions[0].Kind).To(Equal("external"))
|
||||||
|
Expect(controlIssues[0].Suppressions[0].Justification).To(Equal("Globally suppressed."))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not report an error if the analyzer is excluded", func() {
|
||||||
|
sample := testutils.SampleCodeG602[0]
|
||||||
|
source := sample.Code[0]
|
||||||
|
analyzer.LoadAnalyzers(analyzers.Generate(true, analyzers.NewAnalyzerFilter(true, "G602")).AnalyzersInfo())
|
||||||
|
|
||||||
|
controlPackage := testutils.NewTestPackage()
|
||||||
|
defer controlPackage.Close()
|
||||||
|
controlPackage.AddFile("cipher.go", source)
|
||||||
|
err := controlPackage.Build()
|
||||||
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
|
err = analyzer.Process(buildTags, controlPackage.Path)
|
||||||
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
|
issues, _, _ := analyzer.Report()
|
||||||
|
Expect(issues).Should(HaveLen(sample.Errors))
|
||||||
|
Expect(issues[0].Suppressions).To(HaveLen(1))
|
||||||
|
Expect(issues[0].Suppressions[0].Kind).To(Equal("external"))
|
||||||
|
Expect(issues[0].Suppressions[0].Justification).To(Equal("Globally suppressed."))
|
||||||
|
})
|
||||||
|
|
||||||
It("should track multiple suppressions if the violation is multiply suppressed", func() {
|
It("should track multiple suppressions if the violation is multiply suppressed", func() {
|
||||||
sample := testutils.SampleCodeG101[0]
|
sample := testutils.SampleCodeG101[0]
|
||||||
source := sample.Code[0]
|
source := sample.Code[0]
|
||||||
|
|
38
analyzers/analyzers_set.go
Normal file
38
analyzers/analyzers_set.go
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
// (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"
|
||||||
|
|
||||||
|
type AnalyzerSet struct {
|
||||||
|
Analyzers []*analysis.Analyzer
|
||||||
|
AnalyzerSuppressedMap map[string]bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewAnalyzerSet constructs a new AnalyzerSet
|
||||||
|
func NewAnalyzerSet() *AnalyzerSet {
|
||||||
|
return &AnalyzerSet{nil, make(map[string]bool)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register adds a trigger for the supplied analyzer
|
||||||
|
func (a *AnalyzerSet) Register(analyzer *analysis.Analyzer, isSuppressed bool) {
|
||||||
|
a.Analyzers = append(a.Analyzers, analyzer)
|
||||||
|
a.AnalyzerSuppressedMap[analyzer.Name] = isSuppressed
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsSuppressed will return whether the Analyzer is suppressed.
|
||||||
|
func (a *AnalyzerSet) IsSuppressed(ruleID string) bool {
|
||||||
|
return a.AnalyzerSuppressedMap[ruleID]
|
||||||
|
}
|
62
analyzers/analyzers_test.go
Normal file
62
analyzers/analyzers_test.go
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
package analyzers_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo/v2"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
|
"github.com/securego/gosec/v2"
|
||||||
|
"github.com/securego/gosec/v2/analyzers"
|
||||||
|
"github.com/securego/gosec/v2/testutils"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("gosec analyzers", func() {
|
||||||
|
var (
|
||||||
|
logger *log.Logger
|
||||||
|
config gosec.Config
|
||||||
|
analyzer *gosec.Analyzer
|
||||||
|
runner func(string, []testutils.CodeSample)
|
||||||
|
buildTags []string
|
||||||
|
tests bool
|
||||||
|
)
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
logger, _ = testutils.NewLogger()
|
||||||
|
config = gosec.NewConfig()
|
||||||
|
analyzer = gosec.NewAnalyzer(config, tests, false, false, 1, logger)
|
||||||
|
runner = func(analyzerId string, samples []testutils.CodeSample) {
|
||||||
|
for n, sample := range samples {
|
||||||
|
analyzer.Reset()
|
||||||
|
analyzer.SetConfig(sample.Config)
|
||||||
|
analyzer.LoadAnalyzers(analyzers.Generate(false, analyzers.NewAnalyzerFilter(false, analyzerId)).AnalyzersInfo())
|
||||||
|
pkg := testutils.NewTestPackage()
|
||||||
|
defer pkg.Close()
|
||||||
|
for i, code := range sample.Code {
|
||||||
|
pkg.AddFile(fmt.Sprintf("sample_%d_%d.go", n, i), code)
|
||||||
|
}
|
||||||
|
err := pkg.Build()
|
||||||
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
|
Expect(pkg.PrintErrors()).Should(BeZero())
|
||||||
|
err = analyzer.Process(buildTags, pkg.Path)
|
||||||
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
|
issues, _, _ := analyzer.Report()
|
||||||
|
if len(issues) != sample.Errors {
|
||||||
|
fmt.Println(sample.Code)
|
||||||
|
}
|
||||||
|
Expect(issues).Should(HaveLen(sample.Errors))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("report correct errors for all samples", func() {
|
||||||
|
It("should detect integer conversion overflow", func() {
|
||||||
|
runner("G115", testutils.SampleCodeG115)
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should detect out of bounds slice access", func() {
|
||||||
|
runner("G602", testutils.SampleCodeG602)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
94
analyzers/analyzerslist.go
Normal file
94
analyzers/analyzerslist.go
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
// (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"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AnalyzerDefinition contains the description of an analyzer and a mechanism to
|
||||||
|
// create it.
|
||||||
|
type AnalyzerDefinition struct {
|
||||||
|
ID string
|
||||||
|
Description string
|
||||||
|
Create AnalyzerBuilder
|
||||||
|
}
|
||||||
|
|
||||||
|
// AnalyzerBuilder is used to register an analyzer definition with the analyzer
|
||||||
|
type AnalyzerBuilder func(id string, description string) *analysis.Analyzer
|
||||||
|
|
||||||
|
// AnalyzerList contains a mapping of analyzer ID's to analyzer definitions and a mapping
|
||||||
|
// of analyzer ID's to whether analyzers are suppressed.
|
||||||
|
type AnalyzerList struct {
|
||||||
|
Analyzers map[string]AnalyzerDefinition
|
||||||
|
AnalyzerSuppressed map[string]bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// AnalyzersInfo returns all the create methods and the analyzer suppressed map for a
|
||||||
|
// given list
|
||||||
|
func (al *AnalyzerList) AnalyzersInfo() (map[string]AnalyzerDefinition, map[string]bool) {
|
||||||
|
builders := make(map[string]AnalyzerDefinition)
|
||||||
|
for _, def := range al.Analyzers {
|
||||||
|
builders[def.ID] = def
|
||||||
|
}
|
||||||
|
return builders, al.AnalyzerSuppressed
|
||||||
|
}
|
||||||
|
|
||||||
|
// AnalyzerFilter can be used to include or exclude an analyzer depending on the return
|
||||||
|
// value of the function
|
||||||
|
type AnalyzerFilter func(string) bool
|
||||||
|
|
||||||
|
// NewAnalyzerFilter is a closure that will include/exclude the analyzer ID's based on
|
||||||
|
// the supplied boolean value.
|
||||||
|
func NewAnalyzerFilter(action bool, analyzerIDs ...string) AnalyzerFilter {
|
||||||
|
analyzerlist := make(map[string]bool)
|
||||||
|
for _, analyzer := range analyzerIDs {
|
||||||
|
analyzerlist[analyzer] = true
|
||||||
|
}
|
||||||
|
return func(analyzer string) bool {
|
||||||
|
if _, found := analyzerlist[analyzer]; found {
|
||||||
|
return action
|
||||||
|
}
|
||||||
|
return !action
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultAnalyzers = []AnalyzerDefinition{
|
||||||
|
{"G115", "Type conversion which leads to integer overflow", newConversionOverflowAnalyzer},
|
||||||
|
{"G602", "Possible slice bounds out of range", newSliceBoundsAnalyzer},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate the list of analyzers to use
|
||||||
|
func Generate(trackSuppressions bool, filters ...AnalyzerFilter) *AnalyzerList {
|
||||||
|
analyzerMap := make(map[string]AnalyzerDefinition)
|
||||||
|
analyzerSuppressedMap := make(map[string]bool)
|
||||||
|
|
||||||
|
for _, analyzer := range defaultAnalyzers {
|
||||||
|
analyzerSuppressedMap[analyzer.ID] = false
|
||||||
|
addToAnalyzerList := true
|
||||||
|
for _, filter := range filters {
|
||||||
|
if filter(analyzer.ID) {
|
||||||
|
analyzerSuppressedMap[analyzer.ID] = true
|
||||||
|
if !trackSuppressions {
|
||||||
|
addToAnalyzerList = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if addToAnalyzerList {
|
||||||
|
analyzerMap[analyzer.ID] = analyzer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &AnalyzerList{Analyzers: analyzerMap, AnalyzerSuppressed: analyzerSuppressedMap}
|
||||||
|
}
|
13
analyzers/anaylzers_suite_test.go
Normal file
13
analyzers/anaylzers_suite_test.go
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
package analyzers_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo/v2"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAnalyzers(t *testing.T) {
|
||||||
|
RegisterFailHandler(Fail)
|
||||||
|
RunSpecs(t, "Analyzers Suite")
|
||||||
|
}
|
|
@ -35,14 +35,6 @@ type SSAAnalyzerResult struct {
|
||||||
SSA *buildssa.SSA
|
SSA *buildssa.SSA
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildDefaultAnalyzers returns the default list of analyzers
|
|
||||||
func BuildDefaultAnalyzers() []*analysis.Analyzer {
|
|
||||||
return []*analysis.Analyzer{
|
|
||||||
newConversionOverflowAnalyzer("G115", "Type conversion which leads to integer overflow"),
|
|
||||||
newSliceBoundsAnalyzer("G602", "Possible slice bounds out of range"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// getSSAResult retrieves the SSA result from analysis pass
|
// getSSAResult retrieves the SSA result from analysis pass
|
||||||
func getSSAResult(pass *analysis.Pass) (*SSAAnalyzerResult, error) {
|
func getSSAResult(pass *analysis.Pass) (*SSAAnalyzerResult, error) {
|
||||||
result, ok := pass.ResultOf[buildssa.Analyzer]
|
result, ok := pass.ResultOf[buildssa.Analyzer]
|
||||||
|
|
|
@ -25,6 +25,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/securego/gosec/v2"
|
"github.com/securego/gosec/v2"
|
||||||
|
"github.com/securego/gosec/v2/analyzers"
|
||||||
"github.com/securego/gosec/v2/autofix"
|
"github.com/securego/gosec/v2/autofix"
|
||||||
"github.com/securego/gosec/v2/cmd/vflag"
|
"github.com/securego/gosec/v2/cmd/vflag"
|
||||||
"github.com/securego/gosec/v2/issue"
|
"github.com/securego/gosec/v2/issue"
|
||||||
|
@ -177,14 +178,23 @@ func usage() {
|
||||||
|
|
||||||
// sorted rule list for ease of reading
|
// sorted rule list for ease of reading
|
||||||
rl := rules.Generate(*flagTrackSuppressions)
|
rl := rules.Generate(*flagTrackSuppressions)
|
||||||
keys := make([]string, 0, len(rl.Rules))
|
al := analyzers.Generate(*flagTrackSuppressions)
|
||||||
|
keys := make([]string, 0, len(rl.Rules)+len(al.Analyzers))
|
||||||
for key := range rl.Rules {
|
for key := range rl.Rules {
|
||||||
keys = append(keys, key)
|
keys = append(keys, key)
|
||||||
}
|
}
|
||||||
|
for key := range al.Analyzers {
|
||||||
|
keys = append(keys, key)
|
||||||
|
}
|
||||||
sort.Strings(keys)
|
sort.Strings(keys)
|
||||||
for _, k := range keys {
|
for _, k := range keys {
|
||||||
v := rl.Rules[k]
|
var description string
|
||||||
fmt.Fprintf(os.Stderr, "\t%s: %s\n", k, v.Description)
|
if rule, ok := rl.Rules[k]; ok {
|
||||||
|
description = rule.Description
|
||||||
|
} else if analyzer, ok := al.Analyzers[k]; ok {
|
||||||
|
description = analyzer.Description
|
||||||
|
}
|
||||||
|
fmt.Fprintf(os.Stderr, "\t%s: %s\n", k, description)
|
||||||
}
|
}
|
||||||
fmt.Fprint(os.Stderr, "\n")
|
fmt.Fprint(os.Stderr, "\n")
|
||||||
}
|
}
|
||||||
|
@ -245,6 +255,26 @@ func loadRules(include, exclude string) rules.RuleList {
|
||||||
return rules.Generate(*flagTrackSuppressions, filters...)
|
return rules.Generate(*flagTrackSuppressions, filters...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loadAnalyzers(include, exclude string) *analyzers.AnalyzerList {
|
||||||
|
var filters []analyzers.AnalyzerFilter
|
||||||
|
if include != "" {
|
||||||
|
logger.Printf("Including analyzers: %s", include)
|
||||||
|
including := strings.Split(include, ",")
|
||||||
|
filters = append(filters, analyzers.NewAnalyzerFilter(false, including...))
|
||||||
|
} else {
|
||||||
|
logger.Println("Including analyzers: default")
|
||||||
|
}
|
||||||
|
|
||||||
|
if exclude != "" {
|
||||||
|
logger.Printf("Excluding analyzers: %s", exclude)
|
||||||
|
excluding := strings.Split(exclude, ",")
|
||||||
|
filters = append(filters, analyzers.NewAnalyzerFilter(true, excluding...))
|
||||||
|
} else {
|
||||||
|
logger.Println("Excluding analyzers: default")
|
||||||
|
}
|
||||||
|
return analyzers.Generate(*flagTrackSuppressions, filters...)
|
||||||
|
}
|
||||||
|
|
||||||
func getRootPaths(paths []string) []string {
|
func getRootPaths(paths []string) []string {
|
||||||
rootPaths := make([]string, 0)
|
rootPaths := make([]string, 0)
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
|
@ -412,9 +442,12 @@ func main() {
|
||||||
logger.Fatal("No rules are configured")
|
logger.Fatal("No rules are configured")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
analyzerList := loadAnalyzers(includeRules, excludeRules)
|
||||||
|
|
||||||
// Create the analyzer
|
// Create the analyzer
|
||||||
analyzer := gosec.NewAnalyzer(config, *flagScanTests, *flagExcludeGenerated, *flagTrackSuppressions, *flagConcurrency, logger)
|
analyzer := gosec.NewAnalyzer(config, *flagScanTests, *flagExcludeGenerated, *flagTrackSuppressions, *flagConcurrency, logger)
|
||||||
analyzer.LoadRules(ruleList.RulesInfo())
|
analyzer.LoadRules(ruleList.RulesInfo())
|
||||||
|
analyzer.LoadAnalyzers(analyzerList.AnalyzersInfo())
|
||||||
|
|
||||||
excludedDirs := gosec.ExcludedDirsRegExp(flagDirsExclude)
|
excludedDirs := gosec.ExcludedDirsRegExp(flagDirsExclude)
|
||||||
var packages []string
|
var packages []string
|
||||||
|
|
|
@ -111,10 +111,6 @@ var _ = Describe("gosec rules", func() {
|
||||||
runner("G114", testutils.SampleCodeG114)
|
runner("G114", testutils.SampleCodeG114)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should detect integer conversion overflow", func() {
|
|
||||||
runner("G115", testutils.SampleCodeG115)
|
|
||||||
})
|
|
||||||
|
|
||||||
It("should detect sql injection via format strings", func() {
|
It("should detect sql injection via format strings", func() {
|
||||||
runner("G201", testutils.SampleCodeG201)
|
runner("G201", testutils.SampleCodeG201)
|
||||||
})
|
})
|
||||||
|
@ -225,9 +221,5 @@ var _ = Describe("gosec rules", func() {
|
||||||
runner("G601", testutils.SampleCodeG601)
|
runner("G601", testutils.SampleCodeG601)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should detect out of bounds slice access", func() {
|
|
||||||
runner("G602", testutils.SampleCodeG602)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -27,7 +27,7 @@ func main() {
|
||||||
intPtr = (*int)(unsafe.Pointer(addressHolder))
|
intPtr = (*int)(unsafe.Pointer(addressHolder))
|
||||||
fmt.Printf("\nintPtr=%p, *intPtr=%d.\n\n", intPtr, *intPtr)
|
fmt.Printf("\nintPtr=%p, *intPtr=%d.\n\n", intPtr, *intPtr)
|
||||||
}
|
}
|
||||||
`}, 3, gosec.NewConfig()},
|
`}, 2, gosec.NewConfig()},
|
||||||
{[]string{`
|
{[]string{`
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ func main() {
|
||||||
value := int32(bigValue)
|
value := int32(bigValue)
|
||||||
fmt.Println(value)
|
fmt.Println(value)
|
||||||
}
|
}
|
||||||
`}, 2, gosec.NewConfig()},
|
`}, 1, gosec.NewConfig()},
|
||||||
{[]string{`
|
{[]string{`
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ func main() {
|
||||||
fmt.Println(bigValue)
|
fmt.Println(bigValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`}, 2, gosec.NewConfig()},
|
`}, 1, gosec.NewConfig()},
|
||||||
{[]string{`
|
{[]string{`
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue