From 7f8f654235b42704bab6c65c3459a2824bccadd3 Mon Sep 17 00:00:00 2001 From: Dimitar Banchev Date: Fri, 30 Aug 2024 11:39:24 +0200 Subject: [PATCH] Updated analyzer to use new way of initialization * Removed old way of initializing analyzers * Added the new analyzer to the rest of the default analyzers * Fixed small bug in the rule * Removed the test for the new analyzer from the file responsible for testing the rules * Merged the diffrent examples into 1 variable * Added tests for the analyzer * Removed code that was used for testing rules, but it was used to test the analyzer --- analyzer_test.go | 346 ++++-------------------------------- analyzers/analyzers_test.go | 4 + analyzers/analyzerslist.go | 1 + analyzers/hardcodedNonce.go | 4 +- rules/rules_test.go | 76 -------- testutils/g407_samples.go | 114 ++++++------ 6 files changed, 105 insertions(+), 440 deletions(-) diff --git a/analyzer_test.go b/analyzer_test.go index 301f194..2e5591b 100644 --- a/analyzer_test.go +++ b/analyzer_test.go @@ -187,22 +187,6 @@ var _ = Describe("Analyzer", func() { Expect(controlIssues).Should(HaveLen(sample.Errors)) }) - It("should find errors when nosec is not in use", func() { - sample := testutils.SampleCodeG407[0] - source := sample.Code[0] - analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G407")).RulesInfo()) - - controlPackage := testutils.NewTestPackage() - defer controlPackage.Close() - controlPackage.AddFile("aesOFB.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)) - }) - It("should report Go build errors and invalid files", func() { analyzer.LoadRules(rules.Generate(false).RulesInfo()) pkg := testutils.NewTestPackage() @@ -282,23 +266,6 @@ var _ = Describe("Analyzer", func() { Expect(nosecIssues).Should(BeEmpty()) }) - It("should not report errors when a nosec line comment is present", func() { - sample := testutils.SampleCodeG407[0] - source := sample.Code[0] - analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G407")).RulesInfo()) - - nosecPackage := testutils.NewTestPackage() - defer nosecPackage.Close() - nosecSource := strings.Replace(source, "cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\"))", "cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\")) //#nosec", 1) - nosecPackage.AddFile("aesOFB.go", nosecSource) - err := nosecPackage.Build() - Expect(err).ShouldNot(HaveOccurred()) - err = analyzer.Process(buildTags, nosecPackage.Path) - Expect(err).ShouldNot(HaveOccurred()) - nosecIssues, _, _ := analyzer.Report() - Expect(nosecIssues).Should(BeEmpty()) - }) - It("should not report errors when a nosec block comment is present", func() { sample := testutils.SampleCodeG401[0] source := sample.Code[0] @@ -350,23 +317,6 @@ var _ = Describe("Analyzer", func() { Expect(nosecIssues).Should(BeEmpty()) }) - It("should not report errors when a nosec block comment is present", func() { - sample := testutils.SampleCodeG407[0] - source := sample.Code[0] - analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G407")).RulesInfo()) - - nosecPackage := testutils.NewTestPackage() - defer nosecPackage.Close() - nosecSource := strings.Replace(source, "cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\"))", "cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\")) /* #nosec */", 1) - nosecPackage.AddFile("aesOFB.go", nosecSource) - err := nosecPackage.Build() - Expect(err).ShouldNot(HaveOccurred()) - err = analyzer.Process(buildTags, nosecPackage.Path) - Expect(err).ShouldNot(HaveOccurred()) - nosecIssues, _, _ := analyzer.Report() - Expect(nosecIssues).Should(BeEmpty()) - }) - It("should not report errors when an exclude comment is present for the correct rule", func() { // Rule for MD5 weak crypto usage sample := testutils.SampleCodeG401[0] @@ -421,24 +371,6 @@ var _ = Describe("Analyzer", func() { Expect(nosecIssues).Should(BeEmpty()) }) - It("should not report errors when an exclude comment is present for the correct rule", func() { - // Rule for hardcoded nonce/IV - sample := testutils.SampleCodeG407[0] - source := sample.Code[0] - analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G407")).RulesInfo()) - - nosecPackage := testutils.NewTestPackage() - defer nosecPackage.Close() - nosecSource := strings.Replace(source, "cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\"))", "cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\")) //#nosec G407", 1) - nosecPackage.AddFile("aesOFB.go", nosecSource) - err := nosecPackage.Build() - Expect(err).ShouldNot(HaveOccurred()) - err = analyzer.Process(buildTags, nosecPackage.Path) - Expect(err).ShouldNot(HaveOccurred()) - nosecIssues, _, _ := analyzer.Report() - Expect(nosecIssues).Should(BeEmpty()) - }) - It("should not report errors when a nosec block and line comment are present", func() { sample := testutils.SampleCodeG101[23] source := sample.Code[0] @@ -536,23 +468,6 @@ var _ = Describe("Analyzer", func() { Expect(nosecIssues).Should(HaveLen(sample.Errors)) }) - It("should report errors when an exclude comment is present for a different rule", func() { - sample := testutils.SampleCodeG407[0] - source := sample.Code[0] - analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G407")).RulesInfo()) - - nosecPackage := testutils.NewTestPackage() - defer nosecPackage.Close() - nosecSource := strings.Replace(source, "cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\"))", "cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\")) //#nosec G301", 1) - nosecPackage.AddFile("aesOFB.go", nosecSource) - err := nosecPackage.Build() - Expect(err).ShouldNot(HaveOccurred()) - err = analyzer.Process(buildTags, nosecPackage.Path) - Expect(err).ShouldNot(HaveOccurred()) - nosecIssues, _, _ := analyzer.Report() - Expect(nosecIssues).Should(HaveLen(sample.Errors)) - }) - It("should not report errors when an exclude comment is present for multiple rules, including the correct rule", func() { sample := testutils.SampleCodeG401[0] source := sample.Code[0] @@ -610,25 +525,6 @@ var _ = Describe("Analyzer", func() { Expect(nosecIssues).Should(BeEmpty()) }) - It("should not report errors when an exclude comment is present for multiple rules, including the correct rule", func() { - sample := testutils.SampleCodeG407[0] - source := sample.Code[0] - analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G407")).RulesInfo()) - - nosecPackage := testutils.NewTestPackage() - defer nosecPackage.Close() - nosecSource := strings.Replace(source, "cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\"))", "cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\")) //#nosec G301 G407", 1) - nosecPackage.AddFile("aesOFB.go", nosecSource) - err := nosecPackage.Build() - Expect(err).ShouldNot(HaveOccurred()) - err = analyzer.Process(buildTags, nosecPackage.Path) - Expect(err).ShouldNot(HaveOccurred()) - err = analyzer.Process(buildTags, nosecPackage.Path) - Expect(err).ShouldNot(HaveOccurred()) - nosecIssues, _, _ := analyzer.Report() - Expect(nosecIssues).Should(BeEmpty()) - }) - It("should pass the build tags", func() { sample := testutils.SampleCodeBuildTag[0] source := sample.Code[0] @@ -725,29 +621,6 @@ var _ = Describe("Analyzer", func() { Expect(nosecIssues).Should(HaveLen(sample.Errors)) }) - It("should be possible to overwrite nosec comments, and report issues", func() { - // Rule for hardcoded IV/nonce - sample := testutils.SampleCodeG407[0] - source := sample.Code[0] - - // overwrite nosec option - nosecIgnoreConfig := gosec.NewConfig() - nosecIgnoreConfig.SetGlobal(gosec.Nosec, "true") - customAnalyzer := gosec.NewAnalyzer(nosecIgnoreConfig, tests, false, false, 1, logger) - customAnalyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G407")).RulesInfo()) - - nosecPackage := testutils.NewTestPackage() - defer nosecPackage.Close() - nosecSource := strings.Replace(source, "cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\"))", "cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\")) //#nosec", 1) - nosecPackage.AddFile("aesOFB.go", nosecSource) - err := nosecPackage.Build() - Expect(err).ShouldNot(HaveOccurred()) - err = customAnalyzer.Process(buildTags, nosecPackage.Path) - Expect(err).ShouldNot(HaveOccurred()) - nosecIssues, _, _ := customAnalyzer.Report() - Expect(nosecIssues).Should(HaveLen(sample.Errors)) - }) - It("should be possible to overwrite nosec comments, and report issues but they should not be counted", func() { // Rule for MD5 weak crypto usage sample := testutils.SampleCodeG401[0] @@ -826,32 +699,6 @@ var _ = Describe("Analyzer", func() { Expect(metrics.NumNosec).Should(Equal(1)) }) - It("should be possible to overwrite nosec comments, and report issues but they should not be counted", func() { - // Rule for hardcoded nonce/IV - sample := testutils.SampleCodeG407[0] - source := sample.Code[0] - - // overwrite nosec option - nosecIgnoreConfig := gosec.NewConfig() - nosecIgnoreConfig.SetGlobal(gosec.Nosec, "mynosec") - nosecIgnoreConfig.SetGlobal(gosec.ShowIgnored, "true") - customAnalyzer := gosec.NewAnalyzer(nosecIgnoreConfig, tests, false, false, 1, logger) - customAnalyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G407")).RulesInfo()) - - nosecPackage := testutils.NewTestPackage() - defer nosecPackage.Close() - nosecSource := strings.Replace(source, "cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\"))", "cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\")) // #mynosec", 1) - nosecPackage.AddFile("aesOFB.go", nosecSource) - err := nosecPackage.Build() - Expect(err).ShouldNot(HaveOccurred()) - err = customAnalyzer.Process(buildTags, nosecPackage.Path) - Expect(err).ShouldNot(HaveOccurred()) - nosecIssues, metrics, _ := customAnalyzer.Report() - Expect(nosecIssues).Should(HaveLen(sample.Errors)) - Expect(metrics.NumFound).Should(Equal(0)) - Expect(metrics.NumNosec).Should(Equal(1)) - }) - It("should not report errors when nosec tag is in front of a line", func() { sample := testutils.SampleCodeG401[0] source := sample.Code[0] @@ -903,23 +750,6 @@ var _ = Describe("Analyzer", func() { Expect(nosecIssues).Should(BeEmpty()) }) - It("should not report errors when nosec tag is in front of a line", func() { - sample := testutils.SampleCodeG407[0] - source := sample.Code[0] - analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G407")).RulesInfo()) - - nosecPackage := testutils.NewTestPackage() - defer nosecPackage.Close() - nosecSource := strings.Replace(source, "aesOFB := cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\"))", "//Some description\n//#nosec G407\naesOFB := cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\"))", 1) - nosecPackage.AddFile("aesOFB.go", nosecSource) - err := nosecPackage.Build() - Expect(err).ShouldNot(HaveOccurred()) - err = analyzer.Process(buildTags, nosecPackage.Path) - Expect(err).ShouldNot(HaveOccurred()) - nosecIssues, _, _ := analyzer.Report() - Expect(nosecIssues).Should(BeEmpty()) - }) - It("should report errors when nosec tag is not in front of a line", func() { sample := testutils.SampleCodeG401[0] source := sample.Code[0] @@ -971,23 +801,6 @@ var _ = Describe("Analyzer", func() { Expect(nosecIssues).Should(HaveLen(sample.Errors)) }) - It("should report errors when nosec tag is not in front of a line", func() { - sample := testutils.SampleCodeG407[0] - source := sample.Code[0] - analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G407")).RulesInfo()) - - nosecPackage := testutils.NewTestPackage() - defer nosecPackage.Close() - nosecSource := strings.Replace(source, "aesOFB := cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\"))", "//Some description\n//Another description #nosec G407\naesOFB := cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\"))", 1) - nosecPackage.AddFile("aesOFB.go", nosecSource) - err := nosecPackage.Build() - Expect(err).ShouldNot(HaveOccurred()) - err = analyzer.Process(buildTags, nosecPackage.Path) - Expect(err).ShouldNot(HaveOccurred()) - nosecIssues, _, _ := analyzer.Report() - Expect(nosecIssues).Should(HaveLen(sample.Errors)) - }) - It("should not report errors when rules are in front of nosec tag even rules are wrong", func() { sample := testutils.SampleCodeG401[0] source := sample.Code[0] @@ -1039,23 +852,6 @@ var _ = Describe("Analyzer", func() { Expect(nosecIssues).Should(BeEmpty()) }) - It("should not report errors when rules are in front of nosec tag even rules are wrong", func() { - sample := testutils.SampleCodeG407[0] - source := sample.Code[0] - analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G407")).RulesInfo()) - - nosecPackage := testutils.NewTestPackage() - defer nosecPackage.Close() - nosecSource := strings.Replace(source, "aesOFB := cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\"))", "//G301\n//#nosec\naesOFB := cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\"))", 1) - nosecPackage.AddFile("aesOFB.go", nosecSource) - err := nosecPackage.Build() - Expect(err).ShouldNot(HaveOccurred()) - err = analyzer.Process(buildTags, nosecPackage.Path) - Expect(err).ShouldNot(HaveOccurred()) - nosecIssues, _, _ := analyzer.Report() - Expect(nosecIssues).Should(BeEmpty()) - }) - It("should report errors when there are nosec tags after a #nosec WrongRuleList annotation", func() { sample := testutils.SampleCodeG401[0] source := sample.Code[0] @@ -1107,23 +903,6 @@ var _ = Describe("Analyzer", func() { Expect(nosecIssues).Should(HaveLen(sample.Errors)) }) - It("should report errors when there are nosec tags after a #nosec WrongRuleList annotation", func() { - sample := testutils.SampleCodeG407[0] - source := sample.Code[0] - analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G407")).RulesInfo()) - - nosecPackage := testutils.NewTestPackage() - defer nosecPackage.Close() - nosecSource := strings.Replace(source, "aesOFB := cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\"))", "//#nosec\n//G301\n//#nosec\naesOFB := cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\"))", 1) - nosecPackage.AddFile("aesOFB.go", nosecSource) - err := nosecPackage.Build() - Expect(err).ShouldNot(HaveOccurred()) - err = analyzer.Process(buildTags, nosecPackage.Path) - Expect(err).ShouldNot(HaveOccurred()) - nosecIssues, _, _ := analyzer.Report() - Expect(nosecIssues).Should(HaveLen(sample.Errors)) - }) - It("should be possible to use an alternative nosec tag", func() { // Rule for MD5 weak crypto usage sample := testutils.SampleCodeG401[0] @@ -1193,29 +972,6 @@ var _ = Describe("Analyzer", func() { Expect(nosecIssues).Should(BeEmpty()) }) - It("should be possible to use an alternative nosec tag", func() { - // Rule for hardcoded nonce/IV - sample := testutils.SampleCodeG407[0] - source := sample.Code[0] - - // overwrite nosec option - nosecIgnoreConfig := gosec.NewConfig() - nosecIgnoreConfig.SetGlobal(gosec.NoSecAlternative, "falsePositive") - customAnalyzer := gosec.NewAnalyzer(nosecIgnoreConfig, tests, false, false, 1, logger) - customAnalyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G407")).RulesInfo()) - - nosecPackage := testutils.NewTestPackage() - defer nosecPackage.Close() - nosecSource := strings.Replace(source, "cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\"))", "cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\")) // #falsePositive", 1) - nosecPackage.AddFile("aesOFB.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(BeEmpty()) - }) - It("should ignore vulnerabilities when the default tag is found", func() { // Rule for MD5 weak crypto usage sample := testutils.SampleCodeG401[0] @@ -1285,29 +1041,6 @@ var _ = Describe("Analyzer", func() { Expect(nosecIssues).Should(BeEmpty()) }) - It("should ignore vulnerabilities when the default tag is found", func() { - // Rule for hardcoded nonce/IV - sample := testutils.SampleCodeG407[0] - source := sample.Code[0] - - // overwrite nosec option - nosecIgnoreConfig := gosec.NewConfig() - nosecIgnoreConfig.SetGlobal(gosec.NoSecAlternative, "falsePositive") - customAnalyzer := gosec.NewAnalyzer(nosecIgnoreConfig, tests, false, false, 1, logger) - customAnalyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G407")).RulesInfo()) - - nosecPackage := testutils.NewTestPackage() - defer nosecPackage.Close() - nosecSource := strings.Replace(source, "cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\"))", "cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\")) //#nosec", 1) - nosecPackage.AddFile("aesOFB.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(BeEmpty()) - }) - It("should be able to analyze Go test package", func() { customAnalyzer := gosec.NewAnalyzer(nil, true, false, false, 1, logger) customAnalyzer.LoadRules(rules.Generate(false).RulesInfo()) @@ -1671,26 +1404,6 @@ var _ = Describe("Analyzer", func() { Expect(issues[0].Suppressions[0].Justification).To(Equal("Justification")) }) - It("should not report an error if the violation is suppressed", func() { - sample := testutils.SampleCodeG407[0] - source := sample.Code[0] - analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G407")).RulesInfo()) - - nosecPackage := testutils.NewTestPackage() - defer nosecPackage.Close() - nosecSource := strings.Replace(source, "cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\"))", "cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\")) //#nosec G407 -- Justification", 1) - nosecPackage.AddFile("aesOFB.go", nosecSource) - err := nosecPackage.Build() - Expect(err).ShouldNot(HaveOccurred()) - err = analyzer.Process(buildTags, nosecPackage.Path) - Expect(err).ShouldNot(HaveOccurred()) - issues, _, _ := analyzer.Report() - Expect(issues).To(HaveLen(sample.Errors)) - Expect(issues[0].Suppressions).To(HaveLen(1)) - Expect(issues[0].Suppressions[0].Kind).To(Equal("inSource")) - Expect(issues[0].Suppressions[0].Justification).To(Equal("Justification")) - }) - It("should not report an error if the violation is suppressed without certain rules", func() { sample := testutils.SampleCodeG401[0] source := sample.Code[0] @@ -1751,26 +1464,6 @@ var _ = Describe("Analyzer", func() { Expect(issues[0].Suppressions[0].Justification).To(Equal("")) }) - It("should not report an error if the violation is suppressed without certain rules", func() { - sample := testutils.SampleCodeG407[0] - source := sample.Code[0] - analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G407")).RulesInfo()) - - nosecPackage := testutils.NewTestPackage() - defer nosecPackage.Close() - nosecSource := strings.Replace(source, "cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\"))", "cipher.NewOFB(block, []byte(\"ILoveMyNonceAlot\")) //#nosec", 1) - nosecPackage.AddFile("aesOFB.go", nosecSource) - err := nosecPackage.Build() - Expect(err).ShouldNot(HaveOccurred()) - err = analyzer.Process(buildTags, nosecPackage.Path) - Expect(err).ShouldNot(HaveOccurred()) - issues, _, _ := analyzer.Report() - Expect(issues).To(HaveLen(sample.Errors)) - Expect(issues[0].Suppressions).To(HaveLen(1)) - Expect(issues[0].Suppressions[0].Kind).To(Equal("inSource")) - Expect(issues[0].Suppressions[0].Justification).To(Equal("")) - }) - It("should not report an error if the rule is not included", func() { sample := testutils.SampleCodeG101[0] source := sample.Code[0] @@ -1809,6 +1502,45 @@ var _ = Describe("Analyzer", func() { 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.SampleCodeG407[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.SampleCodeG407[0] + source := sample.Code[0] + analyzer.LoadAnalyzers(analyzers.Generate(true, analyzers.NewAnalyzerFilter(true, "G407")).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 not report an error if the analyzer is not included", func() { sample := testutils.SampleCodeG602[0] source := sample.Code[0] diff --git a/analyzers/analyzers_test.go b/analyzers/analyzers_test.go index 898040b..a77445a 100644 --- a/analyzers/analyzers_test.go +++ b/analyzers/analyzers_test.go @@ -55,6 +55,10 @@ var _ = Describe("gosec analyzers", func() { runner("G115", testutils.SampleCodeG115) }) + It("should detect hardcoded nonce/IV", func() { + runner("G407", testutils.SampleCodeG407) + }) + It("should detect out of bounds slice access", func() { runner("G602", testutils.SampleCodeG602) }) diff --git a/analyzers/analyzerslist.go b/analyzers/analyzerslist.go index 4bf9ca9..f215744 100644 --- a/analyzers/analyzerslist.go +++ b/analyzers/analyzerslist.go @@ -68,6 +68,7 @@ func NewAnalyzerFilter(action bool, analyzerIDs ...string) AnalyzerFilter { var defaultAnalyzers = []AnalyzerDefinition{ {"G115", "Type conversion which leads to integer overflow", newConversionOverflowAnalyzer}, {"G602", "Possible slice bounds out of range", newSliceBoundsAnalyzer}, + {"G407", "Use of hardcoded IV/nonce for encryption", newHardCodedNonce}, } // Generate the list of analyzers to use diff --git a/analyzers/hardcodedNonce.go b/analyzers/hardcodedNonce.go index 2d1d343..5598c33 100644 --- a/analyzers/hardcodedNonce.go +++ b/analyzers/hardcodedNonce.go @@ -98,11 +98,13 @@ func raiseIssue(val *ssa.Value, funcsToTrack *map[string][]int, ssaFuncs []*ssa. // It goes and check if this function contains call to crypto/rand.Read in it's body(Assuming that calling crypto/rand.Read in a function, is used for the generation of nonce/iv ) case *ssa.Call: if calledFunction, ok := valType.Call.Value.(*ssa.Function); ok { - if contains, funcErr := isFuncContainsCryptoRand(calledFunction); !contains && funcErr != nil { + if contains, funcErr := isFuncContainsCryptoRand(calledFunction); !contains && funcErr == nil { issueDescription += " by passing a value from function which doesn't use crypto/rand" tmp, hasErr := iterateThroughReferrers(val, funcsToTrack, pass.Analyzer.Name, issueDescription, pass.Fset, issue.High, issue.Medium) gosecIssue = append(gosecIssue, tmp...) err = hasErr + } else if funcErr != nil { + err = funcErr } } diff --git a/rules/rules_test.go b/rules/rules_test.go index 036342a..9a7d65a 100644 --- a/rules/rules_test.go +++ b/rules/rules_test.go @@ -187,82 +187,6 @@ var _ = Describe("gosec rules", func() { runner("G406", testutils.SampleCodeG406b) }) - It("should detect hardcoded nonce/IV", func() { - runner("G407", testutils.SampleCodeG407) - }) - - It("should detect hardcoded nonce/IV", func() { - runner("G407", testutils.SampleCodeG407b) - }) - - It("should detect hardcoded nonce/IV", func() { - runner("G407", testutils.SampleCodeG407c) - }) - - It("should detect hardcoded nonce/IV", func() { - runner("G407", testutils.SampleCodeG407d) - }) - - It("should detect hardcoded nonce/IV", func() { - runner("G407", testutils.SampleCodeG407e) - }) - - It("should detect hardcoded nonce/IV", func() { - runner("G407", testutils.SampleCodeG407f) - }) - - It("should detect hardcoded nonce/IV", func() { - runner("G407", testutils.SampleCodeG407g) - }) - - It("should detect hardcoded nonce/IV", func() { - runner("G407", testutils.SampleCodeG407h) - }) - - It("should detect hardcoded nonce/IV", func() { - runner("G407", testutils.SampleCodeG407i) - }) - - It("should detect hardcoded nonce/IV", func() { - runner("G407", testutils.SampleCodeG407j) - }) - - It("should detect hardcoded nonce/IV", func() { - runner("G407", testutils.SampleCodeG407k) - }) - - It("should detect hardcoded nonce/IV", func() { - runner("G407", testutils.SampleCodeG407l) - }) - - It("should detect hardcoded nonce/IV", func() { - runner("G407", testutils.SampleCodeG407m) - }) - - It("should detect hardcoded nonce/IV", func() { - runner("G407", testutils.SampleCodeG407n) - }) - - It("should detect hardcoded nonce/IV", func() { - runner("G407", testutils.SampleCodeG407o) - }) - - It("should detect hardcoded nonce/IV", func() { - runner("G407", testutils.SampleCodeG407p) - }) - - It("should detect hardcoded nonce/IV", func() { - runner("G407", testutils.SampleCodeG407q) - }) - - It("should detect hardcoded nonce/IV", func() { - runner("G407", testutils.SampleCodeG407r) - }) - - It("should detect hardcoded nonce/IV", func() { - runner("G407", testutils.SampleCodeG407s) - }) - It("should detect blocklisted imports - MD5", func() { runner("G501", testutils.SampleCodeG501) }) diff --git a/testutils/g407_samples.go b/testutils/g407_samples.go index 6bd6c2a..3d1b153 100644 --- a/testutils/g407_samples.go +++ b/testutils/g407_samples.go @@ -5,6 +5,7 @@ import "github.com/securego/gosec/v2" var ( // SampleCodeG407 - Use of hardcoded nonce/IV SampleCodeG407 = []CodeSample{ + {[]string{`package main import ( @@ -21,11 +22,63 @@ func main() { aesOFB.XORKeyStream(output, []byte("Very Cool thing!")) fmt.Println(string(output)) -}`}, 1, gosec.NewConfig()}, - } +} +`}, 1, gosec.NewConfig()}, + + {[]string{`package main + +import ( + "crypto/aes" + "crypto/cipher" + "fmt" +) + +func main() { + + block, _ := aes.NewCipher([]byte{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}) + aesOFB := cipher.NewOFB(block, []byte("ILoveMyNonceAlot")) // #nosec G407 + var output = make([]byte, 16) + aesOFB.XORKeyStream(output, []byte("Very Cool thing!")) + fmt.Println(string(output)) + +} + +`}, 0, gosec.NewConfig()}, + + {[]string{`package main + +import ( + "crypto/aes" + "crypto/cipher" + "fmt" +) + +func main() { + + block, _ := aes.NewCipher( []byte{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}) + aesGCM, _ := cipher.NewGCM(block) + + cipherText := aesGCM.Seal(nil, func() []byte { + if true { + return []byte("ILoveMyNonce") + } else { + return []byte("IDont'Love..") + } + }(), []byte("My secret message"), nil) // #nosec G407 + fmt.Println(string(cipherText)) + + cipherText, _ = aesGCM.Open(nil, func() []byte { + if true { + return []byte("ILoveMyNonce") + } else { + return []byte("IDont'Love..") + } + }(), cipherText, nil) // #nosec G407 + + fmt.Println(string(cipherText)) +} +`}, 0, gosec.NewConfig()}, - // SampleCodeG407b - Use of hardcoded nonce/IV - SampleCodeG407b = []CodeSample{ {[]string{`package main import ( @@ -43,10 +96,7 @@ func main() { fmt.Println(string(output)) }`}, 1, gosec.NewConfig()}, - } - // SampleCodeG407c - Use of hardcoded nonce/IV - SampleCodeG407c = []CodeSample{ {[]string{`package main import ( @@ -64,10 +114,7 @@ func main() { fmt.Println(string(output)) }`}, 1, gosec.NewConfig()}, - } - // SampleCodeG407d - Use of hardcoded nonce/IV - SampleCodeG407d = []CodeSample{ {[]string{`package main import ( @@ -86,10 +133,7 @@ func main() { } `}, 1, gosec.NewConfig()}, - } - // SampleCodeG407e - Use of hardcoded nonce/IV - SampleCodeG407e = []CodeSample{ {[]string{`package main import ( @@ -109,10 +153,7 @@ func main() { fmt.Println(string(cipherText)) } `}, 2, gosec.NewConfig()}, - } - // SampleCodeG407f - Use of hardcoded nonce/IV - SampleCodeG407f = []CodeSample{ {[]string{`package main import ( @@ -132,10 +173,7 @@ func main() { fmt.Println(string(cipherText)) } `}, 2, gosec.NewConfig()}, - } - // SampleCodeG407g - Use of hardcoded nonce/IV - SampleCodeG407g = []CodeSample{ {[]string{`package main import ( @@ -156,10 +194,7 @@ func main() { fmt.Println(string(cipherText)) } `}, 2, gosec.NewConfig()}, - } - // SampleCodeG407h - Use of hardcoded nonce/IV - SampleCodeG407h = []CodeSample{ {[]string{`package main import ( @@ -193,10 +228,7 @@ func main() { fmt.Println(string(cipherText)) } `}, 2, gosec.NewConfig()}, - } - // SampleCodeG407I - Use of hardcoded nonce/IV - SampleCodeG407i = []CodeSample{ {[]string{`package main import ( @@ -229,10 +261,7 @@ func main() { fmt.Println(string(cipherText)) } `}, 2, gosec.NewConfig()}, - } - // SampleCodeG407j - Use of hardcoded nonce/IV - SampleCodeG407j = []CodeSample{ {[]string{`package main import ( @@ -252,10 +281,7 @@ func main() { } `}, 2, gosec.NewConfig()}, - } - // SampleCodeG407k - Use of hardcoded nonce/IV - SampleCodeG407k = []CodeSample{ {[]string{`package main import ( @@ -275,10 +301,7 @@ func main() { } `}, 2, gosec.NewConfig()}, - } - // SampleCodeG407l - Use of hardcoded nonce/IV - SampleCodeG407l = []CodeSample{ {[]string{`package main import ( @@ -299,10 +322,7 @@ func main() { fmt.Println(string(output)) }`}, 2, gosec.NewConfig()}, - } - // SampleCodeG407m - Use of hardcoded nonce/IV - SampleCodeG407m = []CodeSample{ {[]string{`package main import ( @@ -323,10 +343,7 @@ func main() { fmt.Println(string(output)) }`}, 2, gosec.NewConfig()}, - } - // SampleCodeG407n - Use of hardcoded nonce/IV - SampleCodeG407n = []CodeSample{ {[]string{`package main import ( @@ -349,10 +366,7 @@ func main() { fmt.Println(string(output)) }`}, 2, gosec.NewConfig()}, - } - // SampleCodeG407o - Use of hardcoded nonce/IV - SampleCodeG407o = []CodeSample{ {[]string{`package main import ( @@ -376,10 +390,7 @@ func main() { } `}, 2, gosec.NewConfig()}, - } - // SampleCodeG407p - Use of hardcoded nonce/IV - SampleCodeG407p = []CodeSample{ {[]string{`package main import ( @@ -396,10 +407,7 @@ func main() { fmt.Println(string(aesGCM.Seal(nil, nonce, []byte("My secret message"), nil))) } `}, 1, gosec.NewConfig()}, - } - // SampleCodeG407q - Use of hardcoded nonce/IV - SampleCodeG407q = []CodeSample{ {[]string{`package main import ( @@ -418,10 +426,7 @@ func main() { fmt.Println(string(output)) } `}, 1, gosec.NewConfig()}, - } - // SampleCodeG407r - Use of hardcoded nonce/IV - SampleCodeG407r = []CodeSample{ {[]string{`package main import ( @@ -447,15 +452,12 @@ func main() { fmt.Println(string(output)) } `}, 0, gosec.NewConfig()}, - } - // SampleCodeG407s - Use of hardcoded nonce/IV - SampleCodeG407s = []CodeSample{ + {[]string{`package main import ( "crypto/aes" "crypto/cipher" - "crypto/rand" "fmt" )