Merge pull request #83 from GoASTScanner/experimental

Adjust rule interface to allow interest in multiple ast node types
This commit is contained in:
Grant Murphy 2016-11-13 13:08:58 -08:00 committed by GitHub
commit 93016846d2
18 changed files with 157 additions and 122 deletions

View file

@ -142,7 +142,8 @@ func (gas *Analyzer) process(filename string, source interface{}) error {
// AddRule adds a rule into a rule set list mapped to the given AST node's type. // AddRule adds a rule into a rule set list mapped to the given AST node's type.
// The node is only needed for its type and is not otherwise used. // The node is only needed for its type and is not otherwise used.
func (gas *Analyzer) AddRule(r Rule, n ast.Node) { func (gas *Analyzer) AddRule(r Rule, nodes []ast.Node) {
for _, n := range nodes {
t := reflect.TypeOf(n) t := reflect.TypeOf(n)
if val, ok := gas.ruleset[t]; ok { if val, ok := gas.ruleset[t]; ok {
gas.ruleset[t] = append(val, r) gas.ruleset[t] = append(val, r)
@ -150,6 +151,7 @@ func (gas *Analyzer) AddRule(r Rule, n ast.Node) {
gas.ruleset[t] = []Rule{r} gas.ruleset[t] = []Rule{r}
} }
} }
}
// Process reads in a source file, convert it to an AST and traverse it. // Process reads in a source file, convert it to an AST and traverse it.
// Rule methods added with AddRule will be invoked as necessary. // Rule methods added with AddRule will be invoked as necessary.

View file

@ -23,7 +23,7 @@ import (
type RuleInfo struct { type RuleInfo struct {
description string description string
build func(map[string]interface{}) (gas.Rule, ast.Node) build func(map[string]interface{}) (gas.Rule, []ast.Node)
} }
// GetFullRuleList get the full list of all rules available to GAS // GetFullRuleList get the full list of all rules available to GAS

View file

@ -39,8 +39,8 @@ func (r *BindsToAllNetworkInterfaces) Match(n ast.Node, c *gas.Context) (gi *gas
return return
} }
func NewBindsToAllNetworkInterfaces(conf map[string]interface{}) (r gas.Rule, n ast.Node) { func NewBindsToAllNetworkInterfaces(conf map[string]interface{}) (gas.Rule, []ast.Node) {
r = &BindsToAllNetworkInterfaces{ return &BindsToAllNetworkInterfaces{
call: regexp.MustCompile(`^net\.Listen$`), call: regexp.MustCompile(`^net\.Listen$`),
pattern: regexp.MustCompile(`^(0.0.0.0|:).*$`), pattern: regexp.MustCompile(`^(0.0.0.0|:).*$`),
MetaData: gas.MetaData{ MetaData: gas.MetaData{
@ -48,7 +48,5 @@ func NewBindsToAllNetworkInterfaces(conf map[string]interface{}) (r gas.Rule, n
Confidence: gas.High, Confidence: gas.High,
What: "Binds to all network interfaces", What: "Binds to all network interfaces",
}, },
} }, []ast.Node{(*ast.CallExpr)(nil)}
n = (*ast.CallExpr)(nil)
return
} }

View file

@ -34,54 +34,46 @@ func (r *BlacklistImport) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err
return nil, nil return nil, nil
} }
func NewBlacklist_crypto_md5(conf map[string]interface{}) (r gas.Rule, n ast.Node) { func NewBlacklist_crypto_md5(conf map[string]interface{}) (gas.Rule, []ast.Node) {
r = &BlacklistImport{ return &BlacklistImport{
MetaData: gas.MetaData{ MetaData: gas.MetaData{
Severity: gas.High, Severity: gas.High,
Confidence: gas.High, Confidence: gas.High,
What: "Use of weak cryptographic primitive", What: "Use of weak cryptographic primitive",
}, },
Path: `"crypto/md5"`, Path: `"crypto/md5"`,
} }, []ast.Node{(*ast.ImportSpec)(nil)}
n = (*ast.ImportSpec)(nil)
return
} }
func NewBlacklist_crypto_des(conf map[string]interface{}) (r gas.Rule, n ast.Node) { func NewBlacklist_crypto_des(conf map[string]interface{}) (gas.Rule, []ast.Node) {
r = &BlacklistImport{ return &BlacklistImport{
MetaData: gas.MetaData{ MetaData: gas.MetaData{
Severity: gas.High, Severity: gas.High,
Confidence: gas.High, Confidence: gas.High,
What: "Use of weak cryptographic primitive", What: "Use of weak cryptographic primitive",
}, },
Path: `"crypto/des"`, Path: `"crypto/des"`,
} }, []ast.Node{(*ast.ImportSpec)(nil)}
n = (*ast.ImportSpec)(nil)
return
} }
func NewBlacklist_crypto_rc4(conf map[string]interface{}) (r gas.Rule, n ast.Node) { func NewBlacklist_crypto_rc4(conf map[string]interface{}) (gas.Rule, []ast.Node) {
r = &BlacklistImport{ return &BlacklistImport{
MetaData: gas.MetaData{ MetaData: gas.MetaData{
Severity: gas.High, Severity: gas.High,
Confidence: gas.High, Confidence: gas.High,
What: "Use of weak cryptographic primitive", What: "Use of weak cryptographic primitive",
}, },
Path: `"crypto/rc4"`, Path: `"crypto/rc4"`,
} }, []ast.Node{(*ast.ImportSpec)(nil)}
n = (*ast.ImportSpec)(nil)
return
} }
func NewBlacklist_net_http_cgi(conf map[string]interface{}) (r gas.Rule, n ast.Node) { func NewBlacklist_net_http_cgi(conf map[string]interface{}) (gas.Rule, []ast.Node) {
r = &BlacklistImport{ return &BlacklistImport{
MetaData: gas.MetaData{ MetaData: gas.MetaData{
Severity: gas.High, Severity: gas.High,
Confidence: gas.High, Confidence: gas.High,
What: "Go code running under CGI is vulnerable to Httpoxy attack. (CVE-2016-5386)", What: "Go versions < 1.6.3 are vulnerable to Httpoxy attack: (CVE-2016-5386)",
}, },
Path: `"net/http/cgi"`, Path: `"net/http/cgi"`,
} }, []ast.Node{(*ast.ImportSpec)(nil)}
n = (*ast.ImportSpec)(nil)
return
} }

View file

@ -50,14 +50,12 @@ func (r *NoErrorCheck) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err err
return nil, nil return nil, nil
} }
func NewNoErrorCheck(conf map[string]interface{}) (r gas.Rule, n ast.Node) { func NewNoErrorCheck(conf map[string]interface{}) (gas.Rule, []ast.Node) {
r = &NoErrorCheck{ return &NoErrorCheck{
MetaData: gas.MetaData{ MetaData: gas.MetaData{
Severity: gas.Low, Severity: gas.Low,
Confidence: gas.High, Confidence: gas.High,
What: "Errors unhandled.", What: "Errors unhandled.",
}, },
} }, []ast.Node{(*ast.AssignStmt)(nil)}
n = (*ast.AssignStmt)(nil)
return
} }

View file

@ -52,7 +52,7 @@ func (r *FilePermissions) Match(n ast.Node, c *gas.Context) (*gas.Issue, error)
return nil, nil return nil, nil
} }
func NewFilePerms(conf map[string]interface{}) (gas.Rule, ast.Node) { func NewFilePerms(conf map[string]interface{}) (gas.Rule, []ast.Node) {
mode := getConfiguredMode(conf, "G302", 0600) mode := getConfiguredMode(conf, "G302", 0600)
return &FilePermissions{ return &FilePermissions{
mode: mode, mode: mode,
@ -63,10 +63,10 @@ func NewFilePerms(conf map[string]interface{}) (gas.Rule, ast.Node) {
Confidence: gas.High, Confidence: gas.High,
What: fmt.Sprintf("Expect file permissions to be %#o or less", mode), What: fmt.Sprintf("Expect file permissions to be %#o or less", mode),
}, },
}, (*ast.CallExpr)(nil) }, []ast.Node{(*ast.CallExpr)(nil)}
} }
func NewMkdirPerms(conf map[string]interface{}) (gas.Rule, ast.Node) { func NewMkdirPerms(conf map[string]interface{}) (gas.Rule, []ast.Node) {
mode := getConfiguredMode(conf, "G301", 0700) mode := getConfiguredMode(conf, "G301", 0700)
return &FilePermissions{ return &FilePermissions{
mode: mode, mode: mode,
@ -77,5 +77,5 @@ func NewMkdirPerms(conf map[string]interface{}) (gas.Rule, ast.Node) {
Confidence: gas.High, Confidence: gas.High,
What: fmt.Sprintf("Expect directory permissions to be %#o or less", mode), What: fmt.Sprintf("Expect directory permissions to be %#o or less", mode),
}, },
}, (*ast.CallExpr)(nil) }, []ast.Node{(*ast.CallExpr)(nil)}
} }

View file

@ -15,43 +15,71 @@
package rules package rules
import ( import (
"go/ast"
"regexp"
gas "github.com/GoASTScanner/gas/core" gas "github.com/GoASTScanner/gas/core"
"go/ast"
"go/token"
"regexp"
) )
type CredsAssign struct { type Credentials struct {
gas.MetaData gas.MetaData
pattern *regexp.Regexp pattern *regexp.Regexp
} }
func (r *CredsAssign) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err error) { func (r *Credentials) Match(n ast.Node, ctx *gas.Context) (*gas.Issue, error) {
if node, ok := n.(*ast.AssignStmt); ok { switch node := n.(type) {
for _, i := range node.Lhs { case *ast.AssignStmt:
if ident, ok := i.(*ast.Ident); ok { return r.matchAssign(node, ctx)
if r.pattern.MatchString(ident.Name) { case *ast.GenDecl:
for _, e := range node.Rhs { return r.matchGenDecl(node, ctx)
if _, ok := e.(*ast.BasicLit); ok {
return gas.NewIssue(c, n, r.What, r.Severity, r.Confidence), nil
} }
} return nil, nil
}
}
}
}
return
} }
func NewHardcodedCredentials(conf map[string]interface{}) (r gas.Rule, n ast.Node) { func (r *Credentials) matchAssign(assign *ast.AssignStmt, ctx *gas.Context) (*gas.Issue, error) {
r = &CredsAssign{ for _, i := range assign.Lhs {
pattern: regexp.MustCompile(`(?i)passwd|pass|password|pwd|secret|token`), if ident, ok := i.(*ast.Ident); ok {
if r.pattern.MatchString(ident.Name) {
for _, e := range assign.Rhs {
if _, ok := e.(*ast.BasicLit); ok {
return gas.NewIssue(ctx, assign, r.What, r.Severity, r.Confidence), nil
}
}
}
}
}
return nil, nil
}
func (r *Credentials) matchGenDecl(decl *ast.GenDecl, ctx *gas.Context) (*gas.Issue, error) {
if decl.Tok != token.CONST && decl.Tok != token.VAR {
return nil, nil
}
for _, spec := range decl.Specs {
if valueSpec, ok := spec.(*ast.ValueSpec); ok {
for index, ident := range valueSpec.Names {
if r.pattern.MatchString(ident.Name) {
if _, ok := valueSpec.Values[index].(*ast.BasicLit); ok {
return gas.NewIssue(ctx, decl, r.What, r.Severity, r.Confidence), nil
}
}
}
}
}
return nil, nil
}
func NewHardcodedCredentials(conf map[string]interface{}) (gas.Rule, []ast.Node) {
pattern := `(?i)passwd|pass|password|pwd|secret|token`
if val, ok := conf["G101"]; ok {
pattern = val.(string)
}
return &Credentials{
pattern: regexp.MustCompile(pattern),
MetaData: gas.MetaData{ MetaData: gas.MetaData{
What: "Potential hardcoded credentials", What: "Potential hardcoded credentials",
Confidence: gas.Low, Confidence: gas.Low,
Severity: gas.High, Severity: gas.High,
}, },
} }, []ast.Node{(*ast.AssignStmt)(nil), (*ast.GenDecl)(nil)}
n = (*ast.AssignStmt)(nil)
return
} }

View file

@ -39,3 +39,43 @@ func TestHardcoded(t *testing.T) {
checkTestResults(t, issues, 1, "Potential hardcoded credentials") checkTestResults(t, issues, 1, "Potential hardcoded credentials")
} }
func TestHardcodedGlobalVar(t *testing.T) {
config := map[string]interface{}{"ignoreNosec": false}
analyzer := gas.NewAnalyzer(config, nil)
analyzer.AddRule(NewHardcodedCredentials(config))
issues := gasTestRunner(`
package samples
import "fmt"
var password = "admin"
func main() {
username := "admin"
fmt.Println("Doing something with: ", username, password)
}`, analyzer)
checkTestResults(t, issues, 1, "Potential hardcoded credentials")
}
func TestHardcodedConstant(t *testing.T) {
config := map[string]interface{}{"ignoreNosec": false}
analyzer := gas.NewAnalyzer(config, nil)
analyzer.AddRule(NewHardcodedCredentials(config))
issues := gasTestRunner(`
package samples
import "fmt"
const password = "secret"
func main() {
username := "admin"
fmt.Println("Doing something with: ", username, password)
}`, analyzer)
checkTestResults(t, issues, 1, "Potential hardcoded credentials")
}

View file

@ -32,5 +32,5 @@ func TestHttpoxy(t *testing.T) {
) )
func main() {}`, analyzer) func main() {}`, analyzer)
checkTestResults(t, issues, 1, "Go code running under CGI is vulnerable to Httpoxy attack.") checkTestResults(t, issues, 1, "Go versions < 1.6.3 are vulnerable to Httpoxy")
} }

View file

@ -34,8 +34,8 @@ func (w *WeakRand) Match(n ast.Node, c *gas.Context) (*gas.Issue, error) {
return nil, nil return nil, nil
} }
func NewWeakRandCheck(conf map[string]interface{}) (r gas.Rule, n ast.Node) { func NewWeakRandCheck(conf map[string]interface{}) (gas.Rule, []ast.Node) {
r = &WeakRand{ return &WeakRand{
funcName: "Read", funcName: "Read",
packagePath: "math/rand", packagePath: "math/rand",
MetaData: gas.MetaData{ MetaData: gas.MetaData{
@ -43,7 +43,5 @@ func NewWeakRandCheck(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
Confidence: gas.Medium, Confidence: gas.Medium,
What: "Use of weak random number generator (math/rand instead of crypto/rand)", What: "Use of weak random number generator (math/rand instead of crypto/rand)",
}, },
} }, []ast.Node{(*ast.CallExpr)(nil)}
n = (*ast.CallExpr)(nil)
return
} }

View file

@ -37,9 +37,9 @@ func (w *WeakKeyStrength) Match(n ast.Node, c *gas.Context) (*gas.Issue, error)
return nil, nil return nil, nil
} }
func NewWeakKeyStrength(conf map[string]interface{}) (r gas.Rule, n ast.Node) { func NewWeakKeyStrength(conf map[string]interface{}) (gas.Rule, []ast.Node) {
bits := 2048 bits := 2048
r = &WeakKeyStrength{ return &WeakKeyStrength{
pattern: regexp.MustCompile(`^rsa\.GenerateKey$`), pattern: regexp.MustCompile(`^rsa\.GenerateKey$`),
bits: bits, bits: bits,
MetaData: gas.MetaData{ MetaData: gas.MetaData{
@ -47,7 +47,5 @@ func NewWeakKeyStrength(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
Confidence: gas.High, Confidence: gas.High,
What: fmt.Sprintf("RSA keys should be at least %d bits", bits), What: fmt.Sprintf("RSA keys should be at least %d bits", bits),
}, },
} }, []ast.Node{(*ast.CallExpr)(nil)}
n = (*ast.CallExpr)(nil)
return
} }

View file

@ -56,8 +56,8 @@ func (s *SqlStrConcat) Match(n ast.Node, c *gas.Context) (*gas.Issue, error) {
return nil, nil return nil, nil
} }
func NewSqlStrConcat(conf map[string]interface{}) (r gas.Rule, n ast.Node) { func NewSqlStrConcat(conf map[string]interface{}) (gas.Rule, []ast.Node) {
r = &SqlStrConcat{ return &SqlStrConcat{
SqlStatement: SqlStatement{ SqlStatement: SqlStatement{
pattern: regexp.MustCompile(`(?)(SELECT|DELETE|INSERT|UPDATE|INTO|FROM|WHERE) `), pattern: regexp.MustCompile(`(?)(SELECT|DELETE|INSERT|UPDATE|INTO|FROM|WHERE) `),
MetaData: gas.MetaData{ MetaData: gas.MetaData{
@ -66,9 +66,7 @@ func NewSqlStrConcat(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
What: "SQL string concatenation", What: "SQL string concatenation",
}, },
}, },
} }, []ast.Node{(*ast.BinaryExpr)(nil)}
n = (*ast.BinaryExpr)(nil)
return
} }
type SqlStrFormat struct { type SqlStrFormat struct {
@ -86,8 +84,8 @@ func (s *SqlStrFormat) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err err
return nil, nil return nil, nil
} }
func NewSqlStrFormat(conf map[string]interface{}) (r gas.Rule, n ast.Node) { func NewSqlStrFormat(conf map[string]interface{}) (gas.Rule, []ast.Node) {
r = &SqlStrFormat{ return &SqlStrFormat{
call: regexp.MustCompile(`^fmt\.Sprintf$`), call: regexp.MustCompile(`^fmt\.Sprintf$`),
SqlStatement: SqlStatement{ SqlStatement: SqlStatement{
pattern: regexp.MustCompile("(?)(SELECT|DELETE|INSERT|UPDATE|INTO|FROM|WHERE) "), pattern: regexp.MustCompile("(?)(SELECT|DELETE|INSERT|UPDATE|INTO|FROM|WHERE) "),
@ -97,7 +95,5 @@ func NewSqlStrFormat(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
What: "SQL string formatting", What: "SQL string formatting",
}, },
}, },
} }, []ast.Node{(*ast.CallExpr)(nil)}
n = (*ast.CallExpr)(nil)
return
} }

View file

@ -49,10 +49,8 @@ func (r *Subprocess) Match(n ast.Node, c *gas.Context) (*gas.Issue, error) {
return nil, nil return nil, nil
} }
func NewSubproc(conf map[string]interface{}) (r gas.Rule, n ast.Node) { func NewSubproc(conf map[string]interface{}) (gas.Rule, []ast.Node) {
r = &Subprocess{ return &Subprocess{
pattern: regexp.MustCompile(`^exec\.Command|syscall\.Exec$`), pattern: regexp.MustCompile(`^exec\.Command|syscall\.Exec$`),
} }, []ast.Node{(*ast.CallExpr)(nil)}
n = (*ast.CallExpr)(nil)
return
} }

View file

@ -36,8 +36,8 @@ func (t *BadTempFile) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err erro
return nil, nil return nil, nil
} }
func NewBadTempFile(conf map[string]interface{}) (r gas.Rule, n ast.Node) { func NewBadTempFile(conf map[string]interface{}) (gas.Rule, []ast.Node) {
r = &BadTempFile{ return &BadTempFile{
call: regexp.MustCompile(`ioutil\.WriteFile|os\.Create`), call: regexp.MustCompile(`ioutil\.WriteFile|os\.Create`),
args: regexp.MustCompile(`^/tmp/.*$|^/var/tmp/.*$`), args: regexp.MustCompile(`^/tmp/.*$|^/var/tmp/.*$`),
MetaData: gas.MetaData{ MetaData: gas.MetaData{
@ -45,7 +45,5 @@ func NewBadTempFile(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
Confidence: gas.High, Confidence: gas.High,
What: "File creation in shared tmp directory without using ioutil.Tempfile", What: "File creation in shared tmp directory without using ioutil.Tempfile",
}, },
} }, []ast.Node{(*ast.CallExpr)(nil)}
n = (*ast.CallExpr)(nil)
return
} }

View file

@ -37,15 +37,13 @@ func (t *TemplateCheck) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err er
return nil, nil return nil, nil
} }
func NewTemplateCheck(conf map[string]interface{}) (r gas.Rule, n ast.Node) { func NewTemplateCheck(conf map[string]interface{}) (gas.Rule, []ast.Node) {
r = &TemplateCheck{ return &TemplateCheck{
call: regexp.MustCompile(`^template\.(HTML|JS|URL)$`), call: regexp.MustCompile(`^template\.(HTML|JS|URL)$`),
MetaData: gas.MetaData{ MetaData: gas.MetaData{
Severity: gas.Medium, Severity: gas.Medium,
Confidence: gas.Low, Confidence: gas.Low,
What: "this method will not auto-escape HTML. Verify data is well formed.", What: "this method will not auto-escape HTML. Verify data is well formed.",
}, },
} }, []ast.Node{(*ast.CallExpr)(nil)}
n = (*ast.CallExpr)(nil)
return
} }

View file

@ -109,9 +109,9 @@ func (t *InsecureConfigTLS) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, er
return return
} }
func NewModernTlsCheck(conf map[string]interface{}) (r gas.Rule, n ast.Node) { func NewModernTlsCheck(conf map[string]interface{}) (gas.Rule, []ast.Node) {
// https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility // https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility
r = &InsecureConfigTLS{ return &InsecureConfigTLS{
pattern: regexp.MustCompile(`^tls\.Config$`), pattern: regexp.MustCompile(`^tls\.Config$`),
MinVersion: 0x0303, // TLS 1.2 only MinVersion: 0x0303, // TLS 1.2 only
MaxVersion: 0x0303, MaxVersion: 0x0303,
@ -121,14 +121,12 @@ func NewModernTlsCheck(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
}, },
} }, []ast.Node{(*ast.CompositeLit)(nil)}
n = (*ast.CompositeLit)(nil)
return
} }
func NewIntermediateTlsCheck(conf map[string]interface{}) (r gas.Rule, n ast.Node) { func NewIntermediateTlsCheck(conf map[string]interface{}) (gas.Rule, []ast.Node) {
// https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28default.29 // https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28default.29
r = &InsecureConfigTLS{ return &InsecureConfigTLS{
pattern: regexp.MustCompile(`^tls\.Config$`), pattern: regexp.MustCompile(`^tls\.Config$`),
MinVersion: 0x0301, // TLS 1.2, 1.1, 1.0 MinVersion: 0x0301, // TLS 1.2, 1.1, 1.0
MaxVersion: 0x0303, MaxVersion: 0x0303,
@ -149,14 +147,12 @@ func NewIntermediateTlsCheck(conf map[string]interface{}) (r gas.Rule, n ast.Nod
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
}, },
} }, []ast.Node{(*ast.CompositeLit)(nil)}
n = (*ast.CompositeLit)(nil)
return
} }
func NewCompatTlsCheck(conf map[string]interface{}) (r gas.Rule, n ast.Node) { func NewCompatTlsCheck(conf map[string]interface{}) (gas.Rule, []ast.Node) {
// https://wiki.mozilla.org/Security/Server_Side_TLS#Old_compatibility_.28default.29 // https://wiki.mozilla.org/Security/Server_Side_TLS#Old_compatibility_.28default.29
r = &InsecureConfigTLS{ return &InsecureConfigTLS{
pattern: regexp.MustCompile(`^tls\.Config$`), pattern: regexp.MustCompile(`^tls\.Config$`),
MinVersion: 0x0301, // TLS 1.2, 1.1, 1.0 MinVersion: 0x0301, // TLS 1.2, 1.1, 1.0
MaxVersion: 0x0303, MaxVersion: 0x0303,
@ -179,7 +175,5 @@ func NewCompatTlsCheck(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
}, },
} }, []ast.Node{(*ast.CompositeLit)(nil)}
n = (*ast.CompositeLit)(nil)
return
} }

View file

@ -15,10 +15,9 @@
package rules package rules
import ( import (
gas "github.com/GoASTScanner/gas/core"
"go/ast" "go/ast"
"regexp" "regexp"
gas "github.com/GoASTScanner/gas/core"
) )
type UsingUnsafe struct { type UsingUnsafe struct {
@ -33,15 +32,13 @@ func (r *UsingUnsafe) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err erro
return nil, nil return nil, nil
} }
func NewUsingUnsafe(conf map[string]interface{}) (r gas.Rule, n ast.Node) { func NewUsingUnsafe(conf map[string]interface{}) (gas.Rule, []ast.Node) {
r = &UsingUnsafe{ return &UsingUnsafe{
pattern: regexp.MustCompile(`unsafe\..*`), pattern: regexp.MustCompile(`unsafe\..*`),
MetaData: gas.MetaData{ MetaData: gas.MetaData{
What: "Use of unsafe calls should be audited", What: "Use of unsafe calls should be audited",
Severity: gas.Low, Severity: gas.Low,
Confidence: gas.High, Confidence: gas.High,
}, },
} }, []ast.Node{(*ast.CallExpr)(nil)}
n = (*ast.CallExpr)(nil)
return
} }

View file

@ -36,7 +36,7 @@ func (r *UsesWeakCryptography) Match(n ast.Node, c *gas.Context) (*gas.Issue, er
} }
// Uses des.* md5.* or rc4.* // Uses des.* md5.* or rc4.*
func NewUsesWeakCryptography(conf map[string]interface{}) (gas.Rule, ast.Node) { func NewUsesWeakCryptography(conf map[string]interface{}) (gas.Rule, []ast.Node) {
calls := make(map[string][]string) calls := make(map[string][]string)
calls["crypto/des"] = []string{"NewCipher", "NewTripleDESCipher"} calls["crypto/des"] = []string{"NewCipher", "NewTripleDESCipher"}
calls["crypto/md5"] = []string{"New", "Sum"} calls["crypto/md5"] = []string{"New", "Sum"}
@ -49,5 +49,5 @@ func NewUsesWeakCryptography(conf map[string]interface{}) (gas.Rule, ast.Node) {
What: "Use of weak cryptographic primitive", What: "Use of weak cryptographic primitive",
}, },
} }
return rule, (*ast.CallExpr)(nil) return rule, []ast.Node{(*ast.CallExpr)(nil)}
} }