Skip to content

Commit d3f1980

Browse files
wongherlungCosmin Cojocar
authored andcommitted
Fix false positives for SQL string concatenation with constants from another file (#247)
* Allow for SQL concatenation of nodes that resolve to literals If node.Y resolves to a literal, it will not be considered as an issue. * Fix typo in comment. * Go through all files in package to resolve that identifier * Refactor code and added comments. * Changed checking to not var or func. * Allow for supporting code for test cases. * Resolve merge conflict changes.
1 parent 5f98926 commit d3f1980

File tree

5 files changed

+115
-66
lines changed

5 files changed

+115
-66
lines changed

analyzer.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ type Context struct {
3939
Comments ast.CommentMap
4040
Info *types.Info
4141
Pkg *types.Package
42+
PkgFiles []*ast.File
4243
Root *ast.File
4344
Config map[string]interface{}
4445
Imports *ImportTracker
@@ -139,6 +140,7 @@ func (gosec *Analyzer) Process(buildTags []string, packagePaths ...string) error
139140
gosec.context.Root = file
140141
gosec.context.Info = &pkg.Info
141142
gosec.context.Pkg = pkg.Pkg
143+
gosec.context.PkgFiles = pkg.Files
142144
gosec.context.Imports = NewImportTracker()
143145
gosec.context.Imports.TrackPackages(gosec.context.Pkg.Imports()...)
144146
ast.Walk(gosec, file)

resolve.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ func resolveCallExpr(n *ast.CallExpr, c *Context) bool {
5656

5757
// TryResolve will attempt, given a subtree starting at some ATS node, to resolve
5858
// all values contained within to a known constant. It is used to check for any
59-
// unkown values in compound expressions.
59+
// unknown values in compound expressions.
6060
func TryResolve(n ast.Node, c *Context) bool {
6161
switch node := n.(type) {
6262
case *ast.BasicLit:

rules/rules_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,24 @@ var _ = Describe("gosec rules", func() {
2828
analyzer = gosec.NewAnalyzer(config, logger)
2929
runner = func(rule string, samples []testutils.CodeSample) {
3030
analyzer.LoadRules(rules.Generate(rules.NewRuleFilter(false, rule)).Builders())
31+
32+
supportingFiles := []string{}
33+
for _, sample := range samples {
34+
if sample.SupportingCode {
35+
supportingFiles = append(supportingFiles, sample.Code)
36+
}
37+
}
38+
3139
for n, sample := range samples {
40+
if sample.SupportingCode {
41+
continue
42+
}
3243
analyzer.Reset()
3344
pkg := testutils.NewTestPackage()
3445
defer pkg.Close()
46+
for n, supportingCode := range supportingFiles {
47+
pkg.AddFile(fmt.Sprintf("supporting_sample_%d.go", n), supportingCode)
48+
}
3549
pkg.AddFile(fmt.Sprintf("sample_%d.go", n), sample.Code)
3650
err := pkg.Build()
3751
Expect(err).ShouldNot(HaveOccurred())

rules/sql.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,17 @@ func (s *sqlStrConcat) ID() string {
5151
}
5252

5353
// see if we can figure out what it is
54-
func (s *sqlStrConcat) checkObject(n *ast.Ident) bool {
54+
func (s *sqlStrConcat) checkObject(n *ast.Ident, c *gosec.Context) bool {
5555
if n.Obj != nil {
5656
return n.Obj.Kind != ast.Var && n.Obj.Kind != ast.Fun
5757
}
58+
59+
// Try to resolve unresolved identifiers using other files in same package
60+
for _, file := range c.PkgFiles {
61+
if node, ok := file.Scope.Objects[n.String()]; ok {
62+
return node.Kind != ast.Var && node.Kind != ast.Fun
63+
}
64+
}
5865
return false
5966
}
6067

@@ -69,7 +76,7 @@ func (s *sqlStrConcat) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error)
6976
if _, ok := node.Y.(*ast.BasicLit); ok {
7077
return nil, nil // string cat OK
7178
}
72-
if second, ok := node.Y.(*ast.Ident); ok && s.checkObject(second) {
79+
if second, ok := node.Y.(*ast.Ident); ok && s.checkObject(second, c) {
7380
return nil, nil
7481
}
7582
return gosec.NewIssue(c, n, s.ID(), s.What, s.Severity, s.Confidence), nil

0 commit comments

Comments
 (0)