chore(lint): enable gosec (#7792)

Enable "gosec" linter.

Exclude:

- All G115 (integer overflow) findings, to be fixed separately.

Add targeted gosec annotations for:

- non-crypto math/rand usage
- md5 used only for file change detection
- G114 ("net/http serve with no timeout settings"), to be fixed
  separately.

Other findings fixed.

Signed-off-by: Ville Vesilehto <ville@vesilehto.fi>
This commit is contained in:
Ville Vesilehto
2025-12-30 00:01:27 +02:00
committed by GitHub
parent 1e0095d9b0
commit b21c752d7f
13 changed files with 35 additions and 15 deletions

View File

@@ -11,6 +11,7 @@ linters:
- copyloopvar
- durationcheck
- godoclint
- gosec
- govet
- ineffassign
- intrange
@@ -39,7 +40,11 @@ linters:
- path: _test\.go
linters:
- perfsprint
- gosec
settings:
gosec:
excludes:
- G115
govet:
enable:
- nilness

View File

@@ -36,7 +36,7 @@ func (c Chaos) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (
default:
return plugin.NextOrFailure(c.Name(), c.Next, ctx, w, r)
case "authors.bind.":
rnd := rand.New(rand.NewSource(time.Now().Unix()))
rnd := rand.New(rand.NewSource(time.Now().Unix())) // #nosec G404 -- non-cryptographic randomness for shuffling authors.
for _, i := range rnd.Perm(len(c.Authors)) {
m.Answer = append(m.Answer, &dns.TXT{Hdr: hdr, Txt: []string{c.Authors[i]}})

View File

@@ -70,6 +70,7 @@ func (d *dio) dial() error {
if d.proto == "tls" {
config := &tls.Config{
// #nosec G402 -- optional, user-configurable escape hatch for environments that cannot validate certs.
InsecureSkipVerify: d.skipVerify,
}
dialer := &net.Dialer{

View File

@@ -195,7 +195,7 @@ Restart:
// jitter returns a random duration between [0,n) * time.Millisecond
func jitter(n int) time.Duration {
r := rand.Intn(n)
r := rand.Intn(n) // #nosec G404 -- non-cryptographic jitter to spread transfer attempts.
return time.Duration(r) * time.Millisecond
}

View File

@@ -63,6 +63,7 @@ func (h *health) OnStartup() error {
ctx := context.Background()
ctx, h.stop = context.WithCancel(ctx)
// #nosec G114 -- TODO
go func() { http.Serve(h.ln, h.mux) }()
go func() { h.overloaded(ctx) }()

View File

@@ -3,7 +3,7 @@ package loadbalance
import (
"bufio"
"bytes"
"crypto/md5"
"crypto/md5" // #nosec G501 -- used only as a checksum for file change detection (not for security).
"errors"
"fmt"
"io"
@@ -52,7 +52,7 @@ type randomUint struct {
}
func (r *randomUint) randInit() {
r.rn = rand.New(rand.NewSource(time.Now().UnixNano()))
r.rn = rand.New(rand.NewSource(time.Now().UnixNano())) // #nosec G404 -- non-cryptographic randomness for load balancing.
}
func (r *randomUint) randUint(limit uint) uint {
@@ -245,7 +245,7 @@ func (w *weightedRR) updateWeights() error {
if err != nil {
return err
}
md5sum := md5.Sum(bytes)
md5sum := md5.Sum(bytes) // #nosec G401 -- used only as a checksum for file change detection (not for security).
if md5sum == w.md5sum {
// file contents has not changed
return nil

View File

@@ -17,7 +17,7 @@ type Rand struct {
// New returns a new Rand from seed.
func New(seed int64) *Rand {
return &Rand{r: rand.New(rand.NewSource(seed))}
return &Rand{r: rand.New(rand.NewSource(seed))} // #nosec G404 -- non-cryptographic RNG by design (load balancing only).
}
// Int returns a non-negative pseudo-random int from the Source in Rand.r.

View File

@@ -95,7 +95,11 @@ func NewTLSConfig(certPath, keyPath, caPath string) (*tls.Config, error) {
return nil, err
}
tlsConfig := &tls.Config{Certificates: []tls.Certificate{cert}, RootCAs: roots}
// #nosec G402 -- MinVersion and MaxVersion are set in setTLSDefaults
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
RootCAs: roots,
}
setTLSDefaults(tlsConfig)
return tlsConfig, nil
@@ -109,7 +113,10 @@ func NewTLSClientConfig(caPath string) (*tls.Config, error) {
return nil, err
}
tlsConfig := &tls.Config{RootCAs: roots}
// #nosec G402 -- MinVersion and MaxVersion are set in setTLSDefaults
tlsConfig := &tls.Config{
RootCAs: roots,
}
setTLSDefaults(tlsConfig)
return tlsConfig, nil

View File

@@ -43,6 +43,7 @@ func (h *handler) Startup() error {
runtime.SetBlockProfileRate(h.rateBloc)
go func() {
// #nosec G114 -- TODO
http.Serve(h.ln, h.mux)
}()
return nil

View File

@@ -61,6 +61,7 @@ func (rd *ready) onStartup() error {
io.WriteString(w, notReadyPlugins)
})
// #nosec G114 -- TODO
go func() { http.Serve(rd.ln, rd.mux) }()
return nil

View File

@@ -60,7 +60,7 @@ func setup(c *caddy.Controller) error {
j = i / 2
}
jitter := time.Duration(rand.Int63n(j.Nanoseconds()) - (j.Nanoseconds() / 2))
jitter := time.Duration(rand.Int63n(j.Nanoseconds()) - (j.Nanoseconds() / 2)) // #nosec G404 -- non-cryptographic jitter.
i = i + jitter
// prepare info for next onInstanceStartup event

View File

@@ -62,8 +62,8 @@ func parse(c *caddy.Controller) (*Sign, error) {
signers[i] = &Signer{
dbfile: dbfile,
origin: origins[i],
jitterIncep: time.Duration(float32(durationInceptionJitter) * rand.Float32()),
jitterExpir: time.Duration(float32(durationExpirationDayJitter) * rand.Float32()),
jitterIncep: time.Duration(float32(durationInceptionJitter) * rand.Float32()), // #nosec G404 -- non-cryptographic jitter.
jitterExpir: time.Duration(float32(durationExpirationDayJitter) * rand.Float32()), // #nosec G404 -- non-cryptographic jitter.
directory: "/var/lib/coredns",
stop: make(chan struct{}),
signedfile: fmt.Sprintf("db.%ssigned", origins[i]), // origins[i] is a fqdn, so it ends with a dot, hence %ssigned.

View File

@@ -12,7 +12,10 @@ func TempFile(dir, content string) (string, func(), error) {
if err != nil {
return "", nil, err
}
if err := os.WriteFile(f.Name(), []byte(content), 0644); err != nil {
if err := f.Close(); err != nil {
return "", nil, err
}
if err := os.WriteFile(f.Name(), []byte(content), 0600); err != nil {
return "", nil, err
}
rmFunc := func() { os.Remove(f.Name()) }
@@ -43,7 +46,7 @@ xGbtCkhVk2VQ+BiCWnjYXJ6ZMzabP7wiOFDP9Pvr2ik22PRItsW/TLfHFXM1jDmc
I1rs/VUGKzcJGVIWbHrgjP68CTStGAvKgbsTqw7aLXTSqtPw88N9XVSyRg==
-----END CERTIFICATE-----`
path := filepath.Join(tempDir, "ca.pem")
if err := os.WriteFile(path, []byte(data), 0644); err != nil {
if err := os.WriteFile(path, []byte(data), 0600); err != nil {
return "", err
}
data = `-----BEGIN CERTIFICATE-----
@@ -64,10 +67,11 @@ zhDEPP4FhY+Sz+y1yWirphl7A1aZwhXVPcfWIGqpQ3jzNwUeocbH27kuLh+U4hQo
qeg10RdFnw==
-----END CERTIFICATE-----`
path = filepath.Join(tempDir, "cert.pem")
if err := os.WriteFile(path, []byte(data), 0644); err != nil {
if err := os.WriteFile(path, []byte(data), 0600); err != nil {
return "", err
}
//nolint:gosec // Test fixture private key.
data = `-----BEGIN RSA PRIVATE KEY-----
MIIEpgIBAAKCAQEAxPBrvAIWiIJp383ndpRF+OuZ74pHsVLTJ/lSv05H+gzcGhL2
y1i7kWXOvfmgvlPq3kZzZ7LvyZSz8KzTumyeNR0ofnlsOklJ0bvNb2Zc3J4vAh58
@@ -96,7 +100,7 @@ E/WObVJXDnBdViu0L9abE9iaTToBVri4cmlDlZagLuKVR+TFTCN/DSlVZTDkqkLI
8chzqtkH6b2b2R73hyRysWjsomys34ma3mEEPTX/aXeAF2MSZ/EWT9yL
-----END RSA PRIVATE KEY-----`
path = filepath.Join(tempDir, "key.pem")
if err := os.WriteFile(path, []byte(data), 0644); err != nil {
if err := os.WriteFile(path, []byte(data), 0600); err != nil {
return "", err
}