Skip to content

Commit

Permalink
use go-mask to mask sensitive information in zetaclient config file
Browse files Browse the repository at this point in the history
  • Loading branch information
ws4charlie committed Sep 17, 2024
1 parent 19cbeea commit 1b23e96
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 42 deletions.
2 changes: 1 addition & 1 deletion cmd/zetaclientd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ func start(_ *cobra.Command, _ []string) error {
return err
}

startLogger.Info().Msgf("Config is updated from zetacore %s", maskCfg(cfg))
startLogger.Info().Msgf("Config is updated from zetacore\n %s", cfg.StringMasked())

go zetacoreClient.UpdateAppContextWorker(ctx, appContext)

Expand Down
33 changes: 0 additions & 33 deletions cmd/zetaclientd/start_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,36 +51,3 @@ func validatePeer(seedPeer string) error {

return nil
}

// maskCfg sensitive fields are masked, currently only the endpoints and bitcoin credentials,
//
// other fields can be added.
func maskCfg(cfg config.Config) string {
// Make a copy of the config
maskedCfg := cfg

// Mask EVM endpoints
maskedCfg.EVMChainConfigs = map[int64]config.EVMConfig{}
for key, val := range cfg.EVMChainConfigs {
maskedCfg.EVMChainConfigs[key] = config.EVMConfig{
Chain: val.Chain,
Endpoint: "",
}
}

// Mask BTC endpoints and credentials
maskedCfg.BTCChainConfigs = map[int64]config.BTCConfig{}
for key, val := range cfg.BTCChainConfigs {
maskedCfg.BTCChainConfigs[key] = config.BTCConfig{
RPCParams: val.RPCParams,
}
}
maskedCfg.BitcoinConfig = config.BTCConfig{
RPCParams: cfg.BitcoinConfig.RPCParams,
}

// Mask Solana endpoint
maskedCfg.SolanaConfig.Endpoint = ""

return maskedCfg.String()
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ require (

require (
github.com/oasisprotocol/curve25519-voi v0.0.0-20220328075252-7dd334e3daae // indirect
github.com/showa-93/go-mask v0.6.2 // indirect
github.com/snksoft/crc v1.1.0 // indirect
github.com/tonkeeper/tongo v1.9.3 // indirect
)
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1433,6 +1433,8 @@ github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/showa-93/go-mask v0.6.2 h1:sJEUQRpbxUoMTfBKey5K9hCg+eSx5KIAZFT7pa1LXbM=
github.com/showa-93/go-mask v0.6.2/go.mod h1:aswIj007gm0EPAzOGES9ACy1jDm3QT08/LPSClMp410=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
Expand Down
29 changes: 21 additions & 8 deletions zetaclient/config/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"strings"
"sync"

"github.com/showa-93/go-mask"

"github.com/zeta-chain/node/pkg/chains"
)

Expand Down Expand Up @@ -38,23 +40,23 @@ type ClientConfiguration struct {
// EVMConfig is the config for EVM chain
type EVMConfig struct {
Chain chains.Chain
Endpoint string
Endpoint string `mask:"filled"`
RPCAlertLatency int64
}

// BTCConfig is the config for Bitcoin chain
type BTCConfig struct {
// the following are rpcclient ConnConfig fields
RPCUsername string
RPCPassword string
RPCHost string
RPCUsername string `mask:"filled"`
RPCPassword string `mask:"filled"`
RPCHost string `mask:"filled"`

This comment has been minimized.

Copy link
@swift1337

swift1337 Sep 18, 2024

Contributor

Why do we need to mask the username and the host?

This comment has been minimized.

Copy link
@ws4charlie

ws4charlie Sep 18, 2024

Author Contributor

The RPCHost is the endpoint that could contain an API key or UUID. Username + Password is another way of authentication to access the node, I simply masked both of them to be safe.

RPCParams string // "regtest", "mainnet", "testnet3" , "signet"
RPCAlertLatency int64
}

// SolanaConfig is the config for Solana chain
type SolanaConfig struct {
Endpoint string
Endpoint string `mask:"filled"`

This comment has been minimized.

Copy link
@swift1337

swift1337 Sep 18, 2024

Contributor

I assume a URL here contains an API key in the query, right?

This comment has been minimized.

Copy link
@ws4charlie

ws4charlie Sep 18, 2024

Author Contributor

Yeah. It could be an API key or similar string. Our RPC takes a private UUID.

RPCAlertLatency int64
}

Expand Down Expand Up @@ -147,9 +149,20 @@ func (c Config) GetSolanaConfig() (SolanaConfig, bool) {
return c.SolanaConfig, c.SolanaConfig != (SolanaConfig{})
}

// String returns the string representation of the config
func (c Config) String() string {
s, err := json.MarshalIndent(c, "", "\t")
// StringMasked returns the string representation of the config with sensitive fields masked.
// Currently only the endpoints and bitcoin credentials are masked.
func (c Config) StringMasked() string {
// create a masker
masker := mask.NewMasker()
masker.RegisterMaskStringFunc(mask.MaskTypeFilled, masker.MaskFilledString)

// mask the config
masked, err := masker.Mask(c)
if err != nil {
return ""

Check warning on line 162 in zetaclient/config/types.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/config/types.go#L162

Added line #L162 was not covered by tests
}

s, err := json.MarshalIndent(masked, "", "\t")
if err != nil {
return ""
}
Expand Down
16 changes: 16 additions & 0 deletions zetaclient/config/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,19 @@ func Test_GetBTCConfig(t *testing.T) {
})
}
}

func Test_StringMasked(t *testing.T) {
// create config with defaults
cfg := config.New(true)

// mask the config JSON string
masked := cfg.StringMasked()
require.NotEmpty(t, masked)

// should contain necessary fields
require.Contains(t, masked, "EVMChainConfigs")
require.Contains(t, masked, "BTCChainConfigs")

// should not contain endpoint
require.NotContains(t, masked, "http")
}

0 comments on commit 1b23e96

Please sign in to comment.