Skip to content

Commit 8f3ad45

Browse files
authored
gosec: add configuration (#1930)
1 parent db80e16 commit 8f3ad45

File tree

7 files changed

+93
-9
lines changed

7 files changed

+93
-9
lines changed

.golangci.example.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,30 @@ linters-settings:
334334
# reason: "testing if blocked version constraint works." # Reason why the version constraint exists. (Optional)
335335
local_replace_directives: false # Set to true to raise lint issues for packages that are loaded from a local path via replace directive
336336

337+
gosec:
338+
# To select a subset of rules to run.
339+
# Available rules: https://github.com/securego/gosec#available-rules
340+
includes:
341+
- G401
342+
- G306
343+
- G101
344+
# To specify a set of rules to explicitly exclude.
345+
# Available rules: https://github.com/securego/gosec#available-rules
346+
excludes:
347+
- G204
348+
# To specify the configuration of rules.
349+
# The configuration of rules is not fully documented by gosec:
350+
# https://github.com/securego/gosec#configuration
351+
# https://github.com/securego/gosec/blob/569328eade2ccbad4ce2d0f21ee158ab5356a5cf/rules/rulelist.go#L60-L102
352+
config:
353+
G306: "0600"
354+
G101:
355+
pattern: "(?i)example"
356+
ignore_entropy: false
357+
entropy_threshold: "80.0"
358+
per_char_threshold: "3.0"
359+
truncate: "32"
360+
337361
govet:
338362
# report about shadowed variables
339363
check-shadowing: true

go.sum

Lines changed: 0 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/config/linters_settings.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ type LintersSettings struct {
103103
Gomnd GoMndSettings
104104
GoModDirectives GoModDirectivesSettings
105105
Gomodguard GoModGuardSettings
106+
Gosec GoSecSettings
106107
Govet GovetSettings
107108
Ifshort IfshortSettings
108109
ImportAs ImportAsSettings
@@ -268,6 +269,12 @@ type GoModGuardSettings struct {
268269
} `mapstructure:"blocked"`
269270
}
270271

272+
type GoSecSettings struct {
273+
Includes []string
274+
Excludes []string
275+
Config map[string]interface{} `mapstructure:"config"`
276+
}
277+
271278
type GovetSettings struct {
272279
CheckShadowing bool `mapstructure:"check-shadowing"`
273280
Settings map[string]map[string]interface{}

pkg/golinters/gosec.go

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,41 @@ import (
66
"io/ioutil"
77
"log"
88
"strconv"
9+
"strings"
910
"sync"
1011

1112
"github.com/securego/gosec/v2"
1213
"github.com/securego/gosec/v2/rules"
1314
"golang.org/x/tools/go/analysis"
1415
"golang.org/x/tools/go/packages"
1516

17+
"github.com/golangci/golangci-lint/pkg/config"
1618
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
1719
"github.com/golangci/golangci-lint/pkg/lint/linter"
1820
"github.com/golangci/golangci-lint/pkg/result"
1921
)
2022

2123
const gosecName = "gosec"
2224

23-
func NewGosec() *goanalysis.Linter {
25+
func NewGosec(settings *config.GoSecSettings) *goanalysis.Linter {
2426
var mu sync.Mutex
2527
var resIssues []goanalysis.Issue
2628

2729
gasConfig := gosec.NewConfig()
28-
enabledRules := rules.Generate()
30+
31+
var filters []rules.RuleFilter
32+
if settings != nil {
33+
filters = gosecRuleFilters(settings.Includes, settings.Excludes)
34+
35+
for k, v := range settings.Config {
36+
// Uses ToUpper because the parsing of the map's key change the key to lowercase.
37+
// The value is not impacted by that: the case is respected.
38+
gasConfig.Set(strings.ToUpper(k), v)
39+
}
40+
}
41+
42+
ruleDefinitions := rules.Generate(filters...)
43+
2944
logger := log.New(ioutil.Discard, "", 0)
3045

3146
analyzer := &analysis.Analyzer{
@@ -40,7 +55,8 @@ func NewGosec() *goanalysis.Linter {
4055
).WithContextSetter(func(lintCtx *linter.Context) {
4156
analyzer.Run = func(pass *analysis.Pass) (interface{}, error) {
4257
gosecAnalyzer := gosec.NewAnalyzer(gasConfig, true, logger)
43-
gosecAnalyzer.LoadRules(enabledRules.Builders())
58+
gosecAnalyzer.LoadRules(ruleDefinitions.Builders())
59+
4460
pkg := &packages.Package{
4561
Fset: pass.Fset,
4662
Syntax: pass.Files,
@@ -95,3 +111,18 @@ func NewGosec() *goanalysis.Linter {
95111
return resIssues
96112
}).WithLoadMode(goanalysis.LoadModeTypesInfo)
97113
}
114+
115+
// based on https://github.com/securego/gosec/blob/569328eade2ccbad4ce2d0f21ee158ab5356a5cf/cmd/gosec/main.go#L170-L188
116+
func gosecRuleFilters(includes, excludes []string) []rules.RuleFilter {
117+
var filters []rules.RuleFilter
118+
119+
if len(includes) > 0 {
120+
filters = append(filters, rules.NewRuleFilter(false, includes...))
121+
}
122+
123+
if len(excludes) > 0 {
124+
filters = append(filters, rules.NewRuleFilter(true, excludes...))
125+
}
126+
127+
return filters
128+
}

pkg/lint/lintersdb/manager.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
112112
var importAsCfg *config.ImportAsSettings
113113
var goModDirectivesCfg *config.GoModDirectivesSettings
114114
var tagliatelleCfg *config.TagliatelleSettings
115+
var gosecCfg *config.GoSecSettings
115116

116117
if m.cfg != nil {
117118
govetCfg = &m.cfg.LintersSettings.Govet
@@ -127,6 +128,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
127128
importAsCfg = &m.cfg.LintersSettings.ImportAs
128129
goModDirectivesCfg = &m.cfg.LintersSettings.GoModDirectives
129130
tagliatelleCfg = &m.cfg.LintersSettings.Tagliatelle
131+
gosecCfg = &m.cfg.LintersSettings.Gosec
130132
}
131133

132134
const megacheckName = "megacheck"
@@ -190,7 +192,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
190192
WithLoadForGoAnalysis().
191193
WithPresets(linter.PresetStyle).
192194
WithURL("https://github.com/dominikh/go-tools/tree/master/stylecheck"),
193-
linter.NewConfig(golinters.NewGosec()).
195+
linter.NewConfig(golinters.NewGosec(gosecCfg)).
194196
WithSince("v1.0.0").
195197
WithLoadForGoAnalysis().
196198
WithPresets(linter.PresetBugs).

test/testdata/configs/gosec.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
linters-settings:
2+
gosec:
3+
includes:
4+
- G306
5+
- G101
6+
config:
7+
G306: "0666"
8+
G101:
9+
pattern: "(?i)simple"
10+
ignore_entropy: false
11+
entropy_threshold: "80.0"
12+
per_char_threshold: "3.0"
13+
truncate: "32"

test/testdata/gosec_rules_config.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//args: -Egosec
2+
//config_path: testdata/configs/gosec.yml
3+
package testdata
4+
5+
import "io/ioutil"
6+
7+
const gosecToken = "62ebc7a03d6ca24dca1258fd4b48462f6fed1545"
8+
const gosecSimple = "62ebc7a03d6ca24dca1258fd4b48462f6fed1545" // ERROR "G101: Potential hardcoded credentials"
9+
10+
func gosecCustom() {
11+
ioutil.WriteFile("filename", []byte("test"), 0755) // ERROR "G306: Expect WriteFile permissions to be 0666 or less"
12+
}

0 commit comments

Comments
 (0)