Skip to content

Commit

Permalink
Migrated old test cases.
Browse files Browse the repository at this point in the history
  • Loading branch information
gcmurphy committed Dec 28, 2017
1 parent 25d74c6 commit e925d3c
Show file tree
Hide file tree
Showing 6 changed files with 562 additions and 40 deletions.
1 change: 1 addition & 0 deletions call_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ func (c CallList) ContainsCallExpr(n ast.Node, ctx *Context) *ast.CallExpr {
if err != nil {
return nil
}

// Try direct resolution
if c.Contains(selector, ident) {
return n.(*ast.CallExpr)
Expand Down
22 changes: 14 additions & 8 deletions rules/blacklist.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package rules

import (
"go/ast"
"strings"

"github.com/GoASTScanner/gas"
)
Expand All @@ -25,11 +26,16 @@ type blacklistedImport struct {
Blacklisted map[string]string
}

func (r *blacklistedImport) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err error) {
func unquote(original string) string {
copy := strings.TrimSpace(original)
copy = strings.TrimLeft(copy, `"`)
return strings.TrimRight(copy, `"`)
}

func (r *blacklistedImport) Match(n ast.Node, c *gas.Context) (*gas.Issue, error) {
if node, ok := n.(*ast.ImportSpec); ok {
description, ok := r.Blacklisted[node.Path.Value]
if ok && node.Name.String() != "_" {
return gas.NewIssue(c, n, description, r.Severity, r.Confidence), nil
if description, ok := r.Blacklisted[unquote(node.Path.Value)]; ok {
return gas.NewIssue(c, node, description, r.Severity, r.Confidence), nil
}
}
return nil, nil
Expand All @@ -50,27 +56,27 @@ func NewBlacklistedImports(conf gas.Config, blacklist map[string]string) (gas.Ru
// NewBlacklistedImportMD5 fails if MD5 is imported
func NewBlacklistedImportMD5(conf gas.Config) (gas.Rule, []ast.Node) {
return NewBlacklistedImports(conf, map[string]string{
"crypto/md5": "Use of weak cryptographic primitive",
"crypto/md5": "Blacklisted import crypto/md5: weak cryptographic primitive",
})
}

// NewBlacklistedImportDES fails if DES is imported
func NewBlacklistedImportDES(conf gas.Config) (gas.Rule, []ast.Node) {
return NewBlacklistedImports(conf, map[string]string{
"crypto/des": "Use of weak cryptographic primitive",
"crypto/des": "Blacklisted import crypto/des: weak cryptographic primitive",
})
}

// NewBlacklistedImportRC4 fails if DES is imported
func NewBlacklistedImportRC4(conf gas.Config) (gas.Rule, []ast.Node) {
return NewBlacklistedImports(conf, map[string]string{
"crypto/rc4": "Use of weak cryptographic primitive",
"crypto/rc4": "Blacklisted import crypto/rc4: weak cryptographic primitive",
})
}

// NewBlacklistedImportCGI fails if CGI is imported
func NewBlacklistedImportCGI(conf gas.Config) (gas.Rule, []ast.Node) {
return NewBlacklistedImports(conf, map[string]string{
"net/http/cgi": "Go versions < 1.6.3 are vulnerable to Httpoxy attack: (CVE-2016-5386)",
"net/http/cgi": "Blacklisted import net/http/cgi: Go versions < 1.6.3 are vulnerable to Httpoxy attack: (CVE-2016-5386)",
})
}
72 changes: 68 additions & 4 deletions rules/rules_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,86 @@ var _ = Describe("gas rules", func() {
})

Context("report correct errors for all samples", func() {
It("should work for G101 samples", func() {
It("should detect hardcoded credentials", func() {
runner("G101", testutils.SampleCodeG101)
})

It("should work for G102 samples", func() {
It("should detect binding to all network interfaces", func() {
runner("G102", testutils.SampleCodeG102)
})

It("should work for G103 samples", func() {
It("should use of unsafe block", func() {
runner("G103", testutils.SampleCodeG103)
})

It("should work for G104 samples", func() {
It("should errors not being checked", func() {
runner("G104", testutils.SampleCodeG104)
})

It("should detect of big.Exp function", func() {
runner("G105", testutils.SampleCodeG105)
})

It("should detect sql injection via format strings", func() {
runner("G201", testutils.SampleCodeG201)
})

It("should detect sql injection via string concatenation", func() {
runner("G202", testutils.SampleCodeG202)
})

It("should detect unescaped html in templates", func() {
runner("G203", testutils.SampleCodeG203)
})

It("should detect command execution", func() {
runner("G204", testutils.SampleCodeG204)
})

It("should detect poor file permissions on mkdir", func() {
runner("G301", testutils.SampleCodeG301)
})

It("should detect poor permissions when creating or chmod a file", func() {
runner("G302", testutils.SampleCodeG302)
})

It("should detect insecure temp file creation", func() {
runner("G303", testutils.SampleCodeG303)
})

It("should detect weak crypto algorithms", func() {
runner("G401", testutils.SampleCodeG401)
})

It("should find insecure tls settings", func() {
runner("G402", testutils.SampleCodeG402)
})

It("should detect weak creation of weak rsa keys", func() {
runner("G403", testutils.SampleCodeG403)
})

It("should find non cryptographically secure random number sources", func() {
runner("G404", testutils.SampleCodeG404)
})

It("should detect blacklisted imports - MD5", func() {
runner("G501", testutils.SampleCodeG501)
})

It("should detect blacklisted imports - DES", func() {
runner("G502", testutils.SampleCodeG502)
})

It("should detect blacklisted imports - RC4", func() {
runner("G503", testutils.SampleCodeG503)
})

It("should detect blacklisted imports - CGI (httpoxy)", func() {
runner("G504", testutils.SampleCodeG504)
})

})

})
3 changes: 2 additions & 1 deletion rules/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@ func NewTemplateCheck(conf gas.Config) (gas.Rule, []ast.Node) {
calls.Add("template", "HTML")
calls.Add("template", "HTMLAttr")
calls.Add("template", "JS")
calls.Add("template", "URL")
return &templateCheck{
calls: gas.NewCallList(),
calls: calls,
MetaData: gas.MetaData{
Severity: gas.Medium,
Confidence: gas.Low,
Expand Down
45 changes: 18 additions & 27 deletions rules/tls.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,23 +38,13 @@ func stringInSlice(a string, list []string) bool {
}

func (t *insecureConfigTLS) processTLSCipherSuites(n ast.Node, c *gas.Context) *gas.Issue {
tlsConfig := gas.MatchCompLit(n, c, t.requiredType)
if tlsConfig == nil {
return nil
}

for _, expr := range tlsConfig.Elts {
if keyvalExpr, ok := expr.(*ast.KeyValueExpr); ok {
if keyname, ok := keyvalExpr.Key.(*ast.Ident); ok && keyname.Name == "CipherSuites" {
if ciphers, ok := keyvalExpr.Value.(*ast.CompositeLit); ok {
for _, cipher := range ciphers.Elts {
if ident, ok := cipher.(*ast.SelectorExpr); ok {
if !stringInSlice(ident.Sel.Name, t.goodCiphers) {
str := fmt.Sprintf("TLS Bad Cipher Suite: %s", ident.Sel.Name)
return gas.NewIssue(c, n, str, gas.High, gas.High)
}
}
}
if ciphers, ok := n.(*ast.CompositeLit); ok {
for _, cipher := range ciphers.Elts {
if ident, ok := cipher.(*ast.SelectorExpr); ok {
if !stringInSlice(ident.Sel.Name, t.goodCiphers) {
err := fmt.Sprintf("TLS Bad Cipher Suite: %s", ident.Sel.Name)
return gas.NewIssue(c, ident, err, gas.High, gas.High)
}
}
}
Expand All @@ -65,6 +55,7 @@ func (t *insecureConfigTLS) processTLSCipherSuites(n ast.Node, c *gas.Context) *
func (t *insecureConfigTLS) processTLSConfVal(n *ast.KeyValueExpr, c *gas.Context) *gas.Issue {
if ident, ok := n.Key.(*ast.Ident); ok {
switch ident.Name {

case "InsecureSkipVerify":
if node, ok := n.Value.(*ast.Ident); ok {
if node.Name != "false" {
Expand Down Expand Up @@ -104,7 +95,7 @@ func (t *insecureConfigTLS) processTLSConfVal(n *ast.KeyValueExpr, c *gas.Contex
}

case "CipherSuites":
if ret := t.processTLSCipherSuites(n, c); ret != nil {
if ret := t.processTLSCipherSuites(n.Value, c); ret != nil {
return ret
}

Expand All @@ -114,24 +105,24 @@ func (t *insecureConfigTLS) processTLSConfVal(n *ast.KeyValueExpr, c *gas.Contex
return nil
}

func (t *insecureConfigTLS) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err error) {
if node := gas.MatchCompLit(n, c, t.requiredType); node != nil {
for _, elt := range node.Elts {
func (t *insecureConfigTLS) Match(n ast.Node, c *gas.Context) (*gas.Issue, error) {
if complit, ok := n.(*ast.CompositeLit); ok && c.Info.TypeOf(complit.Type).String() == t.requiredType {
for _, elt := range complit.Elts {
if kve, ok := elt.(*ast.KeyValueExpr); ok {
gi = t.processTLSConfVal(kve, c)
if gi != nil {
break
issue := t.processTLSConfVal(kve, c)
if issue != nil {
return issue, nil
}
}
}
}
return
return nil, nil
}

// NewModernTLSCheck see: https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility
func NewModernTLSCheck(conf gas.Config) (gas.Rule, []ast.Node) {
return &insecureConfigTLS{
requiredType: "tls.Config",
requiredType: "crypto/tls.Config",
MinVersion: 0x0303, // TLS 1.2 only
MaxVersion: 0x0303,
goodCiphers: []string{
Expand All @@ -146,7 +137,7 @@ func NewModernTLSCheck(conf gas.Config) (gas.Rule, []ast.Node) {
// NewIntermediateTLSCheck see: https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28default.29
func NewIntermediateTLSCheck(conf gas.Config) (gas.Rule, []ast.Node) {
return &insecureConfigTLS{
requiredType: "tls.Config",
requiredType: "crypto/tls.Config",
MinVersion: 0x0301, // TLS 1.2, 1.1, 1.0
MaxVersion: 0x0303,
goodCiphers: []string{
Expand All @@ -172,7 +163,7 @@ func NewIntermediateTLSCheck(conf gas.Config) (gas.Rule, []ast.Node) {
// NewCompatTLSCheck see: https://wiki.mozilla.org/Security/Server_Side_TLS#Old_compatibility_.28default.29
func NewCompatTLSCheck(conf gas.Config) (gas.Rule, []ast.Node) {
return &insecureConfigTLS{
requiredType: "tls.Config",
requiredType: "crypto/tls.Config",
MinVersion: 0x0301, // TLS 1.2, 1.1, 1.0
MaxVersion: 0x0303,
goodCiphers: []string{
Expand Down
Loading

0 comments on commit e925d3c

Please sign in to comment.