diff --git a/td2/encryption.go b/td2/encryption.go index 99c129f..6d40efd 100644 --- a/td2/encryption.go +++ b/td2/encryption.go @@ -10,11 +10,12 @@ import ( "encoding/base64" "errors" "fmt" - "github.com/go-passwd/validator" - "golang.org/x/crypto/argon2" "io" "log" "os" + + "github.com/go-passwd/validator" + "golang.org/x/crypto/argon2" ) const ( @@ -86,11 +87,15 @@ func encrypt(plainText []byte, password string) (encryptedConfig []byte, err err buf.Write(salt) buf.Write(iv) - cbc := cipher.NewCBCEncrypter(blk, iv) + cbc := cipher.NewCBCEncrypter(blk, iv) // #nosec G407 - IV is generated randomly with crypto/rand above // pad the plaintext padLen := cbc.BlockSize() - (len(plainText) % cbc.BlockSize()) if padLen > 0 { + // Safe conversion with overflow check + if padLen > 255 { // max uint8 + return nil, fmt.Errorf("padding length too large for uint8: %d", padLen) + } plainText = append(plainText, bytes.Repeat([]byte{uint8(padLen)}, padLen)...) } @@ -124,7 +129,6 @@ func encrypt(plainText []byte, password string) (encryptedConfig []byte, err err // decrypt takes a base64 encoded []byte with salt + iv + ciphertext + mac, the password, and authenticates the HMAC // before it gives back the decrypted configuration. func decrypt(encodedFile []byte, password string) (plainText []byte, err error) { - cipherText := make([]byte, base64.StdEncoding.DecodedLen(len(encodedFile))) size, err := base64.StdEncoding.Decode(cipherText, encodedFile) if err != nil { @@ -182,7 +186,7 @@ func decrypt(encodedFile []byte, password string) (plainText []byte, err error) // EncryptedConfig handles conversion of an encrypted or plaintext config to disk func EncryptedConfig(plaintext, ciphertext, pass string, decrypting bool) error { - var infile, outfile = plaintext, ciphertext + infile, outfile := plaintext, ciphertext if decrypting { outfile, infile = plaintext, ciphertext } diff --git a/td2/provider-default.go b/td2/provider-default.go index f2c2d4b..41ac667 100644 --- a/td2/provider-default.go +++ b/td2/provider-default.go @@ -61,6 +61,7 @@ func (d *DefaultProvider) CheckIfValidatorVoted(ctx context.Context, proposalID // Create a reusable HTTP client with timeout tr := &http.Transport{ + //#nosec G402 -- configurable option TLSClientConfig: &tls.Config{InsecureSkipVerify: td.TLSSkipVerify}, } client := &http.Client{ diff --git a/td2/provider-namada.go b/td2/provider-namada.go index ff6e80d..25511e8 100644 --- a/td2/provider-namada.go +++ b/td2/provider-namada.go @@ -103,6 +103,7 @@ func (d *NamadaProvider) QueryUnvotedOpenProposals(ctx context.Context) ([]gov.P if ok1 && ok2 { // Create a reusable HTTP client with timeout tr := &http.Transport{ + //#nosec G402 -- configurable option TLSClientConfig: &tls.Config{InsecureSkipVerify: td.TLSSkipVerify}, } httpClient := &http.Client{ @@ -274,6 +275,10 @@ func (d *NamadaProvider) QuerySigningInfo(ctx context.Context) (*slashing.Valida hexAddress := strings.ToUpper(hex.EncodeToString(d.ChainConfig.valInfo.Conspub)) for _, v := range livenessInfo.Validators { if v.CometAddress == hexAddress { + // Safe conversion with overflow check + if v.MissedVotes > 9223372036854775807 { // max int64 + return nil, fmt.Errorf("MissedVotes too large for int64: %d", v.MissedVotes) + } signingInfo.MissedBlocksCounter = int64(v.MissedVotes) } } @@ -287,6 +292,11 @@ func (d *NamadaProvider) QuerySlashingParams(ctx context.Context) (*slashing.Par return nil, err } + // Safe conversion with overflow check + if livenessInfo.LivenessWindowLen > 9223372036854775807 { // max int64 + return nil, fmt.Errorf("LivenessWindowLen too large for int64: %d", livenessInfo.LivenessWindowLen) + } + return &slashing.Params{SignedBlocksWindow: int64(livenessInfo.LivenessWindowLen), MinSignedPerWindow: cosmos_sdk_types.MustNewDecFromStr(livenessInfo.LivenessThreshold.String())}, nil } @@ -310,6 +320,7 @@ func (d *NamadaProvider) QueryValidatorSelfDelegationRewardsAndCommission(ctx co if ok1 && ok2 { // Create a reusable HTTP client with timeout tr := &http.Transport{ + //#nosec G402 -- configurable option TLSClientConfig: &tls.Config{InsecureSkipVerify: td.TLSSkipVerify}, } httpClient := &http.Client{ @@ -368,6 +379,7 @@ func (d *NamadaProvider) QueryValidatorVotingPool(ctx context.Context) (votingPo if ok { // Create a reusable HTTP client with timeout tr := &http.Transport{ + //#nosec G402 -- configurable option TLSClientConfig: &tls.Config{InsecureSkipVerify: td.TLSSkipVerify}, } httpClient := &http.Client{ diff --git a/td2/rpc.go b/td2/rpc.go index 6736828..0b19a03 100644 --- a/td2/rpc.go +++ b/td2/rpc.go @@ -310,6 +310,7 @@ func getStatusWithEndpoint(ctx context.Context, u string) (string, bool, error) } tr := &http.Transport{ + //#nosec G402 -- configurable option TLSClientConfig: &tls.Config{InsecureSkipVerify: td.TLSSkipVerify}, } client := &http.Client{Transport: tr} diff --git a/td2/utils/price-conversion.go b/td2/utils/price-conversion.go index 3fd46be..4e4470a 100644 --- a/td2/utils/price-conversion.go +++ b/td2/utils/price-conversion.go @@ -158,7 +158,9 @@ func (c *CoinMarketCapClient) fetchPricesFromAPI(ctx context.Context, slugs []st // Always close the response body defer func(slug string, body io.ReadCloser) { - body.Close() + if err := body.Close(); err != nil { + fmt.Printf("Error closing response body for slug %s: %v\n", slug, err) + } }(slug, resp.Body) // If status is not OK, skip this slug diff --git a/td2/ws.go b/td2/ws.go index e4abe18..826c6db 100644 --- a/td2/ws.go +++ b/td2/ws.go @@ -92,6 +92,7 @@ func (cc *ChainConfig) WsRun() { break } + //#nosec G402 -- configurable option cc.wsclient, err = NewClient(cc.client.Remote(), td.TLSSkipVerify) if err != nil { l(err) @@ -466,6 +467,7 @@ func NewClient(u string, allowInsecure bool) (*TmConn, error) { // Add custom TLS dialer to allow self-signed certs dialer := &websocket.Dialer{ TLSClientConfig: &tls.Config{ + //#nosec G402 -- allowInsecure is true and that is configured by the user InsecureSkipVerify: true, }, HandshakeTimeout: 10 * time.Second,