Add flag to handle '#nosec' alternative (#346)

* Add logic to check for a #nosec alternative

* Add NoSecAlternative as a new global variable

* Add nosec-tag flag
This commit is contained in:
Daniel Carlier 2019-09-04 05:20:43 -03:00 committed by Cosmin Cojocar
parent 4b59c94808
commit 8932f702ce
4 changed files with 64 additions and 1 deletions

View file

@ -251,8 +251,15 @@ func (gosec *Analyzer) AppendError(file string, err error) {
// ignore a node (and sub-tree) if it is tagged with a "#nosec" comment // ignore a node (and sub-tree) if it is tagged with a "#nosec" comment
func (gosec *Analyzer) ignore(n ast.Node) ([]string, bool) { func (gosec *Analyzer) ignore(n ast.Node) ([]string, bool) {
if groups, ok := gosec.context.Comments[n]; ok && !gosec.ignoreNosec { if groups, ok := gosec.context.Comments[n]; ok && !gosec.ignoreNosec {
// Checks if an alternative for #nosec is set and, if not, uses the default.
noSecAlternative, err := gosec.config.GetGlobal(NoSecAlternative)
if err != nil {
noSecAlternative = "#nosec"
}
for _, group := range groups { for _, group := range groups {
if strings.Contains(group.Text(), "#nosec") { if strings.Contains(group.Text(), noSecAlternative) {
gosec.stats.NumNosec++ gosec.stats.NumNosec++
// Pull out the specific rules that are listed to be ignored. // Pull out the specific rules that are listed to be ignored.

View file

@ -265,6 +265,54 @@ var _ = Describe("Analyzer", func() {
}) })
It("should be possible to change the default #nosec directive to another one", func() {
// Rule for MD5 weak crypto usage
sample := testutils.SampleCodeG401[0]
source := sample.Code[0]
// overwrite nosec option
nosecIgnoreConfig := gosec.NewConfig()
nosecIgnoreConfig.SetGlobal(gosec.NoSecAlternative, "#falsePositive")
customAnalyzer := gosec.NewAnalyzer(nosecIgnoreConfig, tests, logger)
customAnalyzer.LoadRules(rules.Generate(rules.NewRuleFilter(false, "G401")).Builders())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "h := md5.New()", "h := md5.New() // #falsePositive", 1)
nosecPackage.AddFile("md5.go", nosecSource)
err := nosecPackage.Build()
Expect(err).ShouldNot(HaveOccurred())
err = customAnalyzer.Process(buildTags, nosecPackage.Path)
Expect(err).ShouldNot(HaveOccurred())
nosecIssues, _, _ := customAnalyzer.Report()
Expect(nosecIssues).Should(HaveLen(0))
})
It("should not ignore vulnerabilities", func() {
// Rule for MD5 weak crypto usage
sample := testutils.SampleCodeG401[0]
source := sample.Code[0]
// overwrite nosec option
nosecIgnoreConfig := gosec.NewConfig()
nosecIgnoreConfig.SetGlobal(gosec.NoSecAlternative, "#falsePositive")
customAnalyzer := gosec.NewAnalyzer(nosecIgnoreConfig, tests, logger)
customAnalyzer.LoadRules(rules.Generate(rules.NewRuleFilter(false, "G401")).Builders())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "h := md5.New()", "h := md5.New() // #nosec", 1)
nosecPackage.AddFile("md5.go", nosecSource)
err := nosecPackage.Build()
Expect(err).ShouldNot(HaveOccurred())
err = customAnalyzer.Process(buildTags, nosecPackage.Path)
Expect(err).ShouldNot(HaveOccurred())
nosecIssues, _, _ := customAnalyzer.Report()
Expect(nosecIssues).Should(HaveLen(sample.Errors))
})
It("should be able to analyze Go test package", func() { It("should be able to analyze Go test package", func() {
customAnalyzer := gosec.NewAnalyzer(nil, true, logger) customAnalyzer := gosec.NewAnalyzer(nil, true, logger)
customAnalyzer.LoadRules(rules.Generate().Builders()) customAnalyzer.LoadRules(rules.Generate().Builders())

View file

@ -65,6 +65,9 @@ var (
// format output // format output
flagFormat = flag.String("fmt", "text", "Set output format. Valid options are: json, yaml, csv, junit-xml, html, sonarqube, or text") flagFormat = flag.String("fmt", "text", "Set output format. Valid options are: json, yaml, csv, junit-xml, html, sonarqube, or text")
// #nosec alternative tag
flagAlternativeNoSec = flag.String("nosec-tag", "", "Set an alternative string for #nosec. Some examples: #dontanalyze, #falsepositive")
// output file // output file
flagOutput = flag.String("out", "", "Set output file for results") flagOutput = flag.String("out", "", "Set output file for results")
@ -148,6 +151,9 @@ func loadConfig(configFile string) (gosec.Config, error) {
if *flagIgnoreNoSec { if *flagIgnoreNoSec {
config.SetGlobal(gosec.Nosec, "true") config.SetGlobal(gosec.Nosec, "true")
} }
if *flagAlternativeNoSec != "" {
config.SetGlobal(gosec.NoSecAlternative, *flagAlternativeNoSec)
}
return config, nil return config, nil
} }

View file

@ -22,6 +22,8 @@ const (
Nosec GlobalOption = "nosec" Nosec GlobalOption = "nosec"
// Audit global option which indicates that gosec runs in audit mode // Audit global option which indicates that gosec runs in audit mode
Audit GlobalOption = "audit" Audit GlobalOption = "audit"
// NoSecAlternative global option alternative for #nosec directive
NoSecAlternative GlobalOption = "#nosec"
) )
// Config is used to provide configuration and customization to each of the rules. // Config is used to provide configuration and customization to each of the rules.