gosec: convert global settings as map with proper key type (#3779)
Co-authored-by: Fernandez Ludovic <ldez@users.noreply.github.com>
This commit is contained in:
parent
745ecb9efe
commit
52edd01248
@ -26,20 +26,11 @@ func NewGosec(settings *config.GoSecSettings) *goanalysis.Linter {
|
|||||||
var mu sync.Mutex
|
var mu sync.Mutex
|
||||||
var resIssues []goanalysis.Issue
|
var resIssues []goanalysis.Issue
|
||||||
|
|
||||||
conf := gosec.NewConfig()
|
|
||||||
|
|
||||||
var filters []rules.RuleFilter
|
var filters []rules.RuleFilter
|
||||||
|
conf := gosec.NewConfig()
|
||||||
if settings != nil {
|
if settings != nil {
|
||||||
filters = gosecRuleFilters(settings.Includes, settings.Excludes)
|
filters = gosecRuleFilters(settings.Includes, settings.Excludes)
|
||||||
|
conf = toGosecConfig(settings)
|
||||||
for k, v := range settings.Config {
|
|
||||||
if k != gosec.Globals {
|
|
||||||
// Uses ToUpper because the parsing of the map's key change the key to lowercase.
|
|
||||||
// The value is not impacted by that: the case is respected.
|
|
||||||
k = strings.ToUpper(k)
|
|
||||||
}
|
|
||||||
conf.Set(k, v)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
logger := log.New(io.Discard, "", 0)
|
logger := log.New(io.Discard, "", 0)
|
||||||
@ -140,6 +131,35 @@ func runGoSec(lintCtx *linter.Context, pass *analysis.Pass, settings *config.GoS
|
|||||||
return issues
|
return issues
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func toGosecConfig(settings *config.GoSecSettings) gosec.Config {
|
||||||
|
conf := gosec.NewConfig()
|
||||||
|
|
||||||
|
for k, v := range settings.Config {
|
||||||
|
if k == gosec.Globals {
|
||||||
|
convertGosecGlobals(v, conf)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uses ToUpper because the parsing of the map's key change the key to lowercase.
|
||||||
|
// The value is not impacted by that: the case is respected.
|
||||||
|
conf.Set(strings.ToUpper(k), v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return conf
|
||||||
|
}
|
||||||
|
|
||||||
|
// based on https://github.com/securego/gosec/blob/47bfd4eb6fc7395940933388550b547538b4c946/config.go#L52-L62
|
||||||
|
func convertGosecGlobals(globalOptionFromConfig any, conf gosec.Config) {
|
||||||
|
globalOptionMap, ok := globalOptionFromConfig.(map[string]any)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range globalOptionMap {
|
||||||
|
conf.SetGlobal(gosec.GlobalOption(k), fmt.Sprintf("%v", v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// based on https://github.com/securego/gosec/blob/569328eade2ccbad4ce2d0f21ee158ab5356a5cf/cmd/gosec/main.go#L170-L188
|
// based on https://github.com/securego/gosec/blob/569328eade2ccbad4ce2d0f21ee158ab5356a5cf/cmd/gosec/main.go#L170-L188
|
||||||
func gosecRuleFilters(includes, excludes []string) []rules.RuleFilter {
|
func gosecRuleFilters(includes, excludes []string) []rules.RuleFilter {
|
||||||
var filters []rules.RuleFilter
|
var filters []rules.RuleFilter
|
||||||
@ -173,10 +193,12 @@ func convertToScore(str string) (gosec.Score, error) {
|
|||||||
// code borrowed from https://github.com/securego/gosec/blob/69213955dacfd560562e780f723486ef1ca6d486/cmd/gosec/main.go#L264-L276
|
// code borrowed from https://github.com/securego/gosec/blob/69213955dacfd560562e780f723486ef1ca6d486/cmd/gosec/main.go#L264-L276
|
||||||
func filterIssues(issues []*gosec.Issue, severity, confidence gosec.Score) []*gosec.Issue {
|
func filterIssues(issues []*gosec.Issue, severity, confidence gosec.Score) []*gosec.Issue {
|
||||||
res := make([]*gosec.Issue, 0)
|
res := make([]*gosec.Issue, 0)
|
||||||
|
|
||||||
for _, issue := range issues {
|
for _, issue := range issues {
|
||||||
if issue.Severity >= severity && issue.Confidence >= confidence {
|
if issue.Severity >= severity && issue.Confidence >= confidence {
|
||||||
res = append(res, issue)
|
res = append(res, issue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
70
pkg/golinters/gosec_test.go
Normal file
70
pkg/golinters/gosec_test.go
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
package golinters
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/securego/gosec/v2"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/golangci/golangci-lint/pkg/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_toGosecConfig(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
settings *config.GoSecSettings
|
||||||
|
expected gosec.Config
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "empty config map",
|
||||||
|
settings: &config.GoSecSettings{},
|
||||||
|
expected: gosec.Config{
|
||||||
|
"global": map[gosec.GlobalOption]string{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "with global settings",
|
||||||
|
settings: &config.GoSecSettings{
|
||||||
|
Config: map[string]any{
|
||||||
|
gosec.Globals: map[string]any{
|
||||||
|
string(gosec.Nosec): true,
|
||||||
|
string(gosec.Audit): "true",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: gosec.Config{
|
||||||
|
"global": map[gosec.GlobalOption]string{
|
||||||
|
"audit": "true",
|
||||||
|
"nosec": "true",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "rule specified setting",
|
||||||
|
settings: &config.GoSecSettings{
|
||||||
|
Config: map[string]any{
|
||||||
|
"g101": map[string]any{
|
||||||
|
"pattern": "(?i)example",
|
||||||
|
},
|
||||||
|
"G301": "0750",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: gosec.Config{
|
||||||
|
"G101": map[string]any{"pattern": "(?i)example"},
|
||||||
|
"G301": "0750",
|
||||||
|
"global": map[gosec.GlobalOption]string{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
conf := toGosecConfig(test.settings)
|
||||||
|
|
||||||
|
assert.Equal(t, test.expected, conf)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
5
test/testdata/configs/gosec_global_option.yml
vendored
Normal file
5
test/testdata/configs/gosec_global_option.yml
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
linters-settings:
|
||||||
|
gosec:
|
||||||
|
config:
|
||||||
|
global:
|
||||||
|
nosec: true
|
14
test/testdata/gosec_global_option.go
vendored
Normal file
14
test/testdata/gosec_global_option.go
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
//golangcitest:args -Egosec
|
||||||
|
//golangcitest:config_path testdata/configs/gosec_global_option.yml
|
||||||
|
package testdata
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/md5" // want "G501: Blocklisted import crypto/md5: weak cryptographic primitive"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Gosec() {
|
||||||
|
// #nosec G401
|
||||||
|
h := md5.New() // want "G401: Use of weak cryptographic primitive"
|
||||||
|
log.Print(h)
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user