Restructure and introduce a standalone config

This commit is contained in:
Grant Murphy 2017-04-28 14:46:26 -07:00
parent cacf21f3c0
commit bf78d027a9
26 changed files with 234 additions and 127 deletions

1
.gitignore vendored
View file

@ -3,7 +3,6 @@
*.a *.a
*.so *.so
*.swp *.swp
gas
# Folders # Folders
_obj _obj

View file

@ -82,27 +82,33 @@ type Analyzer struct {
ignoreNosec bool ignoreNosec bool
ruleset RuleSet ruleset RuleSet
context *Context context *Context
config Config
logger *log.Logger logger *log.Logger
Issues []*Issue `json:"issues"` Issues []*Issue `json:"issues"`
Stats *Metrics `json:"metrics"` Stats *Metrics `json:"metrics"`
} }
// NewAnalyzer builds a new anaylzer. // NewAnalyzer builds a new anaylzer.
func NewAnalyzer(conf map[string]interface{}, logger *log.Logger) Analyzer { func NewAnalyzer(conf Config, logger *log.Logger) Analyzer {
if logger == nil { if logger == nil {
logger = log.New(os.Stdout, "[gas]", 0) logger = log.New(os.Stdout, "[gas]", 0)
} }
ignoreNoSec := false
if val, err := conf.Get("ignoreNoSec"); err == nil {
if override, ok := val.(bool); ok {
ignoreNoSec = override
}
}
a := Analyzer{ a := Analyzer{
ignoreNosec: conf["ignoreNosec"].(bool), ignoreNosec: ignoreNoSec,
ruleset: make(RuleSet), ruleset: make(RuleSet),
context: &Context{}, context: &Context{},
config: conf,
logger: logger, logger: logger,
Issues: make([]*Issue, 0, 16), Issues: make([]*Issue, 0, 16),
Stats: &Metrics{0, 0, 0, 0}, Stats: &Metrics{0, 0, 0, 0},
} }
// TODO(tkelsey): use the inc/exc lists
return a return a
} }
@ -111,6 +117,7 @@ func (gas *Analyzer) process(filename string, source interface{}) error {
gas.context.FileSet = token.NewFileSet() gas.context.FileSet = token.NewFileSet()
root, err := parser.ParseFile(gas.context.FileSet, filename, source, mode) root, err := parser.ParseFile(gas.context.FileSet, filename, source, mode)
if err == nil { if err == nil {
gas.context.Config = gas.config
gas.context.Comments = ast.NewCommentMap(gas.context.FileSet, root, root.Comments) gas.context.Comments = ast.NewCommentMap(gas.context.FileSet, root, root.Comments)
gas.context.Root = root gas.context.Root = root
@ -171,6 +178,7 @@ func (gas *Analyzer) Process(filename string) error {
func (gas *Analyzer) ProcessPackage(prog *loader.Program, pkg *loader.PackageInfo, file *ast.File) error { func (gas *Analyzer) ProcessPackage(prog *loader.Program, pkg *loader.PackageInfo, file *ast.File) error {
gas.context.FileSet = prog.Fset gas.context.FileSet = prog.Fset
gas.context.Config = gas.config
gas.context.Comments = ast.NewCommentMap(gas.context.FileSet, file, file.Comments) gas.context.Comments = ast.NewCommentMap(gas.context.FileSet, file, file.Comments)
gas.context.Root = file gas.context.Root = file
gas.context.Info = &pkg.Info gas.context.Info = &pkg.Info

BIN
cmd/gas/gas Executable file

Binary file not shown.

View file

@ -29,6 +29,7 @@ import (
"github.com/GoASTScanner/gas" "github.com/GoASTScanner/gas"
"github.com/GoASTScanner/gas/output" "github.com/GoASTScanner/gas/output"
"github.com/GoASTScanner/gas/rules"
"golang.org/x/tools/go/loader" "golang.org/x/tools/go/loader"
) )
@ -138,7 +139,7 @@ func usage() {
fmt.Fprint(os.Stderr, "\n\nRULES:\n\n") fmt.Fprint(os.Stderr, "\n\nRULES:\n\n")
// sorted rule list for eas of reading // sorted rule list for eas of reading
rl := GetFullRuleList() rl := rules.Generate()
keys := make([]string, 0, len(rl)) keys := make([]string, 0, len(rl))
for key := range rl { for key := range rl {
keys = append(keys, key) keys = append(keys, key)
@ -146,13 +147,13 @@ func usage() {
sort.Strings(keys) sort.Strings(keys)
for _, k := range keys { for _, k := range keys {
v := rl[k] v := rl[k]
fmt.Fprintf(os.Stderr, "\t%s: %s\n", k, v.description) fmt.Fprintf(os.Stderr, "\t%s: %s\n", k, v.Description)
} }
fmt.Fprint(os.Stderr, "\n") fmt.Fprint(os.Stderr, "\n")
} }
// TODO(gm) This needs to be refactored (potentially included in Analyzer) // TODO(gm) This needs to be refactored (potentially included in Analyzer)
func analyzePackage(packageDirectory string, metrics *gas.Metrics, config map[string]interface{}, logger *log.Logger) ([]*gas.Issue, error) { func analyzePackage(packageDirectory string, metrics *gas.Metrics, config gas.Config, logger *log.Logger, ruleDefs rules.RuleList) ([]*gas.Issue, error) {
basePackage, err := build.Default.ImportDir(packageDirectory, build.ImportComment) basePackage, err := build.Default.ImportDir(packageDirectory, build.ImportComment)
if err != nil { if err != nil {
@ -174,7 +175,9 @@ func analyzePackage(packageDirectory string, metrics *gas.Metrics, config map[st
for _, pkg := range builtPackage.Created { for _, pkg := range builtPackage.Created {
analyzer := gas.NewAnalyzer(config, logger) analyzer := gas.NewAnalyzer(config, logger)
AddRules(&analyzer, config) for _, rule := range ruleDefs {
analyzer.AddRule(rule.Create(config))
}
for _, file := range pkg.Files { for _, file := range pkg.Files {
analyzer.ProcessPackage(builtPackage, pkg, file) analyzer.ProcessPackage(builtPackage, pkg, file)
} }
@ -227,10 +230,30 @@ func main() {
os.Exit(0) os.Exit(0)
} }
config := buildConfig(incRules, excRules) // Load config
config := gas.NewConfig()
if flagConfig != nil && *flagConfig != "" {
file, err := os.Open(*flagConfig)
if err != nil {
logger.Fatal(err)
}
defer file.Close()
if _, err := config.ReadFrom(file); err != nil {
logger.Fatal(err)
}
}
filters := make([]rules.RuleFilter, 0)
if incRules != "" {
including := strings.Split(incRules, ",")
filters = append(filters, rules.NewRuleFilter(false, including...))
}
if excRules != "" {
excluding := strings.Split(excRules, ",")
filters = append(filters, rules.NewRuleFilter(true, excluding...))
}
ruleDefinitions := rules.Generate(filters...)
issues := make([]*gas.Issue, 0) issues := make([]*gas.Issue, 0)
metrics := &gas.Metrics{} metrics := &gas.Metrics{}
for _, arg := range flag.Args() { for _, arg := range flag.Args() {
if arg == "./..." { if arg == "./..." {
baseDirectory, err := os.Getwd() baseDirectory, err := os.Getwd()
@ -246,7 +269,7 @@ func main() {
log.Printf("Skipping %s\n", path) log.Printf("Skipping %s\n", path)
return filepath.SkipDir return filepath.SkipDir
} }
newIssues, err := analyzePackage(path, metrics, config, logger) newIssues, err := analyzePackage(path, metrics, config, logger, ruleDefinitions)
if err != nil { if err != nil {
log.Println(err) log.Println(err)
} else { } else {
@ -256,7 +279,7 @@ func main() {
return nil return nil
}) })
} else { } else {
newIssues, err := analyzePackage(arg, metrics, config, logger) newIssues, err := analyzePackage(arg, metrics, config, logger, ruleDefinitions)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }

View file

@ -1,91 +0,0 @@
// (c) Copyright 2016 Hewlett Packard Enterprise Development LP
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"go/ast"
"github.com/GoASTScanner/gas"
"github.com/GoASTScanner/gas/rules"
)
type RuleInfo struct {
description string
build func(map[string]interface{}) (gas.Rule, []ast.Node)
}
// GetFullRuleList get the full list of all rules available to GAS
func GetFullRuleList() map[string]RuleInfo {
return map[string]RuleInfo{
// misc
"G101": RuleInfo{"Look for hardcoded credentials", rules.NewHardcodedCredentials},
"G102": RuleInfo{"Bind to all interfaces", rules.NewBindsToAllNetworkInterfaces},
"G103": RuleInfo{"Audit the use of unsafe block", rules.NewUsingUnsafe},
"G104": RuleInfo{"Audit errors not checked", rules.NewNoErrorCheck},
"G105": RuleInfo{"Audit the use of big.Exp function", rules.NewUsingBigExp},
// injection
"G201": RuleInfo{"SQL query construction using format string", rules.NewSqlStrFormat},
"G202": RuleInfo{"SQL query construction using string concatenation", rules.NewSqlStrConcat},
"G203": RuleInfo{"Use of unescaped data in HTML templates", rules.NewTemplateCheck},
"G204": RuleInfo{"Audit use of command execution", rules.NewSubproc},
// filesystem
"G301": RuleInfo{"Poor file permissions used when creating a directory", rules.NewMkdirPerms},
"G302": RuleInfo{"Poor file permisions used when creation file or using chmod", rules.NewFilePerms},
"G303": RuleInfo{"Creating tempfile using a predictable path", rules.NewBadTempFile},
// crypto
"G401": RuleInfo{"Detect the usage of DES, RC4, or MD5", rules.NewUsesWeakCryptography},
"G402": RuleInfo{"Look for bad TLS connection settings", rules.NewIntermediateTlsCheck},
"G403": RuleInfo{"Ensure minimum RSA key length of 2048 bits", rules.NewWeakKeyStrength},
"G404": RuleInfo{"Insecure random number source (rand)", rules.NewWeakRandCheck},
// blacklist
"G501": RuleInfo{"Import blacklist: crypto/md5", rules.NewBlacklist_crypto_md5},
"G502": RuleInfo{"Import blacklist: crypto/des", rules.NewBlacklist_crypto_des},
"G503": RuleInfo{"Import blacklist: crypto/rc4", rules.NewBlacklist_crypto_rc4},
"G504": RuleInfo{"Import blacklist: net/http/cgi", rules.NewBlacklist_net_http_cgi},
}
}
func AddRules(analyzer *gas.Analyzer, conf map[string]interface{}) {
var all map[string]RuleInfo
inc := conf["include"].([]string)
exc := conf["exclude"].([]string)
// 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))
}
}

80
config.go Normal file
View file

@ -0,0 +1,80 @@
package gas
import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
)
// Config is used to provide configuration and customization to each of the rules.
type Config map[string]interface{}
// NewConfig initializes a new configuration instance. The configuration data then
// needs to be loaded via c.ReadFrom(strings.NewReader("config data"))
// or from a *os.File.
func NewConfig() Config {
return make(Config)
}
// ReadFrom implements the io.ReaderFrom interface. This
// should be used with io.Reader to load configuration from
//file or from string etc.
func (c Config) ReadFrom(r io.Reader) (int64, error) {
data, err := ioutil.ReadAll(r)
if err != nil {
return int64(len(data)), err
}
if err = json.Unmarshal(data, c); err != nil {
return int64(len(data)), err
}
return int64(len(data)), nil
}
// WriteTo implements the io.WriteTo interface. This should
// be used to save or print out the configuration information.
func (c Config) WriteTo(w io.Writer) (int64, error) {
data, err := json.Marshal(c)
if err != nil {
return int64(len(data)), err
}
return io.Copy(w, bytes.NewReader(data))
}
// EnableRule will change the rule to the specified enabled state
func (c Config) EnableRule(ruleID string, enabled bool) {
if data, found := c["rules"]; found {
if rules, ok := data.(map[string]bool); ok {
rules[ruleID] = enabled
}
}
}
// Enabled returns a list of rules that are enabled
func (c Config) Enabled() []string {
if data, found := c["rules"]; found {
if rules, ok := data.(map[string]bool); ok {
enabled := make([]string, len(rules))
for ruleID := range rules {
enabled = append(enabled, ruleID)
}
return enabled
}
}
return nil
}
// Get returns the configuration section for a given rule
func (c Config) Get(ruleID string) (interface{}, error) {
section, found := c[ruleID]
if !found {
return nil, fmt.Errorf("Rule %s not in configuration", ruleID)
}
return section, nil
}
// Set section for a given rule
func (c Config) Set(ruleID string, val interface{}) {
c[ruleID] = val
}

View file

@ -15,8 +15,9 @@
package rules package rules
import ( import (
"github.com/GoASTScanner/gas"
"go/ast" "go/ast"
"github.com/GoASTScanner/gas"
) )
type UsingBigExp struct { type UsingBigExp struct {
@ -31,7 +32,7 @@ func (r *UsingBigExp) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err erro
} }
return nil, nil return nil, nil
} }
func NewUsingBigExp(conf map[string]interface{}) (gas.Rule, []ast.Node) { func NewUsingBigExp(conf gas.Config) (gas.Rule, []ast.Node) {
return &UsingBigExp{ return &UsingBigExp{
pkg: "*math/big.Int", pkg: "*math/big.Int",
calls: []string{"Exp"}, calls: []string{"Exp"},

View file

@ -39,7 +39,7 @@ func (r *BindsToAllNetworkInterfaces) Match(n ast.Node, c *gas.Context) (gi *gas
return return
} }
func NewBindsToAllNetworkInterfaces(conf map[string]interface{}) (gas.Rule, []ast.Node) { func NewBindsToAllNetworkInterfaces(conf gas.Config) (gas.Rule, []ast.Node) {
return &BindsToAllNetworkInterfaces{ return &BindsToAllNetworkInterfaces{
call: regexp.MustCompile(`^(net|tls)\.Listen$`), call: regexp.MustCompile(`^(net|tls)\.Listen$`),
pattern: regexp.MustCompile(`^(0.0.0.0|:).*$`), pattern: regexp.MustCompile(`^(0.0.0.0|:).*$`),

View file

@ -34,7 +34,7 @@ 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{}) (gas.Rule, []ast.Node) { func NewBlacklist_crypto_md5(conf gas.Config) (gas.Rule, []ast.Node) {
return &BlacklistImport{ return &BlacklistImport{
MetaData: gas.MetaData{ MetaData: gas.MetaData{
Severity: gas.High, Severity: gas.High,
@ -45,7 +45,7 @@ func NewBlacklist_crypto_md5(conf map[string]interface{}) (gas.Rule, []ast.Node)
}, []ast.Node{(*ast.ImportSpec)(nil)} }, []ast.Node{(*ast.ImportSpec)(nil)}
} }
func NewBlacklist_crypto_des(conf map[string]interface{}) (gas.Rule, []ast.Node) { func NewBlacklist_crypto_des(conf gas.Config) (gas.Rule, []ast.Node) {
return &BlacklistImport{ return &BlacklistImport{
MetaData: gas.MetaData{ MetaData: gas.MetaData{
Severity: gas.High, Severity: gas.High,
@ -56,7 +56,7 @@ func NewBlacklist_crypto_des(conf map[string]interface{}) (gas.Rule, []ast.Node)
}, []ast.Node{(*ast.ImportSpec)(nil)} }, []ast.Node{(*ast.ImportSpec)(nil)}
} }
func NewBlacklist_crypto_rc4(conf map[string]interface{}) (gas.Rule, []ast.Node) { func NewBlacklist_crypto_rc4(conf gas.Config) (gas.Rule, []ast.Node) {
return &BlacklistImport{ return &BlacklistImport{
MetaData: gas.MetaData{ MetaData: gas.MetaData{
Severity: gas.High, Severity: gas.High,
@ -67,7 +67,7 @@ func NewBlacklist_crypto_rc4(conf map[string]interface{}) (gas.Rule, []ast.Node)
}, []ast.Node{(*ast.ImportSpec)(nil)} }, []ast.Node{(*ast.ImportSpec)(nil)}
} }
func NewBlacklist_net_http_cgi(conf map[string]interface{}) (gas.Rule, []ast.Node) { func NewBlacklist_net_http_cgi(conf gas.Config) (gas.Rule, []ast.Node) {
return &BlacklistImport{ return &BlacklistImport{
MetaData: gas.MetaData{ MetaData: gas.MetaData{
Severity: gas.High, Severity: gas.High,

View file

@ -70,7 +70,7 @@ func (r *NoErrorCheck) Match(n ast.Node, ctx *gas.Context) (*gas.Issue, error) {
return nil, nil return nil, nil
} }
func NewNoErrorCheck(conf map[string]interface{}) (gas.Rule, []ast.Node) { func NewNoErrorCheck(conf gas.Config) (gas.Rule, []ast.Node) {
// TODO(gm) Come up with sensible defaults here. Or flip it to use a // TODO(gm) Come up with sensible defaults here. Or flip it to use a
// black list instead. // black list instead.

View file

@ -56,7 +56,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 gas.Config) (gas.Rule, []ast.Node) {
mode := getConfiguredMode(conf, "G302", 0600) mode := getConfiguredMode(conf, "G302", 0600)
return &FilePermissions{ return &FilePermissions{
mode: mode, mode: mode,
@ -70,7 +70,7 @@ func NewFilePerms(conf map[string]interface{}) (gas.Rule, []ast.Node) {
}, []ast.Node{(*ast.CallExpr)(nil)} }, []ast.Node{(*ast.CallExpr)(nil)}
} }
func NewMkdirPerms(conf map[string]interface{}) (gas.Rule, []ast.Node) { func NewMkdirPerms(conf gas.Config) (gas.Rule, []ast.Node) {
mode := getConfiguredMode(conf, "G301", 0700) mode := getConfiguredMode(conf, "G301", 0700)
return &FilePermissions{ return &FilePermissions{
mode: mode, mode: mode,

View file

@ -100,7 +100,7 @@ func (r *Credentials) matchGenDecl(decl *ast.GenDecl, ctx *gas.Context) (*gas.Is
return nil, nil return nil, nil
} }
func NewHardcodedCredentials(conf map[string]interface{}) (gas.Rule, []ast.Node) { func NewHardcodedCredentials(conf gas.Config) (gas.Rule, []ast.Node) {
pattern := `(?i)passwd|pass|password|pwd|secret|token` pattern := `(?i)passwd|pass|password|pwd|secret|token`
entropyThreshold := 80.0 entropyThreshold := 80.0
perCharThreshold := 3.0 perCharThreshold := 3.0

View file

@ -36,7 +36,7 @@ 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{}) (gas.Rule, []ast.Node) { func NewWeakRandCheck(conf gas.Config) (gas.Rule, []ast.Node) {
return &WeakRand{ return &WeakRand{
funcNames: []string{"Read", "Int"}, funcNames: []string{"Read", "Int"},
packagePath: "math/rand", packagePath: "math/rand",

View file

@ -37,7 +37,7 @@ 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{}) (gas.Rule, []ast.Node) { func NewWeakKeyStrength(conf gas.Config) (gas.Rule, []ast.Node) {
bits := 2048 bits := 2048
return &WeakKeyStrength{ return &WeakKeyStrength{
pattern: regexp.MustCompile(`^rsa\.GenerateKey$`), pattern: regexp.MustCompile(`^rsa\.GenerateKey$`),

87
rules/rulelist.go Normal file
View file

@ -0,0 +1,87 @@
// (c) Copyright 2016 Hewlett Packard Enterprise Development LP
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package rules
import (
"go/ast"
"github.com/GoASTScanner/gas"
)
type RuleDefinition struct {
Description string
Create func(c gas.Config) (gas.Rule, []ast.Node)
}
type RuleList map[string]RuleDefinition
type RuleFilter func(string) bool
func NewRuleFilter(action bool, ruleIDs ...string) RuleFilter {
rulelist := make(map[string]bool)
for _, rule := range ruleIDs {
rulelist[rule] = true
}
return func(rule string) bool {
if _, found := rulelist[rule]; found {
return action
}
return !action
}
}
// Generate the list of rules to use
func Generate(filters ...RuleFilter) RuleList {
rules := map[string]RuleDefinition{
// misc
"G101": RuleDefinition{"Look for hardcoded credentials", NewHardcodedCredentials},
"G102": RuleDefinition{"Bind to all interfaces", NewBindsToAllNetworkInterfaces},
"G103": RuleDefinition{"Audit the use of unsafe block", NewUsingUnsafe},
"G104": RuleDefinition{"Audit errors not checked", NewNoErrorCheck},
"G105": RuleDefinition{"Audit the use of big.Exp function", NewUsingBigExp},
// injection
"G201": RuleDefinition{"SQL query construction using format string", NewSqlStrFormat},
"G202": RuleDefinition{"SQL query construction using string concatenation", NewSqlStrConcat},
"G203": RuleDefinition{"Use of unescaped data in HTML templates", NewTemplateCheck},
"G204": RuleDefinition{"Audit use of command execution", NewSubproc},
// filesystem
"G301": RuleDefinition{"Poor file permissions used when creating a directory", NewMkdirPerms},
"G302": RuleDefinition{"Poor file permisions used when creation file or using chmod", NewFilePerms},
"G303": RuleDefinition{"Creating tempfile using a predictable path", NewBadTempFile},
// crypto
"G401": RuleDefinition{"Detect the usage of DES, RC4, or MD5", NewUsesWeakCryptography},
"G402": RuleDefinition{"Look for bad TLS connection settings", NewIntermediateTlsCheck},
"G403": RuleDefinition{"Ensure minimum RSA key length of 2048 bits", NewWeakKeyStrength},
"G404": RuleDefinition{"Insecure random number source (rand)", NewWeakRandCheck},
// blacklist
"G501": RuleDefinition{"Import blacklist: crypto/md5", NewBlacklist_crypto_md5},
"G502": RuleDefinition{"Import blacklist: crypto/des", NewBlacklist_crypto_des},
"G503": RuleDefinition{"Import blacklist: crypto/rc4", NewBlacklist_crypto_rc4},
"G504": RuleDefinition{"Import blacklist: net/http/cgi", NewBlacklist_net_http_cgi},
}
for rule := range rules {
for _, filter := range filters {
if filter(rule) {
delete(rules, rule)
}
}
}
return rules
}

View file

@ -56,7 +56,7 @@ 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{}) (gas.Rule, []ast.Node) { func NewSqlStrConcat(conf gas.Config) (gas.Rule, []ast.Node) {
return &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) `),
@ -84,7 +84,7 @@ 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{}) (gas.Rule, []ast.Node) { func NewSqlStrFormat(conf gas.Config) (gas.Rule, []ast.Node) {
return &SqlStrFormat{ return &SqlStrFormat{
call: regexp.MustCompile(`^fmt\.Sprintf$`), call: regexp.MustCompile(`^fmt\.Sprintf$`),
SqlStatement: SqlStatement{ SqlStatement: SqlStatement{

View file

@ -49,7 +49,7 @@ 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{}) (gas.Rule, []ast.Node) { func NewSubproc(conf gas.Config) (gas.Rule, []ast.Node) {
return &Subprocess{ return &Subprocess{
pattern: regexp.MustCompile(`^exec\.Command|syscall\.Exec$`), pattern: regexp.MustCompile(`^exec\.Command|syscall\.Exec$`),
}, []ast.Node{(*ast.CallExpr)(nil)} }, []ast.Node{(*ast.CallExpr)(nil)}

View file

@ -36,7 +36,7 @@ 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{}) (gas.Rule, []ast.Node) { func NewBadTempFile(conf gas.Config) (gas.Rule, []ast.Node) {
return &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/.*$`),

View file

@ -37,7 +37,7 @@ 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{}) (gas.Rule, []ast.Node) { func NewTemplateCheck(conf gas.Config) (gas.Rule, []ast.Node) {
return &TemplateCheck{ return &TemplateCheck{
call: regexp.MustCompile(`^template\.(HTML|JS|URL)$`), call: regexp.MustCompile(`^template\.(HTML|JS|URL)$`),
MetaData: gas.MetaData{ MetaData: gas.MetaData{

View file

@ -121,7 +121,7 @@ func (t *InsecureConfigTLS) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, er
return return
} }
func NewModernTlsCheck(conf map[string]interface{}) (gas.Rule, []ast.Node) { func NewModernTlsCheck(conf gas.Config) (gas.Rule, []ast.Node) {
// https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility // https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility
return &InsecureConfigTLS{ return &InsecureConfigTLS{
pattern: regexp.MustCompile(`^tls\.Config$`), pattern: regexp.MustCompile(`^tls\.Config$`),
@ -136,7 +136,7 @@ func NewModernTlsCheck(conf map[string]interface{}) (gas.Rule, []ast.Node) {
}, []ast.Node{(*ast.CompositeLit)(nil)} }, []ast.Node{(*ast.CompositeLit)(nil)}
} }
func NewIntermediateTlsCheck(conf map[string]interface{}) (gas.Rule, []ast.Node) { func NewIntermediateTlsCheck(conf gas.Config) (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
return &InsecureConfigTLS{ return &InsecureConfigTLS{
pattern: regexp.MustCompile(`^tls\.Config$`), pattern: regexp.MustCompile(`^tls\.Config$`),
@ -162,7 +162,7 @@ func NewIntermediateTlsCheck(conf map[string]interface{}) (gas.Rule, []ast.Node)
}, []ast.Node{(*ast.CompositeLit)(nil)} }, []ast.Node{(*ast.CompositeLit)(nil)}
} }
func NewCompatTlsCheck(conf map[string]interface{}) (gas.Rule, []ast.Node) { func NewCompatTlsCheck(conf gas.Config) (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
return &InsecureConfigTLS{ return &InsecureConfigTLS{
pattern: regexp.MustCompile(`^tls\.Config$`), pattern: regexp.MustCompile(`^tls\.Config$`),

View file

@ -33,7 +33,7 @@ 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{}) (gas.Rule, []ast.Node) { func NewUsingUnsafe(conf gas.Config) (gas.Rule, []ast.Node) {
return &UsingUnsafe{ return &UsingUnsafe{
pkg: "unsafe", pkg: "unsafe",
calls: []string{"Alignof", "Offsetof", "Sizeof", "Pointer"}, calls: []string{"Alignof", "Offsetof", "Sizeof", "Pointer"},

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 gas.Config) (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"}