Add support for //gosec:disable directive (#1314)

This commit is contained in:
frozenbonito 2025-03-10 18:09:27 +09:00 committed by GitHub
parent e5fee17863
commit 57ec63392c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 753 additions and 43 deletions

View file

@ -304,7 +304,13 @@ You could put the description or justification text for the annotation. The
justification should be after the rule(s) to suppress and start with two or
more dashes, e.g: `//#nosec G101 G102 -- This is a false positive`
In some cases you may also want to revisit places where `#nosec` annotations
Alternatively, gosec also supports the `//gosec:disable` directive, which functions similar to `#nosec`:
```go
//gosec:disable G101 -- This is a false positive
```
In some cases you may also want to revisit places where `#nosec` or `//gosec:disable` annotations
have been used. To run the scanner and ignore any `#nosec` annotations you
can do the following:

View file

@ -57,6 +57,8 @@ const externalSuppressionJustification = "Globally suppressed."
const aliasOfAllRules = "*"
var directiveRegexp = regexp.MustCompile("^//gosec:disable(?: (.+))?$")
type ignore struct {
start int
end int
@ -582,23 +584,16 @@ func (gosec *Analyzer) ignore(n ast.Node) map[string]issue.SuppressionInfo {
}
for _, group := range groups {
comment := strings.TrimSpace(group.Text())
foundDefaultTag := strings.HasPrefix(comment, noSecDefaultTag) || regexp.MustCompile("\n *"+noSecDefaultTag).MatchString(comment)
foundAlternativeTag := strings.HasPrefix(comment, noSecAlternativeTag) || regexp.MustCompile("\n *"+noSecAlternativeTag).MatchString(comment)
if foundDefaultTag || foundAlternativeTag {
gosec.stats.NumNosec++
// Discard what's in front of the nosec tag.
if foundDefaultTag {
comment = strings.SplitN(comment, noSecDefaultTag, 2)[1]
} else {
comment = strings.SplitN(comment, noSecAlternativeTag, 2)[1]
found, args := findNoSecDirective(group, noSecDefaultTag, noSecAlternativeTag)
if !found {
continue
}
gosec.stats.NumNosec++
// Extract the directive and the justification.
justification := ""
commentParts := regexp.MustCompile(`-{2,}`).Split(comment, 2)
commentParts := regexp.MustCompile(`-{2,}`).Split(args, 2)
directive := commentParts[0]
if len(commentParts) > 1 {
justification = strings.TrimSpace(strings.TrimRight(commentParts[1], "\n"))
@ -625,10 +620,41 @@ func (gosec *Analyzer) ignore(n ast.Node) map[string]issue.SuppressionInfo {
}
return ignores
}
}
return nil
}
// findNoSecDirective checks if the comment group contains `#nosec` or `//gosec:disable` directive.
// If found, it returns true and the directive's arguments.
func findNoSecDirective(group *ast.CommentGroup, noSecDefaultTag, noSecAlternativeTag string) (bool, string) {
// Check if the comment grounp has a nosec comment.
for _, tag := range []string{noSecDefaultTag, noSecAlternativeTag} {
if found, args := findNoSecTag(group, tag); found {
return true, args
}
}
// Check if the comment group has a directive comment.
for _, c := range group.List {
match := directiveRegexp.FindStringSubmatch(c.Text)
if len(match) > 0 {
return true, match[0]
}
}
return false, ""
}
func findNoSecTag(group *ast.CommentGroup, tag string) (bool, string) {
comment := strings.TrimSpace(group.Text())
if strings.HasPrefix(comment, tag) || regexp.MustCompile("\n *"+tag).MatchString(comment) {
// Discard what's in front of the nosec tag.
return true, strings.SplitN(comment, tag, 2)[1]
}
return false, ""
}
// 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 {

View file

@ -230,6 +230,23 @@ var _ = Describe("Analyzer", func() {
Expect(nosecIssues).Should(BeEmpty())
})
It("should not report errors when a disable directive is present", func() {
sample := testutils.SampleCodeG401[0]
source := sample.Code[0]
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G401")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "h := md5.New()", "h := md5.New() //gosec:disable", 1)
nosecPackage.AddFile("md5.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 line comment is present", func() {
sample := testutils.SampleCodeG405[0]
source := sample.Code[0]
@ -247,6 +264,23 @@ var _ = Describe("Analyzer", func() {
Expect(nosecIssues).Should(BeEmpty())
})
It("should not report errors when a disable directive is present", func() {
sample := testutils.SampleCodeG405[0]
source := sample.Code[0]
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G405")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "c, e := des.NewCipher([]byte(\"mySecret\"))", "c, e := des.NewCipher([]byte(\"mySecret\")) //gosec:disable", 1)
nosecPackage.AddFile("cipher.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 line comment is present", func() {
sample := testutils.SampleCodeG406[0]
source := sample.Code[0]
@ -264,6 +298,23 @@ var _ = Describe("Analyzer", func() {
Expect(nosecIssues).Should(BeEmpty())
})
It("should not report errors when a disable directive is present", func() {
sample := testutils.SampleCodeG406[0]
source := sample.Code[0]
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G406")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "h := md4.New()", "h := md4.New() //gosec:disable", 1)
nosecPackage.AddFile("md4.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]
@ -333,6 +384,24 @@ 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 MD5 weak crypto usage
sample := testutils.SampleCodeG401[0]
source := sample.Code[0]
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G401")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "h := md5.New()", "h := md5.New() //gosec:disable G401", 1)
nosecPackage.AddFile("md5.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 DES weak crypto usage
sample := testutils.SampleCodeG405[0]
@ -351,6 +420,24 @@ 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 DES weak crypto usage
sample := testutils.SampleCodeG405[0]
source := sample.Code[0]
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G405")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "c, e := des.NewCipher([]byte(\"mySecret\"))", "c, e := des.NewCipher([]byte(\"mySecret\")) //gosec:disable G405", 1)
nosecPackage.AddFile("cipher.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 MD4 deprecated weak crypto usage
sample := testutils.SampleCodeG406[0]
@ -369,6 +456,24 @@ 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 MD4 deprecated weak crypto usage
sample := testutils.SampleCodeG406[0]
source := sample.Code[0]
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G406")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "h := md4.New()", "h := md4.New() //gosec:disable G406", 1)
nosecPackage.AddFile("md4.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]
@ -415,6 +520,52 @@ var _ = Describe("Analyzer", func() {
Expect(nosecIssues).Should(BeEmpty())
})
It("should not report errors when a disable directive block and line comment are present", func() {
sample := testutils.SampleCodeG101[26]
source := sample.Code[0]
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G101")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecPackage.AddFile("g101.go", source)
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 only a disable directive block is present", func() {
sample := testutils.SampleCodeG101[27]
source := sample.Code[0]
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G101")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecPackage.AddFile("g101.go", source)
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 single line nosec is present on a multi-line issue", func() {
sample := testutils.SampleCodeG112[4]
source := sample.Code[0]
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G112")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecPackage.AddFile("g112.go", source)
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 an exclude comment is present for a different rule", func() {
sample := testutils.SampleCodeG401[0]
source := sample.Code[0]
@ -432,6 +583,23 @@ 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.SampleCodeG401[0]
source := sample.Code[0]
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G401")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "h := md5.New()", "h := md5.New() //gosec:disable G301", 1)
nosecPackage.AddFile("md5.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 report errors when an exclude comment is present for a different rule", func() {
sample := testutils.SampleCodeG405[0]
source := sample.Code[0]
@ -449,6 +617,23 @@ 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.SampleCodeG405[0]
source := sample.Code[0]
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G405")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "c, e := des.NewCipher([]byte(\"mySecret\"))", "c, e := des.NewCipher([]byte(\"mySecret\")) //gosec:disable G301", 1)
nosecPackage.AddFile("cipher.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 report errors when an exclude comment is present for a different rule", func() {
sample := testutils.SampleCodeG406[0]
source := sample.Code[0]
@ -466,6 +651,23 @@ 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.SampleCodeG406[0]
source := sample.Code[0]
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G406")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "h := md4.New()", "h := md4.New() //gosec:disable G301", 1)
nosecPackage.AddFile("md4.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]
@ -485,6 +687,25 @@ 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.SampleCodeG401[0]
source := sample.Code[0]
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G401")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "h := md5.New()", "h := md5.New() //gosec:disable G301 G401", 1)
nosecPackage.AddFile("md5.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 not report errors when an exclude comment is present for multiple rules, including the correct rule", func() {
sample := testutils.SampleCodeG405[0]
source := sample.Code[0]
@ -504,6 +725,25 @@ 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.SampleCodeG405[0]
source := sample.Code[0]
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G405")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "c, e := des.NewCipher([]byte(\"mySecret\"))", "c, e := des.NewCipher([]byte(\"mySecret\")) //gosec:disable G301 G405", 1)
nosecPackage.AddFile("cipher.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 not report errors when an exclude comment is present for multiple rules, including the correct rule", func() {
sample := testutils.SampleCodeG406[0]
source := sample.Code[0]
@ -523,6 +763,25 @@ 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.SampleCodeG406[0]
source := sample.Code[0]
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G406")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "h := md4.New()", "h := md4.New() //gosec:disable G301 G406", 1)
nosecPackage.AddFile("md4.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]
@ -573,6 +832,29 @@ var _ = Describe("Analyzer", func() {
Expect(nosecIssues).Should(HaveLen(sample.Errors))
})
It("should be possible to overwrite disable directive, and report issues", func() {
// Rule for MD5 weak crypto usage
sample := testutils.SampleCodeG401[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, "G401")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "h := md5.New()", "h := md5.New() //gosec:disable", 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 possible to overwrite nosec comments, and report issues", func() {
// Rule for DES weak crypto usage
sample := testutils.SampleCodeG405[0]
@ -596,6 +878,29 @@ var _ = Describe("Analyzer", func() {
Expect(nosecIssues).Should(HaveLen(sample.Errors))
})
It("should be possible to overwrite disable directive comments, and report issues", func() {
// Rule for DES weak crypto usage
sample := testutils.SampleCodeG405[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, "G405")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "c, e := des.NewCipher([]byte(\"mySecret\"))", "c, e := des.NewCipher([]byte(\"mySecret\")) //gosec:disable", 1)
nosecPackage.AddFile("cipher.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", func() {
// Rule for MD4 weak crypto usage
sample := testutils.SampleCodeG406[0]
@ -619,6 +924,29 @@ var _ = Describe("Analyzer", func() {
Expect(nosecIssues).Should(HaveLen(sample.Errors))
})
It("should be possible to overwrite disable directive comments, and report issues", func() {
// Rule for MD4 weak crypto usage
sample := testutils.SampleCodeG406[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, "G406")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "h := md4.New()", "h := md4.New() //gosec:disable", 1)
nosecPackage.AddFile("md4.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]
@ -714,6 +1042,23 @@ var _ = Describe("Analyzer", func() {
Expect(nosecIssues).Should(BeEmpty())
})
It("should not report errors when disable directive is in front of a line", func() {
sample := testutils.SampleCodeG401[0]
source := sample.Code[0]
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G401")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "h := md5.New()", "//Some description\n//gosec:disable G401\nh := md5.New()", 1)
nosecPackage.AddFile("md5.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 nosec tag is in front of a line", func() {
sample := testutils.SampleCodeG405[0]
source := sample.Code[0]
@ -731,6 +1076,23 @@ var _ = Describe("Analyzer", func() {
Expect(nosecIssues).Should(BeEmpty())
})
It("should not report errors when disable directive is in front of a line", func() {
sample := testutils.SampleCodeG405[0]
source := sample.Code[0]
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G405")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "c, e := des.NewCipher([]byte(\"mySecret\"))", "//Some description\n//gosec:disable G405\nc, e := des.NewCipher([]byte(\"mySecret\"))", 1)
nosecPackage.AddFile("cipher.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 nosec tag is in front of a line", func() {
sample := testutils.SampleCodeG406[0]
source := sample.Code[0]
@ -748,6 +1110,23 @@ var _ = Describe("Analyzer", func() {
Expect(nosecIssues).Should(BeEmpty())
})
It("should not report errors when disable directive is in front of a line", func() {
sample := testutils.SampleCodeG406[0]
source := sample.Code[0]
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G406")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "h := md4.New()", "//Some description\n//gosec:disable G406\nh := md4.New()", 1)
nosecPackage.AddFile("md4.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]
@ -867,6 +1246,23 @@ var _ = Describe("Analyzer", func() {
Expect(nosecIssues).Should(HaveLen(sample.Errors))
})
It("should report errors when there are disable directives after a //gosec:disable WrongRuleList", func() {
sample := testutils.SampleCodeG401[0]
source := sample.Code[0]
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G401")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "h := md5.New()", "//gosec:disable G301\n//gosec:disable\nh := md5.New()", 1)
nosecPackage.AddFile("md5.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 report errors when there are nosec tags after a #nosec WrongRuleList annotation", func() {
sample := testutils.SampleCodeG405[0]
source := sample.Code[0]
@ -884,6 +1280,23 @@ var _ = Describe("Analyzer", func() {
Expect(nosecIssues).Should(HaveLen(sample.Errors))
})
It("should report errors when there are disable directives after a //gosec:disable WrongRuleList", func() {
sample := testutils.SampleCodeG405[0]
source := sample.Code[0]
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G405")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "c, e := des.NewCipher([]byte(\"mySecret\"))", "//gosec:disable G301\n//gosec:disable\nc, e := des.NewCipher([]byte(\"mySecret\"))", 1)
nosecPackage.AddFile("cipher.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 report errors when there are nosec tags after a #nosec WrongRuleList annotation", func() {
sample := testutils.SampleCodeG406[0]
source := sample.Code[0]
@ -901,6 +1314,23 @@ var _ = Describe("Analyzer", func() {
Expect(nosecIssues).Should(HaveLen(sample.Errors))
})
It("should report errors when there are disable directives after a //gosec:disable WrongRuleList", func() {
sample := testutils.SampleCodeG406[0]
source := sample.Code[0]
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G406")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "h := md4.New()", "//gosec:disable G301\n//gosec:disable\nh := md4.New()", 1)
nosecPackage.AddFile("md4.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]
@ -1365,6 +1795,26 @@ 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.SampleCodeG401[0]
source := sample.Code[0]
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G401")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "h := md5.New()", "h := md5.New() //gosec:disable G401 -- Justification", 1)
nosecPackage.AddFile("md5.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", func() {
sample := testutils.SampleCodeG405[0]
source := sample.Code[0]
@ -1385,6 +1835,26 @@ 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.SampleCodeG405[0]
source := sample.Code[0]
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G405")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "c, e := des.NewCipher([]byte(\"mySecret\"))", "c, e := des.NewCipher([]byte(\"mySecret\")) //gosec:disable G405 -- Justification", 1)
nosecPackage.AddFile("cipher.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", func() {
sample := testutils.SampleCodeG406[0]
source := sample.Code[0]
@ -1405,6 +1875,26 @@ 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.SampleCodeG406[0]
source := sample.Code[0]
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G406")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "h := md4.New()", "h := md4.New() //gosec:disable G406 -- Justification", 1)
nosecPackage.AddFile("md4.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]
@ -1425,6 +1915,26 @@ 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.SampleCodeG401[0]
source := sample.Code[0]
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G401")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "h := md5.New()", "h := md5.New() //gosec:disable", 1)
nosecPackage.AddFile("md5.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 violation is suppressed without certain rules", func() {
sample := testutils.SampleCodeG405[0]
source := sample.Code[0]
@ -1445,6 +1955,26 @@ 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.SampleCodeG405[0]
source := sample.Code[0]
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G405")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "c, e := des.NewCipher([]byte(\"mySecret\"))", "c, e := des.NewCipher([]byte(\"mySecret\")) //gosec:disable", 1)
nosecPackage.AddFile("cipher.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 violation is suppressed without certain rules", func() {
sample := testutils.SampleCodeG406[0]
source := sample.Code[0]
@ -1465,6 +1995,26 @@ 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.SampleCodeG406[0]
source := sample.Code[0]
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G406")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source, "h := md4.New()", "h := md4.New() //gosec:disable", 1)
nosecPackage.AddFile("md4.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]
@ -1618,6 +2168,27 @@ var _ = Describe("Analyzer", func() {
Expect(issues[0].Suppressions[0].Kind).To(Equal("inSource"))
})
It("should not report an error if the violation is suppressed on a struct filed", func() {
sample := testutils.SampleCodeG402[0]
source := sample.Code[0]
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G402")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecSource := strings.Replace(source,
"TLSClientConfig: &tls.Config{InsecureSkipVerify: true}",
"TLSClientConfig: &tls.Config{InsecureSkipVerify: true} //gosec:disable G402", 1)
nosecPackage.AddFile("tls.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"))
})
It("should not report an error if the violation is suppressed on multi-lien issue", func() {
source := `
package main
@ -1632,6 +2203,37 @@ f62e5bcda4fae4f82370da0c6f20697b8f8447ef
` + "`" + "//#nosec G101 -- false positive, this is not a private data" + `
func main() {
fmt.Printf("Label: %s ", TokenLabel)
}
`
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G101")).RulesInfo())
nosecPackage := testutils.NewTestPackage()
defer nosecPackage.Close()
nosecPackage.AddFile("pwd.go", source)
err := nosecPackage.Build()
Expect(err).ShouldNot(HaveOccurred())
err = analyzer.Process(buildTags, nosecPackage.Path)
Expect(err).ShouldNot(HaveOccurred())
issues, _, _ := analyzer.Report()
Expect(issues).To(HaveLen(1))
Expect(issues[0].Suppressions).To(HaveLen(1))
Expect(issues[0].Suppressions[0].Kind).To(Equal("inSource"))
Expect(issues[0].Suppressions[0].Justification).To(Equal("false positive, this is not a private data"))
})
It("should not report an error if the violation is suppressed on multi-lien issue", func() {
source := `
package main
import (
"fmt"
)
const TokenLabel = `
source += "`" + `
f62e5bcda4fae4f82370da0c6f20697b8f8447ef
` + "`" + "//gosec:disable G101 -- false positive, this is not a private data" + `
func main() {
fmt.Printf("Label: %s ", TokenLabel)
}
`
analyzer.LoadRules(rules.Generate(false, rules.NewRuleFilter(false, "G101")).RulesInfo())

View file

@ -321,6 +321,50 @@ func main() {
fmt.Printf("%s\n", ConfigLearnerTokenAuth)
}
`}, 0, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
//gosec:disable G101
const (
ConfigLearnerTokenAuth string = "learner_auth_token_config" //gosec:disable G101
)
func main() {
fmt.Printf("%s\n", ConfigLearnerTokenAuth)
}
`}, 0, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
//gosec:disable G101
const (
ConfigLearnerTokenAuth string = "learner_auth_token_config"
)
func main() {
fmt.Printf("%s\n", ConfigLearnerTokenAuth)
}
`}, 0, gosec.NewConfig()},
{[]string{`
package main
import "fmt"
const (
ConfigLearnerTokenAuth string = "learner_auth_token_config" //gosec:disable G101
)
func main() {
fmt.Printf("%s\n", ConfigLearnerTokenAuth)
}
`}, 0, gosec.NewConfig()},
}

View file

@ -98,6 +98,38 @@ func New(listenAddr string) *Server {
}
}
func main() {
fmt.Print("test")
}
`}, 0, gosec.NewConfig()},
{[]string{`
package main
import (
"fmt"
"net/http"
"sync"
)
type Server struct {
hs *http.Server
mux *http.ServeMux
mu sync.Mutex
}
func New(listenAddr string) *Server {
mux := http.NewServeMux()
return &Server{
hs: &http.Server{ //gosec:disable G112 - Not publicly exposed
Addr: listenAddr,
Handler: mux,
},
mux: mux,
mu: sync.Mutex{},
}
}
func main() {
fmt.Print("test")
}