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:
Tim Kelsey 2016-08-10 12:51:03 +01:00
parent 235308f853
commit 713949fe69
31 changed files with 211 additions and 181 deletions

42
main.go
View file

@ -22,6 +22,7 @@ import (
"log"
"os"
"path/filepath"
"sort"
"strings"
gas "github.com/HewlettPackard/gas/core"
@ -61,7 +62,11 @@ USAGE:
var logger *log.Logger
func extendConfList(conf map[string]interface{}, name string, input []string) {
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...)
@ -69,7 +74,8 @@ func extendConfList(conf map[string]interface{}, name string, input []string) {
logger.Fatal("Config item must be a string list: ", name)
}
} else {
conf[name] = []string{}
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) == "./..." {

View file

@ -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)
func (r *rulelist) String() string {
return strings.Join(r.list(), ", ")
}
fmt.Println(len(inc))
func (r *rulelist) Set(opt string) error {
r.overwritten = true
if x, ok := r.rules[opt]; ok {
x.enabled = true
return nil
// 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
}
}
}
// 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)
}

View file

@ -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|:).*$`),

View file

@ -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

View file

@ -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{
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",
},
`"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)",
},
},
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
}

View file

@ -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,

View file

@ -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

View file

@ -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)$`),

View file

@ -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

View file

@ -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{

View file

@ -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(
`

View file

@ -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

View file

@ -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

View file

@ -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",

View file

@ -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(
`

View file

@ -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$`),

View file

@ -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

View file

@ -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{

View file

@ -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 := `

View file

@ -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$`),
}

View file

@ -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

View file

@ -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/.*$`),

View file

@ -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

View file

@ -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{

View file

@ -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

View file

@ -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$`),

View file

@ -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

View file

@ -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{

View file

@ -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

View file

@ -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{

View file

@ -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