cosmos / cosmos-sdk

:chains: A Framework for Building High Value Public Blockchains :sparkles:
https://cosmos.network/
Apache License 2.0
6.19k stars 3.58k forks source link

Makefile: mitigate supply chain risk of curl downloading rogue protobuf dependencies without verifying nor signing #13218

Closed odeke-em closed 11 months ago

odeke-em commented 2 years ago

Currently

Currently in the Makefile the following code exists to download and build the protobuf dependencies from Tendermint https://github.com/cosmos/cosmos-sdk/blob/40180cda8fe96a11c4797a7faf634673e545e19a/Makefile#L433-L457

Risk

Our software supply chain security partner and vendor Chainguard Inc performed a supply chain analysis of the cosmos-sdk in https://drive.google.com/file/d/1BCDUSZ3cSdO8FTD9A-nA21_iViONoFln/view and identified the risk of just using cURL to download dependencies per cosmos-sdk-curl-risk Sure this uses HTTPS/SSL but a mere Machine-In-The-Middle (MiTM) attack (common in corporate settings) can serve the desired wrong/target dependencies and without their hashes being verified that further increases the bliss we face

Suggestion

Using HTTPS alone with cURL surely will retrieve the files from the HTTPS source, but if an MiTM occurs there won't be any way to know that the files sent in were the correct ones. Instead, we can perhaps use another protocol which checks and verifies expected SHA* digests of files and relies on prior histories to track file changes, and that protocol is git. I think that perhaps instead of using cURL, we can use git with sparse checkouts to download exactly the target directories without cloning the whole of the tendermint repo but only instead the proto/tendermint directory and here is how we can do it

TM_TARGET_VERSION = v0.37.0-alpha.2
TM_REPO_ALIAS=tm
TM_PROTO_SRC = $(TM_REPO_ALIAS)/proto/tendermint

proto-update-deps-secure:
        @echo "Updating Protobuf dependencies by a sparse git checkout to ensure dependency verification"

        @rm -rf $(TM_REPO_ALIAS)
        @git init $(TM_REPO_ALIAS)  >/dev/null 2>&1 || exit
        @cd $(TM_REPO_ALIAS) && git remote add origin -f git@github.com:tendermint/tendermint.git >/dev/null 2>&1 
        @cd $(TM_REPO_ALIAS) && git config core.spareCheckout true
        @cd $(TM_REPO_ALIAS) && echo -e "abci\nversion\ntypes\ncrypto\nlibs/bits\np2p" | while read F;do echo proto/tendermint/$F >> .git/info/spare-checkout;done
        @cd $(TM_REPO_ALIAS) && git checkout $(TM_TARGET_VERSION) >/dev/null 2>&1  || exit
        @cd $(TM_REPO_ALIAS) && git pull origin $(TM_TARGET_VERSION)  >/dev/null 2>&1 || exit

        @mkdir -p $(TM_ABCI_TYPES)
        @cp $(TM_PROTO_SRC)/abci/types.proto $(TM_ABCI_TYPES)

        @mkdir -p $(TM_VERSION)
        @cp $(TM_PROTO_SRC)/version/types.proto $(TM_VERSION)

        @mkdir -p $(TM_TYPES)
        @cp $(TM_PROTO_SRC)/types/*.proto $(TM_TYPES)

        @mkdir -p $(TM_CRYPTO_TYPES)
        @cp $(TM_PROTO_SRC)/crypto/proof.proto $(TM_CRYPTO_TYPES)
        @cp $(TM_PROTO_SRC)/crypto/keys.proto $(TM_CRYPTO_TYPES)

        @mkdir -p $(TM_LIBS)
        @cp $(TM_PROTO_SRC)/libs/bits/*.proto $(TM_LIBS)

        @mkdir -p $(TM_P2P)
        @cp $(TM_PROTO_SRC)/p2p/types.proto $(TM_P2P)

Just a kind FYI for @elias-orijtech @kirbyquerby @kaniini @amouat @marbar3778

Questions, criticisms and suggestions are highly welcome!

julienrbrt commented 2 years ago

We could advice TM to actively use buf instead too (https://buf.build/tendermint/tendermint/tree/main).

This way we can simply buf export it.

tac0turtle commented 1 year ago

@odeke-em do you want to make a pr here?

odeke-em commented 1 year ago

@kirbyquerby from my team had a much better suggestion! Nathan, please send a PR for it.