diff --git a/node/pkg/governor/governor_integration_test.go b/node/pkg/governor/governor_integration_test.go new file mode 100644 index 0000000000..560becd38d --- /dev/null +++ b/node/pkg/governor/governor_integration_test.go @@ -0,0 +1,67 @@ +//go:build integration + +//nolint:unparam // we exclude the unparam linter because there are many cases here where parameters are static +package governor + +import ( + "context" + "fmt" + "os" + "testing" + + "github.com/stretchr/testify/require" +) + +// Test that the prices are gathering from the CoinGecko API +func TestCoinGeckoPriceChecks(t *testing.T) { + + coinGeckoApiKey := os.Getenv("COIN_GECKO_API_KEY") + if coinGeckoApiKey == "" { + fmt.Println("No API key provided. Skipping pro test.") + } else { + fmt.Println("Using provided API key") + } + + ids := []string{"usd-coin"} + + ctx := context.Background() + gov, err := newChainGovernorForTest(ctx) + require.Equal(t, err, nil) + + /* + The standard governor doesn't have the test suite initiated. Even if it did, + the amount of time this takes is too high So, instead of doing that, we're + testing at a lower level to ensure that the queries are actually made successfully + from the URLs given directly + */ + coinGeckoQueries := createCoinGeckoQueries(ids, 1, "") + require.Equal(t, len(coinGeckoQueries), 1) + + token_map, err := gov.queryCoinGeckoChunk(coinGeckoQueries[0]) + require.Equal(t, err, nil) + token_entry, ok := token_map[ids[0]].(map[string]interface{}) + require.Equal(t, ok, true) + + token_price, ok := token_entry["usd"] + require.Equal(t, ok, true) + require.LessOrEqual(t, token_price, 1.5) + require.GreaterOrEqual(t, token_price, 0.5) + + // Only run if the key is specified + if coinGeckoApiKey != "" { + // Pro API key tests + coinGeckoQueries = createCoinGeckoQueries(ids, 1, coinGeckoApiKey) + require.Equal(t, len(coinGeckoQueries), 1) + + token_map, err = gov.queryCoinGeckoChunk(coinGeckoQueries[0]) + require.Equal(t, err, nil) + + // Check the price information. Make sure it succeeded. + token_entry, ok = token_map[ids[0]].(map[string]interface{}) + require.Equal(t, ok, true) + token_price, ok = token_entry["usd"] + require.Equal(t, ok, true) + require.LessOrEqual(t, token_price, 1.5) + require.GreaterOrEqual(t, token_price, 0.5) + } +} diff --git a/node/pkg/watchers/cosmwasm/watcher_test.go b/node/pkg/watchers/cosmwasm/watcher_test.go new file mode 100644 index 0000000000..3836a65238 --- /dev/null +++ b/node/pkg/watchers/cosmwasm/watcher_test.go @@ -0,0 +1,64 @@ +package cosmwasm + +import ( + "fmt" + "io" + "net/http" + "testing" + "time" +) + +/* +Secondary context bug: +- Restricted behind a Guardian making the request though. So, some good news! +- Doesn't seem to be input validation on the provided data for the TxHash +- The Go request follows redirects according to docs. +- So, either hitting around endpoint where ALL of the data is controlled or finding an arbitrary redirect on any endpoint leads to compromise. + +Reobservation request flow: +- Admin server: + - GetAndObserveMissingVAAs writes to this particular channel. + - Used as a web service by Guardians who have an API key for their box. + - Converts hex string to bytes + +- handleReobservationRequests: + - Inputs are a TxHash (byte array) and chain id + - Based on the chain ID, it writes to a particular channel + - Has a channel that is waiting to be written to + +- CosmWasm parser: + - Takes in the request + - Looks at the `TxHash` field. + - Adds it to a URL + - Makes the request + +Fixes: +- Validate the JSON before using it +- Validate that the txhash is sane +*/ +func TestMakeDirectoryTraversal(t *testing.T) { + client := &http.Client{ + Timeout: time.Second * 5, + } + + tx := "../../../../cosmos/bank/v1beta1/balances/cosmos1mvas6843pv3cmuwrk3pszpqkrfwhrysxx2s9fd" + //tx = "2BD2C41778BFECA0A70E44E4ACF95E347212E69DFD49A4DD9B8042534E34BDBB" + + // Breaking the URL parser probably isn't viable but still something to consider - https://web-assets.claroty.com/exploiting-url-parsing-confusion.pdf + resp, err := client.Get(fmt.Sprintf("%s/cosmos/tx/v1beta1/txs/%s", "https://cosmos-rest.publicnode.com:443/", tx)) + + if err != nil { + fmt.Println("Error:", err) + panic("Error!") + } + + txBody, err := io.ReadAll(resp.Body) + txJSON := string(txBody) + fmt.Println(txJSON) + //txJSON = "{\"tx\":{\"a\": \"\LF\"}}" + + // https://github.com/google/gson/issues/2295 + // " This function expects that the json is well-formed, and does not validate." lol - https://github.com/tidwall/gjson/blob/c2bc5a409a229e55cd1ba59b6cfd5fe1488d6f0f/gjson.go#L2010 + //txHashRaw := gjson.Get(txJSON, "tx") + //fmt.Println(txHashRaw) +}