Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(go): introduce gosec linter #4501

Merged
merged 1 commit into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ linters:
#- gocyclo
#- godot
- gofumpt
#- gosec
- gosec
- gosimple
- govet
- ineffassign
Expand Down Expand Up @@ -85,6 +85,12 @@ linters-settings:
- style
gofumpt:
extra-rules: true
gosec:
excludes:
- G110
- G115
- G204
- G306
lll:
line-length: 150

Expand Down
11 changes: 7 additions & 4 deletions cmd/gitops-server/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,8 +293,9 @@ func runCmd(cmd *cobra.Command, args []string) error {

addr := net.JoinHostPort(options.Host, options.Port)
srv := &http.Server{
Addr: addr,
Handler: handler,
Addr: addr,
Handler: handler,
ReadHeaderTimeout: 5 * time.Second,
}

go func() {
Expand All @@ -318,8 +319,9 @@ func runCmd(cmd *cobra.Command, args []string) error {
metricsMux.Handle("/metrics", promhttp.HandlerFor(gatherers, promhttp.HandlerOpts{}))

metricsServer = &http.Server{
Addr: options.MetricsAddress,
Handler: metricsMux,
Addr: options.MetricsAddress,
Handler: metricsMux,
ReadHeaderTimeout: 5 * time.Second,
}

go func() {
Expand Down Expand Up @@ -375,6 +377,7 @@ func listenAndServe(log logr.Logger, srv *http.Server, options Options) error {
srv.TLSConfig = &tls.Config{
ClientCAs: caCertPool,
ClientAuth: tls.RequireAndVerifyClientCert,
MinVersion: tls.VersionTLS12,
}
} else {
log.Info("Using TLS", "cert_file", options.TLSCertFile, "key_file", options.TLSKeyFile)
Expand Down
6 changes: 2 additions & 4 deletions cmd/gitops/root/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package root
import (
"fmt"
"log"
"math/rand/v2"
"os"
"strings"
"time"

"github.com/manifoldco/promptui"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -121,10 +121,8 @@ func RootCmd() *cobra.Command {
enableAnalytics = true
}

seed := time.Now().UnixNano()

gitopsConfig = &config.GitopsCLIConfig{
UserID: config.GenerateUserID(10, seed),
UserID: config.GenerateUserID(10, rand.Uint64()), // #nosec G404
Analytics: enableAnalytics,
}

Expand Down
6 changes: 2 additions & 4 deletions cmd/gitops/set/config/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ package config

import (
"fmt"
"math/rand/v2"
"os"
"strconv"
"strings"
"time"

"github.com/spf13/cobra"

Expand Down Expand Up @@ -77,9 +77,7 @@ func setConfigCommandRunE(opts *cfg.Options) func(*cobra.Command, []string) erro
gitopsConfig.Analytics = analyticsValue

if gitopsConfig.UserID == "" {
seed := time.Now().UnixNano()

gitopsConfig.UserID = config.GenerateUserID(10, seed)
gitopsConfig.UserID = config.GenerateUserID(10, rand.Uint64()) // #nosec G404
}

log.Actionf("Saving GitOps CLI config ...")
Expand Down
2 changes: 1 addition & 1 deletion core/server/inventory.go
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ func parseInventoryFromUnstructured(obj *unstructured.Unstructured) ([]*unstruct
return objects, nil
}

const helmSecretNameFmt = "sh.helm.release.v1.%s.v%v"
const helmSecretNameFmt = "sh.helm.release.v1.%s.v%v" // #nosec G101

func secretNameFromHelmRelease(helmRelease *helmv2.HelmRelease) *client.ObjectKey {
if latest := helmRelease.Status.History.Latest(); latest != nil {
Expand Down
2 changes: 1 addition & 1 deletion pkg/analytics/analytics.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const (
app = "cli"
analyticsType = "track"
trackEventURL = "https://app.pendo.io/data/track"
trackEventSecret = "bf6ab33e-cd70-46e7-4b77-279f54cac447"
trackEventSecret = "bf6ab33e-cd70-46e7-4b77-279f54cac447" // #nosec G101
)

type analyticsRequestBody struct {
Expand Down
8 changes: 4 additions & 4 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"fmt"
"io"
"io/fs"
"math/rand"
"math/rand/v2"
"os"
"path/filepath"
)
Expand Down Expand Up @@ -188,12 +188,12 @@ func parseConfig(data []byte, config *GitopsCLIConfig) error {
}

// GenerateUserID generates a string of specified length made of random characters and encodes it in base64 format
func GenerateUserID(numChars int, seed int64) string {
srand := rand.New(rand.NewSource(seed))
func GenerateUserID(numChars int, seed uint64) string {
srand := rand.New(rand.NewPCG(seed, 0)) // #nosec G404

b := make([]byte, numChars)
for i := range b {
b[i] = letters[srand.Intn(len(letters))]
b[i] = letters[srand.IntN(len(letters))]
}

return string(b)
Expand Down
2 changes: 1 addition & 1 deletion pkg/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ var _ = Describe("GenerateUserID", func() {
It("generates user ID", func() {
userID := GenerateUserID(10, 1024)

Expect(userID).To(Equal("2Q2MsgBDSV"))
Expect(userID).To(Equal("ULhi8C5Ti1"))
})
})
8 changes: 5 additions & 3 deletions pkg/http/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"net"
"net/http"
"sync"
"time"
)

// MultiServer lets you create and run an HTTP server that serves over both, HTTP and HTTPS. It is a convenience wrapper around net/http and crypto/tls.
Expand Down Expand Up @@ -59,7 +60,7 @@ func createTLSListener(port int, certFile, keyFile string) (net.Listener, error)
return nil, fmt.Errorf("unable to load TLS key pair: %w", err)
}

listener, err := tls.Listen("tcp", fmt.Sprintf(":%d", port), &tls.Config{Certificates: []tls.Certificate{cert}})
listener, err := tls.Listen("tcp", fmt.Sprintf(":%d", port), &tls.Config{Certificates: []tls.Certificate{cert}, MinVersion: tls.VersionTLS12})
if err != nil {
return nil, fmt.Errorf("unable to start TLS listener: %w", err)
}
Expand All @@ -69,8 +70,9 @@ func createTLSListener(port int, certFile, keyFile string) (net.Listener, error)

func startServer(ctx context.Context, hndlr http.Handler, listener net.Listener, logger *log.Logger) {
srv := http.Server{
Addr: listener.Addr().String(),
Handler: hndlr,
Addr: listener.Addr().String(),
Handler: hndlr,
ReadHeaderTimeout: 5 * time.Second,
}
logger.Printf("https://%s", srv.Addr)

Expand Down
11 changes: 6 additions & 5 deletions pkg/http/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"fmt"
"io"
"log"
"math/rand"
"math/rand/v2"
"net/http"
"os"
"testing"
Expand Down Expand Up @@ -43,11 +43,11 @@ func TestMultiServerWithoutTLSConfigFailsToStart(t *testing.T) {
func TestMultiServerServesOverBothProtocols(t *testing.T) {
g := NewGomegaWithT(t)

httpPort := rand.Intn(49151-1024) + 1024
httpsPort := rand.Intn(49151-1024) + 1024
httpPort := rand.N(49151-1024) + 1024 // #nosec G404
httpsPort := rand.N(49151-1024) + 1024 // #nosec G404

for httpPort == httpsPort {
httpsPort = rand.Intn(49151-1024) + 1024
httpsPort = rand.N(49151-1024) + 1024 // #nosec G404
}

srv := wegohttp.MultiServer{
Expand Down Expand Up @@ -93,7 +93,8 @@ func TestMultiServerServesOverBothProtocols(t *testing.T) {

tr := &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: rootCAs,
RootCAs: rootCAs,
MinVersion: tls.VersionTLS12,
},
}
c := http.Client{
Expand Down
6 changes: 0 additions & 6 deletions pkg/kube/kube_suite_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package kube_test

import (
"math/rand"
"testing"
"time"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
Expand Down Expand Up @@ -39,7 +37,3 @@ var _ = BeforeSuite(func() {
var _ = AfterSuite(func() {
cleanupK8s()
})

func init() {
rand.New(rand.NewSource(time.Now().UnixNano()))
}
4 changes: 2 additions & 2 deletions pkg/names/names.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package names

import (
"crypto/md5"
"crypto/sha256"
"fmt"
"strings"

Expand Down Expand Up @@ -43,7 +43,7 @@ func hashNameIfTooLong(name string) string {
return name
}

return fmt.Sprintf("wego-%x", md5.Sum([]byte(name)))
return fmt.Sprintf("wego-%x", sha256.Sum224([]byte(name)))
}

func ApplicationNameTooLong(name string) bool {
Expand Down
9 changes: 5 additions & 4 deletions pkg/oidc/check/flow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,16 @@ func (tp TestProvider) genToken() string {
}

func (tp *TestProvider) Start() error {
listener, err := net.Listen("tcp", ":8765")
listener, err := net.Listen("tcp", "127.0.0.1:8765")
if err != nil {
return fmt.Errorf("failed starting listener: %w", err)
}

tp.URL = fmt.Sprintf("http://%s", listener.Addr().String())
mux := http.ServeMux{}
tp.srv = &http.Server{
Handler: &mux,
Handler: &mux,
ReadHeaderTimeout: 5 * time.Second,
}

mux.HandleFunc("/.well-known/openid-configuration", func(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -160,7 +161,7 @@ func TestGetClaimsWithSecret(t *testing.T) {
SecretName: "test-oidc",
SecretNamespace: "flux-system",
OpenURL: func(u string) error {
http.Get(u)
http.Get(u) // #nosec: G107
return nil
},
InsecureSkipSignatureCheck: true,
Expand Down Expand Up @@ -311,7 +312,7 @@ func TestGetClaimsWithoutSecret(t *testing.T) {

if tt.opts.OpenURL == nil {
tt.opts.OpenURL = func(u string) error {
http.Get(u)
http.Get(u) // #nosec: G107
return nil
}
}
Expand Down
5 changes: 3 additions & 2 deletions pkg/oidc/check/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ var errorHTML string
func retrieveIDToken(log logger.Logger, oauth2Config oauth2.Config, verifier *oidc.IDTokenVerifier) (*oidc.IDToken, error) {
mux := http.ServeMux{}
srv := http.Server{
Handler: &mux,
Handler: &mux,
ReadHeaderTimeout: 5 * time.Second,
}
var idToken *oidc.IDToken
var handleErr error
Expand Down Expand Up @@ -70,7 +71,7 @@ func retrieveIDToken(log logger.Logger, oauth2Config oauth2.Config, verifier *oi
fmt.Fprint(w, successHTML)
})

listener, err := net.Listen("tcp", ":9876")
listener, err := net.Listen("tcp", ":9876") // #nosec G102
if err != nil {
return nil, fmt.Errorf("failed starting listener: %w", err)
}
Expand Down
9 changes: 3 additions & 6 deletions pkg/s3/auth_middleware_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ import (
"bytes"
"fmt"
"io"
"math/rand"
"math/rand/v2"
"net/http"
"net/http/httptest"
"testing"
"time"

"github.com/minio/minio-go/v7/pkg/signer"
. "github.com/onsi/gomega"
Expand All @@ -19,11 +18,9 @@ func generateRandomBody(method string) io.Reader {
return nil
}

srand := rand.New(rand.NewSource(time.Now().UnixNano()))

size := srand.Intn(2000) + 2000
size := rand.N(2000) + 2000 // #nosec G404
buf := make([]byte, size)
srand.Read(buf)
_, _ = rand.NewChaCha8([32]byte{}).Read(buf)

return bytes.NewReader(buf)
}
Expand Down
12 changes: 6 additions & 6 deletions pkg/s3/secret_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import (
"fmt"
"io"
"math/big"
"math/rand"
"math/rand/v2"
"testing"

. "github.com/onsi/gomega"
)

func deterministicRandInt(seed int64, err error) RandIntFunc {
func deterministicRandInt(seed uint64, err error) RandIntFunc {
var srand *rand.Rand

return func(_ io.Reader, max *big.Int) (*big.Int, error) {
Expand All @@ -19,10 +19,10 @@ func deterministicRandInt(seed int64, err error) RandIntFunc {
}

if srand == nil {
srand = rand.New(rand.NewSource(seed))
srand = rand.New(rand.NewPCG(seed, 0)) // #nosec G404
}

return big.NewInt(int64(srand.Intn(int(max.Int64())))), nil
return big.NewInt(srand.Int64N(max.Int64())), nil // #nosec G404
}
}

Expand All @@ -38,7 +38,7 @@ func TestGenerators(t *testing.T) {
name: "GenerateAccessKey generates a deterministic access key",
generator: GenerateAccessKey,
randIntFunc: deterministicRandInt(100, nil),
expected: "AKIA5UQA4UZJM3",
expected: "AKIATBK3988IAG",
expectedErr: false,
},
{
Expand All @@ -52,7 +52,7 @@ func TestGenerators(t *testing.T) {
name: "GenerateSecretKey generates a deterministic secret key",
generator: GenerateSecretKey,
randIntFunc: deterministicRandInt(512, nil),
expected: "Fg5n9W6CwTfnMu4FzEk8xuTomwk2OpFe0yLcLMAL",
expected: "0aEEdyKByGEXsQUh1af86o6HON4Ig468I6DhJH1C",
expectedErr: false,
},
{
Expand Down
4 changes: 2 additions & 2 deletions pkg/server/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package auth

import (
"context"
"crypto/md5"
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"encoding/hex"
"fmt"
Expand Down Expand Up @@ -106,7 +106,7 @@ func (p *UserPrincipal) String() string {

// Hash returns a unique string using user id,token and groups.
func (p *UserPrincipal) Hash() string {
hash := md5.Sum([]byte(fmt.Sprintf("%s/%s/%v", p.ID, p.Token(), p.Groups)))
hash := sha256.Sum224([]byte(fmt.Sprintf("%s/%s/%v", p.ID, p.Token(), p.Groups)))
return hex.EncodeToString(hash[:])
}

Expand Down
Loading
Loading