mirror of
https://github.com/securego/gosec.git
synced 2024-11-05 19:45:51 +00:00
58e4fccc13
Now the G401 rule is split into hashing and encryption algorithms. G401 is responsible for checking the usage of MD5 and SHA1, with corresponding CWE of 328. And G405(New rule) is responsible for checking the usege of DES and RC4, with corresponding CWE of 327.
149 lines
3.9 KiB
Go
149 lines
3.9 KiB
Go
package gosec_test
|
|
|
|
import (
|
|
"go/ast"
|
|
|
|
. "github.com/onsi/ginkgo/v2"
|
|
. "github.com/onsi/gomega"
|
|
|
|
"github.com/securego/gosec/v2"
|
|
"github.com/securego/gosec/v2/testutils"
|
|
)
|
|
|
|
var _ = Describe("Call List", func() {
|
|
var calls gosec.CallList
|
|
BeforeEach(func() {
|
|
calls = gosec.NewCallList()
|
|
})
|
|
|
|
It("should not return any matches when empty", func() {
|
|
Expect(calls.Contains("foo", "bar")).Should(BeFalse())
|
|
})
|
|
|
|
It("should be possible to add a single call", func() {
|
|
Expect(calls).Should(BeEmpty())
|
|
calls.Add("foo", "bar")
|
|
Expect(calls).Should(HaveLen(1))
|
|
|
|
expected := make(map[string]bool)
|
|
expected["bar"] = true
|
|
actual := map[string]bool(calls["foo"])
|
|
Expect(actual).Should(Equal(expected))
|
|
})
|
|
|
|
It("should be possible to add multiple calls at once", func() {
|
|
Expect(calls).Should(BeEmpty())
|
|
calls.AddAll("fmt", "Sprint", "Sprintf", "Printf", "Println")
|
|
|
|
expected := map[string]bool{
|
|
"Sprint": true,
|
|
"Sprintf": true,
|
|
"Printf": true,
|
|
"Println": true,
|
|
}
|
|
actual := map[string]bool(calls["fmt"])
|
|
Expect(actual).Should(Equal(expected))
|
|
})
|
|
|
|
It("should be possible to add pointer call", func() {
|
|
Expect(calls).Should(BeEmpty())
|
|
calls.Add("*bytes.Buffer", "WriteString")
|
|
actual := calls.ContainsPointer("*bytes.Buffer", "WriteString")
|
|
Expect(actual).Should(BeTrue())
|
|
})
|
|
|
|
It("should be possible to check pointer call", func() {
|
|
Expect(calls).Should(BeEmpty())
|
|
calls.Add("bytes.Buffer", "WriteString")
|
|
actual := calls.ContainsPointer("*bytes.Buffer", "WriteString")
|
|
Expect(actual).Should(BeTrue())
|
|
})
|
|
|
|
It("should not return a match if none are present", func() {
|
|
calls.Add("ioutil", "Copy")
|
|
Expect(calls.Contains("fmt", "Println")).Should(BeFalse())
|
|
})
|
|
|
|
It("should match a call based on selector and ident", func() {
|
|
calls.Add("ioutil", "Copy")
|
|
Expect(calls.Contains("ioutil", "Copy")).Should(BeTrue())
|
|
})
|
|
|
|
It("should match a package call expression", func() {
|
|
// Create file to be scanned
|
|
pkg := testutils.NewTestPackage()
|
|
defer pkg.Close()
|
|
pkg.AddFile("md5.go", testutils.SampleCodeG401[0].Code[0])
|
|
|
|
ctx := pkg.CreateContext("md5.go")
|
|
|
|
// Search for md5.New()
|
|
calls.Add("crypto/md5", "New")
|
|
|
|
// Stub out visitor and count number of matched call expr
|
|
matched := 0
|
|
v := testutils.NewMockVisitor()
|
|
v.Context = ctx
|
|
v.Callback = func(n ast.Node, ctx *gosec.Context) bool {
|
|
if _, ok := n.(*ast.CallExpr); ok && calls.ContainsPkgCallExpr(n, ctx, false) != nil {
|
|
matched++
|
|
}
|
|
return true
|
|
}
|
|
ast.Walk(v, ctx.Root)
|
|
Expect(matched).Should(Equal(1))
|
|
})
|
|
|
|
It("should match a package call expression", func() {
|
|
// Create file to be scanned
|
|
pkg := testutils.NewTestPackage()
|
|
defer pkg.Close()
|
|
pkg.AddFile("cipher.go", testutils.SampleCodeG405[0].Code[0])
|
|
|
|
ctx := pkg.CreateContext("cipher.go")
|
|
|
|
// Search for des.NewCipher()
|
|
calls.Add("crypto/des", "NewCipher")
|
|
|
|
// Stub out visitor and count number of matched call expr
|
|
matched := 0
|
|
v := testutils.NewMockVisitor()
|
|
v.Context = ctx
|
|
v.Callback = func(n ast.Node, ctx *gosec.Context) bool {
|
|
if _, ok := n.(*ast.CallExpr); ok && calls.ContainsPkgCallExpr(n, ctx, false) != nil {
|
|
matched++
|
|
}
|
|
return true
|
|
}
|
|
ast.Walk(v, ctx.Root)
|
|
Expect(matched).Should(Equal(1))
|
|
})
|
|
|
|
|
|
It("should match a call expression", func() {
|
|
// Create file to be scanned
|
|
pkg := testutils.NewTestPackage()
|
|
defer pkg.Close()
|
|
pkg.AddFile("main.go", testutils.SampleCodeG104[6].Code[0])
|
|
|
|
ctx := pkg.CreateContext("main.go")
|
|
|
|
calls.Add("bytes.Buffer", "WriteString")
|
|
calls.Add("strings.Builder", "WriteString")
|
|
calls.Add("io.Pipe", "CloseWithError")
|
|
calls.Add("fmt", "Fprintln")
|
|
|
|
// Stub out visitor and count number of matched call expr
|
|
matched := 0
|
|
v := testutils.NewMockVisitor()
|
|
v.Context = ctx
|
|
v.Callback = func(n ast.Node, ctx *gosec.Context) bool {
|
|
if _, ok := n.(*ast.CallExpr); ok && calls.ContainsCallExpr(n, ctx) != nil {
|
|
matched++
|
|
}
|
|
return true
|
|
}
|
|
ast.Walk(v, ctx.Root)
|
|
Expect(matched).Should(Equal(5))
|
|
})
|
|
})
|