From 8932f702cecbb3ffafcf52473b85d5d8f19333a1 Mon Sep 17 00:00:00 2001 From: Daniel Carlier Date: Wed, 4 Sep 2019 05:20:43 -0300 Subject: [PATCH] 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 --- analyzer.go | 9 ++++++++- analyzer_test.go | 48 +++++++++++++++++++++++++++++++++++++++++++++++ cmd/gosec/main.go | 6 ++++++ config.go | 2 ++ 4 files changed, 64 insertions(+), 1 deletion(-) diff --git a/analyzer.go b/analyzer.go index 8043255..79e590b 100644 --- a/analyzer.go +++ b/analyzer.go @@ -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 func (gosec *Analyzer) ignore(n ast.Node) ([]string, bool) { 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 { - if strings.Contains(group.Text(), "#nosec") { + if strings.Contains(group.Text(), noSecAlternative) { gosec.stats.NumNosec++ // Pull out the specific rules that are listed to be ignored. diff --git a/analyzer_test.go b/analyzer_test.go index 534bf01..7aeef5f 100644 --- a/analyzer_test.go +++ b/analyzer_test.go @@ -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() { customAnalyzer := gosec.NewAnalyzer(nil, true, logger) customAnalyzer.LoadRules(rules.Generate().Builders()) diff --git a/cmd/gosec/main.go b/cmd/gosec/main.go index 2459e50..c9c29d5 100644 --- a/cmd/gosec/main.go +++ b/cmd/gosec/main.go @@ -65,6 +65,9 @@ var ( // format output 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 flagOutput = flag.String("out", "", "Set output file for results") @@ -148,6 +151,9 @@ func loadConfig(configFile string) (gosec.Config, error) { if *flagIgnoreNoSec { config.SetGlobal(gosec.Nosec, "true") } + if *flagAlternativeNoSec != "" { + config.SetGlobal(gosec.NoSecAlternative, *flagAlternativeNoSec) + } return config, nil } diff --git a/config.go b/config.go index f098b4f..14fd2b3 100644 --- a/config.go +++ b/config.go @@ -22,6 +22,8 @@ const ( Nosec GlobalOption = "nosec" // Audit global option which indicates that gosec runs in audit mode 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.