mirror of
https://github.com/securego/gosec.git
synced 2024-12-24 11:35:52 +00:00
Rule selection rules
This makes the following changes: - riles are identified by an ID - include / exclude list now work - rules are selected based on these lists - blacklist rules are broken out into methods - rule constructors now take the config map - config file can be used to select rules - CLI options embelish config selection options
This commit is contained in:
parent
235308f853
commit
713949fe69
31 changed files with 211 additions and 181 deletions
54
main.go
54
main.go
|
@ -22,6 +22,7 @@ import (
|
|||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
gas "github.com/HewlettPackard/gas/core"
|
||||
|
@ -61,15 +62,20 @@ USAGE:
|
|||
|
||||
var logger *log.Logger
|
||||
|
||||
func extendConfList(conf map[string]interface{}, name string, input []string) {
|
||||
if val, ok := conf[name]; ok {
|
||||
if data, ok := val.(*[]string); ok {
|
||||
conf[name] = append(*data, input...)
|
||||
} else {
|
||||
logger.Fatal("Config item must be a string list: ", name)
|
||||
}
|
||||
} else {
|
||||
func extendConfList(conf map[string]interface{}, name string, inputStr string) {
|
||||
if inputStr == "" {
|
||||
conf[name] = []string{}
|
||||
} else {
|
||||
input := strings.Split(inputStr, ",")
|
||||
if val, ok := conf[name]; ok {
|
||||
if data, ok := val.(*[]string); ok {
|
||||
conf[name] = append(*data, input...)
|
||||
} else {
|
||||
logger.Fatal("Config item must be a string list: ", name)
|
||||
}
|
||||
} else {
|
||||
conf[name] = input
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,8 +92,8 @@ func buildConfig(incRules string, excRules string) map[string]interface{} {
|
|||
}
|
||||
|
||||
// add in CLI include and exclude data
|
||||
extendConfList(config, "include", strings.Split(incRules, ","))
|
||||
extendConfList(config, "exclude", strings.Split(excRules, ","))
|
||||
extendConfList(config, "include", incRules)
|
||||
extendConfList(config, "exclude", excRules)
|
||||
|
||||
// override ignoreNosec if given on CLI
|
||||
if flagIgnoreNoSec != nil {
|
||||
|
@ -108,6 +114,20 @@ func usage() {
|
|||
fmt.Fprintln(os.Stderr, usageText)
|
||||
fmt.Fprint(os.Stderr, "OPTIONS:\n\n")
|
||||
flag.PrintDefaults()
|
||||
fmt.Fprint(os.Stderr, "\n\nRULES:\n\n")
|
||||
|
||||
// sorted rule list for eas of reading
|
||||
rl := GetFullRuleList()
|
||||
keys := make([]string, 0, len(rl))
|
||||
for key := range rl {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, k := range keys {
|
||||
v := rl[k]
|
||||
fmt.Fprintf(os.Stderr, "\t%s: %s\n", k, v.description)
|
||||
}
|
||||
fmt.Fprint(os.Stderr, "\n")
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
@ -119,15 +139,11 @@ func main() {
|
|||
var excluded filelist = []string{"*_test.go"}
|
||||
flag.Var(&excluded, "skip", "File pattern to exclude from scan")
|
||||
|
||||
// Rule configuration
|
||||
rules := newRulelist()
|
||||
flag.Var(&rules, "rule", "GAS rules enabled when performing a scan")
|
||||
|
||||
incRules := ""
|
||||
flag.StringVar(&incRules, "include", "", "comma sperated list of rules to include")
|
||||
flag.StringVar(&incRules, "include", "", "comma sperated list of rules IDs to include, see rule list")
|
||||
|
||||
excRules := ""
|
||||
flag.StringVar(&excRules, "exclude", "", "comma sperated list of rules to exclude")
|
||||
flag.StringVar(&excRules, "exclude", "", "comma sperated list of rules IDs to exclude, see rule list")
|
||||
|
||||
// Custom commands / utilities to run instead of default analyzer
|
||||
tools := newUtils()
|
||||
|
@ -155,12 +171,8 @@ func main() {
|
|||
|
||||
// Setup analyzer
|
||||
config := buildConfig(incRules, excRules)
|
||||
|
||||
analyzer := gas.NewAnalyzer(config, logger)
|
||||
if !rules.overwritten {
|
||||
rules.useDefaults()
|
||||
}
|
||||
rules.apply(&analyzer)
|
||||
AddRules(&analyzer, config)
|
||||
|
||||
// Traverse directory structure if './...'
|
||||
if flag.NArg() == 1 && flag.Arg(0) == "./..." {
|
||||
|
|
116
rulelist.go
116
rulelist.go
|
@ -17,85 +17,77 @@ package main
|
|||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"strings"
|
||||
|
||||
gas "github.com/HewlettPackard/gas/core"
|
||||
"github.com/HewlettPackard/gas/rules"
|
||||
)
|
||||
|
||||
type ruleMaker func() (gas.Rule, ast.Node)
|
||||
type ruleConfig struct {
|
||||
enabled bool
|
||||
constructors []ruleMaker
|
||||
type RuleInfo struct {
|
||||
description string
|
||||
build func(map[string]interface{}) (gas.Rule, ast.Node)
|
||||
}
|
||||
|
||||
type rulelist struct {
|
||||
rules map[string]*ruleConfig
|
||||
overwritten bool
|
||||
}
|
||||
// GetFullRuleList get the full list of all rules available to GAS
|
||||
func GetFullRuleList() map[string]RuleInfo {
|
||||
return map[string]RuleInfo{
|
||||
// misc
|
||||
"G101": RuleInfo{"hardcoded credentials", rules.NewHardcodedCredentials},
|
||||
"G102": RuleInfo{"bind to all interfaces", rules.NewBindsToAllNetworkInterfaces},
|
||||
"G103": RuleInfo{"use of unsafe block", rules.NewUsingUnsafe},
|
||||
"G104": RuleInfo{"errors not checked", rules.NewTemplateCheck},
|
||||
|
||||
func newRulelist() rulelist {
|
||||
var rs rulelist
|
||||
rs.rules = make(map[string]*ruleConfig)
|
||||
rs.overwritten = false
|
||||
rs.register("sql", rules.NewSqlStrConcat, rules.NewSqlStrFormat)
|
||||
rs.register("crypto", rules.NewUsesWeakCryptography)
|
||||
rs.register("hardcoded", rules.NewHardcodedCredentials)
|
||||
rs.register("perms", rules.NewMkdirPerms, rules.NewChmodPerms)
|
||||
rs.register("tempfile", rules.NewBadTempFile)
|
||||
rs.register("tls_good", rules.NewModernTlsCheck)
|
||||
rs.register("tls_ok", rules.NewIntermediateTlsCheck)
|
||||
rs.register("tls_old", rules.NewCompatTlsCheck)
|
||||
rs.register("bind", rules.NewBindsToAllNetworkInterfaces)
|
||||
rs.register("unsafe", rules.NewUsingUnsafe)
|
||||
rs.register("rsa", rules.NewWeakKeyStrength)
|
||||
rs.register("templates", rules.NewTemplateCheck)
|
||||
rs.register("exec", rules.NewSubproc)
|
||||
rs.register("errors", rules.NewNoErrorCheck)
|
||||
rs.register("rand", rules.NewWeakRandCheck)
|
||||
rs.register("blacklist_imports", rules.NewBlacklistImports)
|
||||
return rs
|
||||
}
|
||||
// injection
|
||||
"G201": RuleInfo{"sql string format", rules.NewSqlStrFormat},
|
||||
"G202": RuleInfo{"sql string concat", rules.NewSqlStrConcat},
|
||||
"G203": RuleInfo{"unescaped templates", rules.NewTemplateCheck},
|
||||
"G204": RuleInfo{"use of exec", rules.NewSubproc},
|
||||
|
||||
func (r *rulelist) register(name string, cons ...ruleMaker) {
|
||||
r.rules[name] = &ruleConfig{false, cons}
|
||||
}
|
||||
// filesystem
|
||||
"G301": RuleInfo{"poor mkdir permissions", rules.NewMkdirPerms},
|
||||
"G302": RuleInfo{"poor chmod permisions", rules.NewChmodPerms},
|
||||
"G303": RuleInfo{"predicatable tempfile", rules.NewBadTempFile},
|
||||
|
||||
func (r *rulelist) useDefaults() {
|
||||
for k := range r.rules {
|
||||
r.rules[k].enabled = true
|
||||
// crypto
|
||||
"G401": RuleInfo{"weak crypto", rules.NewUsesWeakCryptography},
|
||||
"G402": RuleInfo{"bad TLS options", rules.NewIntermediateTlsCheck},
|
||||
"G403": RuleInfo{"bad RSA key length", rules.NewWeakKeyStrength},
|
||||
"G404": RuleInfo{"poor random source (rand)", rules.NewWeakRandCheck},
|
||||
|
||||
// blacklist
|
||||
"G501": RuleInfo{"blacklist: crypto/md5", rules.NewBlacklist_crypto_md5},
|
||||
"G502": RuleInfo{"blacklist: crypto/des", rules.NewBlacklist_crypto_des},
|
||||
"G503": RuleInfo{"blacklist: crypto/rc4", rules.NewBlacklist_crypto_rc4},
|
||||
"G504": RuleInfo{"blacklist: net/http/cgi", rules.NewBlacklist_net_http_cgi},
|
||||
}
|
||||
}
|
||||
|
||||
func (r *rulelist) list() []string {
|
||||
i := 0
|
||||
keys := make([]string, len(r.rules))
|
||||
for k := range r.rules {
|
||||
keys[i] = k
|
||||
i++
|
||||
}
|
||||
return keys
|
||||
}
|
||||
func AddRules(analyzer *gas.Analyzer, conf map[string]interface{}) {
|
||||
var all map[string]RuleInfo
|
||||
|
||||
func (r *rulelist) apply(g *gas.Analyzer) {
|
||||
for _, v := range r.rules {
|
||||
if v.enabled {
|
||||
for _, ctor := range v.constructors {
|
||||
g.AddRule(ctor())
|
||||
inc := conf["include"].([]string)
|
||||
exc := conf["exclude"].([]string)
|
||||
|
||||
fmt.Println(len(inc))
|
||||
|
||||
// add included rules
|
||||
if len(inc) == 0 {
|
||||
all = GetFullRuleList()
|
||||
} else {
|
||||
all = map[string]RuleInfo{}
|
||||
tmp := GetFullRuleList()
|
||||
for _, v := range inc {
|
||||
if val, ok := tmp[v]; ok {
|
||||
all[v] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *rulelist) String() string {
|
||||
return strings.Join(r.list(), ", ")
|
||||
}
|
||||
|
||||
func (r *rulelist) Set(opt string) error {
|
||||
r.overwritten = true
|
||||
if x, ok := r.rules[opt]; ok {
|
||||
x.enabled = true
|
||||
return nil
|
||||
// remove excluded rules
|
||||
for _, v := range exc {
|
||||
delete(all, v)
|
||||
}
|
||||
|
||||
for _, v := range all {
|
||||
analyzer.AddRule(v.build(conf))
|
||||
}
|
||||
return fmt.Errorf("Valid rules are: %s", r)
|
||||
}
|
||||
|
|
|
@ -15,9 +15,10 @@
|
|||
package rules
|
||||
|
||||
import (
|
||||
gas "github.com/HewlettPackard/gas/core"
|
||||
"go/ast"
|
||||
"regexp"
|
||||
|
||||
gas "github.com/HewlettPackard/gas/core"
|
||||
)
|
||||
|
||||
// Looks for net.Listen("0.0.0.0") or net.Listen(":8080")
|
||||
|
@ -38,7 +39,7 @@ func (r *BindsToAllNetworkInterfaces) Match(n ast.Node, c *gas.Context) (gi *gas
|
|||
return
|
||||
}
|
||||
|
||||
func NewBindsToAllNetworkInterfaces() (r gas.Rule, n ast.Node) {
|
||||
func NewBindsToAllNetworkInterfaces(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
|
||||
r = &BindsToAllNetworkInterfaces{
|
||||
call: regexp.MustCompile(`^net\.Listen$`),
|
||||
pattern: regexp.MustCompile(`^(0.0.0.0|:).*$`),
|
||||
|
|
|
@ -23,7 +23,7 @@ import (
|
|||
func TestBind0000(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewBindsToAllNetworkInterfaces())
|
||||
analyzer.AddRule(NewBindsToAllNetworkInterfaces(config))
|
||||
|
||||
issues := gasTestRunner(`
|
||||
package main
|
||||
|
@ -45,7 +45,7 @@ func TestBind0000(t *testing.T) {
|
|||
func TestBindEmptyHost(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewBindsToAllNetworkInterfaces())
|
||||
analyzer.AddRule(NewBindsToAllNetworkInterfaces(config))
|
||||
|
||||
issues := gasTestRunner(`
|
||||
package main
|
||||
|
|
|
@ -20,47 +20,68 @@ import (
|
|||
gas "github.com/HewlettPackard/gas/core"
|
||||
)
|
||||
|
||||
type BlacklistImports struct {
|
||||
BlacklistSet map[string]gas.MetaData
|
||||
type BlacklistImport struct {
|
||||
gas.MetaData
|
||||
Path string
|
||||
}
|
||||
|
||||
func (r *BlacklistImports) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err error) {
|
||||
func (r *BlacklistImport) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err error) {
|
||||
if node, ok := n.(*ast.ImportSpec); ok {
|
||||
if data, ok := r.BlacklistSet[node.Path.Value]; ok {
|
||||
return gas.NewIssue(c, n, data.What, data.Severity, data.Confidence), nil
|
||||
if r.Path == node.Path.Value {
|
||||
return gas.NewIssue(c, n, r.What, r.Severity, r.Confidence), nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func NewBlacklistImports() (r gas.Rule, n ast.Node) {
|
||||
// TODO(tkelsey): make this configurable
|
||||
// TODO(tkelsey): make it so each item can be selected/excluded individually
|
||||
r = &BlacklistImports{
|
||||
BlacklistSet: map[string]gas.MetaData{
|
||||
`"crypto/md5"`: gas.MetaData{
|
||||
Severity: gas.High,
|
||||
Confidence: gas.High,
|
||||
What: "Use of weak cryptographic primitive",
|
||||
},
|
||||
`"crypto/des"`: gas.MetaData{
|
||||
Severity: gas.High,
|
||||
Confidence: gas.High,
|
||||
What: "Use of weak cryptographic primitive",
|
||||
},
|
||||
`"crypto/rc4"`: gas.MetaData{
|
||||
Severity: gas.High,
|
||||
Confidence: gas.High,
|
||||
What: "Use of weak cryptographic primitive",
|
||||
},
|
||||
`"net/http/cgi"`: gas.MetaData{
|
||||
Severity: gas.High,
|
||||
Confidence: gas.Low,
|
||||
What: "Go code running under CGI is vulnerable to Httpoxy attack. (CVE-2016-5386)",
|
||||
},
|
||||
func NewBlacklist_crypto_md5(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
|
||||
r = &BlacklistImport{
|
||||
MetaData: gas.MetaData{
|
||||
Severity: gas.High,
|
||||
Confidence: gas.High,
|
||||
What: "Use of weak cryptographic primitive",
|
||||
},
|
||||
Path: `"crypto/md5"`,
|
||||
}
|
||||
n = (*ast.ImportSpec)(nil)
|
||||
return
|
||||
}
|
||||
|
||||
func NewBlacklist_crypto_des(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
|
||||
r = &BlacklistImport{
|
||||
MetaData: gas.MetaData{
|
||||
Severity: gas.High,
|
||||
Confidence: gas.High,
|
||||
What: "Use of weak cryptographic primitive",
|
||||
},
|
||||
Path: `"crypto/des"`,
|
||||
}
|
||||
n = (*ast.ImportSpec)(nil)
|
||||
return
|
||||
}
|
||||
|
||||
func NewBlacklist_crypto_rc4(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
|
||||
r = &BlacklistImport{
|
||||
MetaData: gas.MetaData{
|
||||
Severity: gas.High,
|
||||
Confidence: gas.High,
|
||||
What: "Use of weak cryptographic primitive",
|
||||
},
|
||||
Path: `"crypto/rc4"`,
|
||||
}
|
||||
n = (*ast.ImportSpec)(nil)
|
||||
return
|
||||
}
|
||||
|
||||
func NewBlacklist_net_http_cgi(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
|
||||
r = &BlacklistImport{
|
||||
MetaData: gas.MetaData{
|
||||
Severity: gas.High,
|
||||
Confidence: gas.High,
|
||||
What: "Go code running under CGI is vulnerable to Httpoxy attack. (CVE-2016-5386)",
|
||||
},
|
||||
Path: `"net/http/cgi"`,
|
||||
}
|
||||
|
||||
n = (*ast.ImportSpec)(nil)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ func (r *NoErrorCheck) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err err
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func NewNoErrorCheck() (r gas.Rule, n ast.Node) {
|
||||
func NewNoErrorCheck(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
|
||||
r = &NoErrorCheck{
|
||||
MetaData: gas.MetaData{
|
||||
Severity: gas.Low,
|
||||
|
|
|
@ -23,7 +23,7 @@ import (
|
|||
func TestErrorsMulti(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewNoErrorCheck())
|
||||
analyzer.AddRule(NewNoErrorCheck(config))
|
||||
|
||||
issues := gasTestRunner(
|
||||
`package main
|
||||
|
@ -46,7 +46,7 @@ func TestErrorsMulti(t *testing.T) {
|
|||
func TestErrorsSingle(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewNoErrorCheck())
|
||||
analyzer.AddRule(NewNoErrorCheck(config))
|
||||
|
||||
issues := gasTestRunner(
|
||||
`package main
|
||||
|
@ -69,7 +69,7 @@ func TestErrorsSingle(t *testing.T) {
|
|||
func TestErrorsGood(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewNoErrorCheck())
|
||||
analyzer.AddRule(NewNoErrorCheck(config))
|
||||
|
||||
issues := gasTestRunner(
|
||||
`package main
|
||||
|
|
|
@ -16,9 +16,10 @@ package rules
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
gas "github.com/HewlettPackard/gas/core"
|
||||
"go/ast"
|
||||
"regexp"
|
||||
|
||||
gas "github.com/HewlettPackard/gas/core"
|
||||
)
|
||||
|
||||
type FilePermissions struct {
|
||||
|
@ -36,7 +37,7 @@ func (r *FilePermissions) Match(n ast.Node, c *gas.Context) (*gas.Issue, error)
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func NewChmodPerms() (r gas.Rule, n ast.Node) {
|
||||
func NewChmodPerms(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
|
||||
mode := 0600
|
||||
r = &FilePermissions{
|
||||
pattern: regexp.MustCompile(`^os\.Chmod$`),
|
||||
|
@ -51,7 +52,7 @@ func NewChmodPerms() (r gas.Rule, n ast.Node) {
|
|||
return
|
||||
}
|
||||
|
||||
func NewMkdirPerms() (r gas.Rule, n ast.Node) {
|
||||
func NewMkdirPerms(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
|
||||
mode := 0700
|
||||
r = &FilePermissions{
|
||||
pattern: regexp.MustCompile(`^(os\.Mkdir|os\.MkdirAll)$`),
|
||||
|
|
|
@ -23,7 +23,7 @@ import (
|
|||
func TestChmod(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewChmodPerms())
|
||||
analyzer.AddRule(NewChmodPerms(config))
|
||||
|
||||
issues := gasTestRunner(`
|
||||
package main
|
||||
|
@ -39,7 +39,7 @@ func TestChmod(t *testing.T) {
|
|||
func TestMkdir(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewMkdirPerms())
|
||||
analyzer.AddRule(NewMkdirPerms(config))
|
||||
|
||||
issues := gasTestRunner(`
|
||||
package main
|
||||
|
|
|
@ -43,7 +43,7 @@ func (r *CredsAssign) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err erro
|
|||
return
|
||||
}
|
||||
|
||||
func NewHardcodedCredentials() (r gas.Rule, n ast.Node) {
|
||||
func NewHardcodedCredentials(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
|
||||
r = &CredsAssign{
|
||||
pattern: regexp.MustCompile(`(?i)passwd|pass|password|pwd|secret|token`),
|
||||
MetaData: gas.MetaData{
|
||||
|
|
|
@ -23,7 +23,7 @@ import (
|
|||
func TestHardcoded(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewHardcodedCredentials())
|
||||
analyzer.AddRule(NewHardcodedCredentials(config))
|
||||
|
||||
issues := gasTestRunner(
|
||||
`
|
||||
|
|
|
@ -23,7 +23,7 @@ import (
|
|||
func TestHttpoxy(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewBlacklistImports())
|
||||
analyzer.AddRule(NewBlacklist_net_http_cgi(config))
|
||||
|
||||
issues := gasTestRunner(`
|
||||
package main
|
||||
|
|
|
@ -23,7 +23,7 @@ import (
|
|||
func TestNosec(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewSubproc())
|
||||
analyzer.AddRule(NewSubproc(config))
|
||||
|
||||
issues := gasTestRunner(
|
||||
`package main
|
||||
|
@ -42,7 +42,7 @@ func TestNosec(t *testing.T) {
|
|||
func TestNosecBlock(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewSubproc())
|
||||
analyzer.AddRule(NewSubproc(config))
|
||||
|
||||
issues := gasTestRunner(
|
||||
`package main
|
||||
|
@ -64,7 +64,7 @@ func TestNosecBlock(t *testing.T) {
|
|||
func TestNosecIgnore(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": true}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewSubproc())
|
||||
analyzer.AddRule(NewSubproc(config))
|
||||
|
||||
issues := gasTestRunner(
|
||||
`package main
|
||||
|
|
|
@ -39,7 +39,7 @@ func (w *WeakRand) Match(n ast.Node, c *gas.Context) (*gas.Issue, error) {
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func NewWeakRandCheck() (r gas.Rule, n ast.Node) {
|
||||
func NewWeakRandCheck(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
|
||||
r = &WeakRand{
|
||||
pattern: regexp.MustCompile(`^rand\.Read$`),
|
||||
packageName: "rand",
|
||||
|
|
|
@ -23,7 +23,7 @@ import (
|
|||
func TestRandOk(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewWeakRandCheck())
|
||||
analyzer.AddRule(NewWeakRandCheck(config))
|
||||
|
||||
issues := gasTestRunner(
|
||||
`
|
||||
|
@ -41,7 +41,7 @@ func TestRandOk(t *testing.T) {
|
|||
func TestRandBad(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewWeakRandCheck())
|
||||
analyzer.AddRule(NewWeakRandCheck(config))
|
||||
|
||||
issues := gasTestRunner(
|
||||
`
|
||||
|
|
|
@ -37,7 +37,7 @@ func (w *WeakKeyStrength) Match(n ast.Node, c *gas.Context) (*gas.Issue, error)
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func NewWeakKeyStrength() (r gas.Rule, n ast.Node) {
|
||||
func NewWeakKeyStrength(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
|
||||
bits := 2048
|
||||
r = &WeakKeyStrength{
|
||||
pattern: regexp.MustCompile(`^rsa\.GenerateKey$`),
|
||||
|
|
|
@ -23,7 +23,7 @@ import (
|
|||
func TestRSAKeys(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewWeakKeyStrength())
|
||||
analyzer.AddRule(NewWeakKeyStrength(config))
|
||||
|
||||
issues := gasTestRunner(
|
||||
`package main
|
||||
|
|
|
@ -56,7 +56,7 @@ func (s *SqlStrConcat) Match(n ast.Node, c *gas.Context) (*gas.Issue, error) {
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func NewSqlStrConcat() (r gas.Rule, n ast.Node) {
|
||||
func NewSqlStrConcat(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
|
||||
r = &SqlStrConcat{
|
||||
SqlStatement: SqlStatement{
|
||||
pattern: regexp.MustCompile(`(?)(SELECT|DELETE|INSERT|UPDATE|INTO|FROM|WHERE) `),
|
||||
|
@ -86,7 +86,7 @@ func (s *SqlStrFormat) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err err
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func NewSqlStrFormat() (r gas.Rule, n ast.Node) {
|
||||
func NewSqlStrFormat(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
|
||||
r = &SqlStrFormat{
|
||||
call: regexp.MustCompile(`^fmt\.Sprintf$`),
|
||||
SqlStatement: SqlStatement{
|
||||
|
|
|
@ -23,7 +23,7 @@ import (
|
|||
func TestSQLInjectionViaConcatenation(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewSqlStrConcat())
|
||||
analyzer.AddRule(NewSqlStrConcat(config))
|
||||
|
||||
source := `
|
||||
package main
|
||||
|
@ -51,7 +51,7 @@ func TestSQLInjectionViaConcatenation(t *testing.T) {
|
|||
func TestSQLInjectionViaIntepolation(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewSqlStrFormat())
|
||||
analyzer.AddRule(NewSqlStrFormat(config))
|
||||
|
||||
source := `
|
||||
package main
|
||||
|
@ -81,8 +81,8 @@ func TestSQLInjectionViaIntepolation(t *testing.T) {
|
|||
func TestSQLInjectionFalsePositiveA(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewSqlStrConcat())
|
||||
analyzer.AddRule(NewSqlStrFormat())
|
||||
analyzer.AddRule(NewSqlStrConcat(config))
|
||||
analyzer.AddRule(NewSqlStrFormat(config))
|
||||
|
||||
source := `
|
||||
|
||||
|
@ -117,8 +117,8 @@ func TestSQLInjectionFalsePositiveA(t *testing.T) {
|
|||
func TestSQLInjectionFalsePositiveB(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewSqlStrConcat())
|
||||
analyzer.AddRule(NewSqlStrFormat())
|
||||
analyzer.AddRule(NewSqlStrConcat(config))
|
||||
analyzer.AddRule(NewSqlStrFormat(config))
|
||||
|
||||
source := `
|
||||
|
||||
|
@ -153,8 +153,8 @@ func TestSQLInjectionFalsePositiveB(t *testing.T) {
|
|||
func TestSQLInjectionFalsePositiveC(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewSqlStrConcat())
|
||||
analyzer.AddRule(NewSqlStrFormat())
|
||||
analyzer.AddRule(NewSqlStrConcat(config))
|
||||
analyzer.AddRule(NewSqlStrFormat(config))
|
||||
|
||||
source := `
|
||||
|
||||
|
@ -189,8 +189,8 @@ func TestSQLInjectionFalsePositiveC(t *testing.T) {
|
|||
func TestSQLInjectionFalsePositiveD(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewSqlStrConcat())
|
||||
analyzer.AddRule(NewSqlStrFormat())
|
||||
analyzer.AddRule(NewSqlStrConcat(config))
|
||||
analyzer.AddRule(NewSqlStrFormat(config))
|
||||
|
||||
source := `
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ func (r *Subprocess) Match(n ast.Node, c *gas.Context) (*gas.Issue, error) {
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func NewSubproc() (r gas.Rule, n ast.Node) {
|
||||
func NewSubproc(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
|
||||
r = &Subprocess{
|
||||
pattern: regexp.MustCompile(`^exec\.Command|syscall\.Exec$`),
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ import (
|
|||
func TestSubprocess(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewSubproc())
|
||||
analyzer.AddRule(NewSubproc(config))
|
||||
|
||||
issues := gasTestRunner(`
|
||||
package main
|
||||
|
@ -51,7 +51,7 @@ func TestSubprocess(t *testing.T) {
|
|||
func TestSubprocessVar(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewSubproc())
|
||||
analyzer.AddRule(NewSubproc(config))
|
||||
|
||||
issues := gasTestRunner(`
|
||||
package main
|
||||
|
@ -79,7 +79,7 @@ func TestSubprocessVar(t *testing.T) {
|
|||
func TestSubprocessPath(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewSubproc())
|
||||
analyzer.AddRule(NewSubproc(config))
|
||||
|
||||
issues := gasTestRunner(`
|
||||
package main
|
||||
|
@ -106,7 +106,7 @@ func TestSubprocessPath(t *testing.T) {
|
|||
func TestSubprocessSyscall(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewSubproc())
|
||||
analyzer.AddRule(NewSubproc(config))
|
||||
|
||||
issues := gasTestRunner(`
|
||||
package main
|
||||
|
|
|
@ -15,9 +15,10 @@
|
|||
package rules
|
||||
|
||||
import (
|
||||
gas "github.com/HewlettPackard/gas/core"
|
||||
"go/ast"
|
||||
"regexp"
|
||||
|
||||
gas "github.com/HewlettPackard/gas/core"
|
||||
)
|
||||
|
||||
type BadTempFile struct {
|
||||
|
@ -35,7 +36,7 @@ func (t *BadTempFile) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err erro
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func NewBadTempFile() (r gas.Rule, n ast.Node) {
|
||||
func NewBadTempFile(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
|
||||
r = &BadTempFile{
|
||||
call: regexp.MustCompile(`ioutil\.WriteFile|os\.Create`),
|
||||
args: regexp.MustCompile(`^/tmp/.*$|^/var/tmp/.*$`),
|
||||
|
|
|
@ -23,7 +23,7 @@ import (
|
|||
func TestTempfiles(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewBadTempFile())
|
||||
analyzer.AddRule(NewBadTempFile(config))
|
||||
|
||||
source := `
|
||||
package samples
|
||||
|
|
|
@ -15,9 +15,10 @@
|
|||
package rules
|
||||
|
||||
import (
|
||||
gas "github.com/HewlettPackard/gas/core"
|
||||
"go/ast"
|
||||
"regexp"
|
||||
|
||||
gas "github.com/HewlettPackard/gas/core"
|
||||
)
|
||||
|
||||
type TemplateCheck struct {
|
||||
|
@ -36,7 +37,7 @@ func (t *TemplateCheck) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err er
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func NewTemplateCheck() (r gas.Rule, n ast.Node) {
|
||||
func NewTemplateCheck(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
|
||||
r = &TemplateCheck{
|
||||
call: regexp.MustCompile(`^template\.(HTML|JS|URL)$`),
|
||||
MetaData: gas.MetaData{
|
||||
|
|
|
@ -23,7 +23,7 @@ import (
|
|||
func TestTemplateCheckSafe(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewTemplateCheck())
|
||||
analyzer.AddRule(NewTemplateCheck(config))
|
||||
|
||||
source := `
|
||||
package samples
|
||||
|
@ -51,7 +51,7 @@ func TestTemplateCheckSafe(t *testing.T) {
|
|||
func TestTemplateCheckBadHTML(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewTemplateCheck())
|
||||
analyzer.AddRule(NewTemplateCheck(config))
|
||||
|
||||
source := `
|
||||
package samples
|
||||
|
@ -80,7 +80,7 @@ func TestTemplateCheckBadHTML(t *testing.T) {
|
|||
func TestTemplateCheckBadJS(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewTemplateCheck())
|
||||
analyzer.AddRule(NewTemplateCheck(config))
|
||||
|
||||
source := `
|
||||
package samples
|
||||
|
@ -109,7 +109,7 @@ func TestTemplateCheckBadJS(t *testing.T) {
|
|||
func TestTemplateCheckBadURL(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewTemplateCheck())
|
||||
analyzer.AddRule(NewTemplateCheck(config))
|
||||
|
||||
source := `
|
||||
package samples
|
||||
|
|
|
@ -109,7 +109,7 @@ func (t *InsecureConfigTLS) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, er
|
|||
return
|
||||
}
|
||||
|
||||
func NewModernTlsCheck() (r gas.Rule, n ast.Node) {
|
||||
func NewModernTlsCheck(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
|
||||
// https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility
|
||||
r = &InsecureConfigTLS{
|
||||
pattern: regexp.MustCompile(`^tls\.Config$`),
|
||||
|
@ -126,7 +126,7 @@ func NewModernTlsCheck() (r gas.Rule, n ast.Node) {
|
|||
return
|
||||
}
|
||||
|
||||
func NewIntermediateTlsCheck() (r gas.Rule, n ast.Node) {
|
||||
func NewIntermediateTlsCheck(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
|
||||
// https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28default.29
|
||||
r = &InsecureConfigTLS{
|
||||
pattern: regexp.MustCompile(`^tls\.Config$`),
|
||||
|
@ -154,7 +154,7 @@ func NewIntermediateTlsCheck() (r gas.Rule, n ast.Node) {
|
|||
return
|
||||
}
|
||||
|
||||
func NewCompatTlsCheck() (r gas.Rule, n ast.Node) {
|
||||
func NewCompatTlsCheck(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
|
||||
// https://wiki.mozilla.org/Security/Server_Side_TLS#Old_compatibility_.28default.29
|
||||
r = &InsecureConfigTLS{
|
||||
pattern: regexp.MustCompile(`^tls\.Config$`),
|
||||
|
|
|
@ -23,7 +23,7 @@ import (
|
|||
func TestInsecureSkipVerify(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewModernTlsCheck())
|
||||
analyzer.AddRule(NewModernTlsCheck(config))
|
||||
|
||||
issues := gasTestRunner(`
|
||||
package main
|
||||
|
@ -52,7 +52,7 @@ func TestInsecureSkipVerify(t *testing.T) {
|
|||
func TestInsecureMinVersion(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewModernTlsCheck())
|
||||
analyzer.AddRule(NewModernTlsCheck(config))
|
||||
|
||||
issues := gasTestRunner(`
|
||||
package main
|
||||
|
@ -81,7 +81,7 @@ func TestInsecureMinVersion(t *testing.T) {
|
|||
func TestInsecureMaxVersion(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewModernTlsCheck())
|
||||
analyzer.AddRule(NewModernTlsCheck(config))
|
||||
|
||||
issues := gasTestRunner(`
|
||||
package main
|
||||
|
@ -110,7 +110,7 @@ func TestInsecureMaxVersion(t *testing.T) {
|
|||
func TestInsecureCipherSuite(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewModernTlsCheck())
|
||||
analyzer.AddRule(NewModernTlsCheck(config))
|
||||
|
||||
issues := gasTestRunner(`
|
||||
package main
|
||||
|
|
|
@ -15,9 +15,10 @@
|
|||
package rules
|
||||
|
||||
import (
|
||||
gas "github.com/HewlettPackard/gas/core"
|
||||
"go/ast"
|
||||
"regexp"
|
||||
|
||||
gas "github.com/HewlettPackard/gas/core"
|
||||
)
|
||||
|
||||
type UsingUnsafe struct {
|
||||
|
@ -32,7 +33,7 @@ func (r *UsingUnsafe) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err erro
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func NewUsingUnsafe() (r gas.Rule, n ast.Node) {
|
||||
func NewUsingUnsafe(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
|
||||
r = &UsingUnsafe{
|
||||
pattern: regexp.MustCompile(`unsafe.*`),
|
||||
MetaData: gas.MetaData{
|
||||
|
|
|
@ -23,7 +23,7 @@ import (
|
|||
func TestUnsafe(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewUsingUnsafe())
|
||||
analyzer.AddRule(NewUsingUnsafe(config))
|
||||
|
||||
issues := gasTestRunner(`
|
||||
package main
|
||||
|
|
|
@ -34,7 +34,7 @@ func (r *UsesWeakCryptography) Match(n ast.Node, c *gas.Context) (*gas.Issue, er
|
|||
}
|
||||
|
||||
// Uses des.* md5.* or rc4.*
|
||||
func NewUsesWeakCryptography() (r gas.Rule, n ast.Node) {
|
||||
func NewUsesWeakCryptography(conf map[string]interface{}) (r gas.Rule, n ast.Node) {
|
||||
r = &UsesWeakCryptography{
|
||||
pattern: regexp.MustCompile(`des\.NewCipher|des\.NewTripleDESCipher|md5\.New|md5\.Sum|rc4\.NewCipher`),
|
||||
MetaData: gas.MetaData{
|
||||
|
|
|
@ -23,8 +23,8 @@ import (
|
|||
func TestMD5(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewBlacklistImports())
|
||||
analyzer.AddRule(NewUsesWeakCryptography())
|
||||
analyzer.AddRule(NewBlacklist_crypto_md5(config))
|
||||
analyzer.AddRule(NewUsesWeakCryptography(config))
|
||||
|
||||
issues := gasTestRunner(`
|
||||
package main
|
||||
|
@ -45,8 +45,8 @@ func TestMD5(t *testing.T) {
|
|||
func TestDES(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewBlacklistImports())
|
||||
analyzer.AddRule(NewUsesWeakCryptography())
|
||||
analyzer.AddRule(NewBlacklist_crypto_des(config))
|
||||
analyzer.AddRule(NewUsesWeakCryptography(config))
|
||||
|
||||
issues := gasTestRunner(`
|
||||
package main
|
||||
|
@ -85,8 +85,8 @@ func TestDES(t *testing.T) {
|
|||
func TestRC4(t *testing.T) {
|
||||
config := map[string]interface{}{"ignoreNosec": false}
|
||||
analyzer := gas.NewAnalyzer(config, nil)
|
||||
analyzer.AddRule(NewBlacklistImports())
|
||||
analyzer.AddRule(NewUsesWeakCryptography())
|
||||
analyzer.AddRule(NewBlacklist_crypto_rc4(config))
|
||||
analyzer.AddRule(NewUsesWeakCryptography(config))
|
||||
|
||||
issues := gasTestRunner(`
|
||||
package main
|
||||
|
|
Loading…
Reference in a new issue