cosmos / ibc-rs

Rust implementation of the Inter-Blockchain Communication (IBC) protocol.
Apache License 2.0
205 stars 81 forks source link

Support for untrusted modules #595

Open kevinji opened 1 year ago

kevinji commented 1 year ago

Feature Summary

What would need to be added to add support for untrusted modules? Specifically, in the ibc README, there is a warning saying

This crate currently does not support mutually distrusted packages. That is, modules on the host state machine are assumed to be fully trusted. In practice, this means that every module has either been written by the host state machine developers, or fully vetted by them.

Are there any specific issues that are known with the ibc-rs package that would need to be addressed, or has the possibility of support not really been fully explored? Off the top of my head we would probably need to check for reentrancy attacks.

Proposal

Add support for untrusted modules to fully support ICS 24.

plafer commented 1 year ago

The short answer is that they are not essential to the IBC protocol, and the value of this feature could come if we had hundreds of IBC apps and it simply wasn't possible to review everything. This is not the case today, and we didn't see the value of this today. By the way, not even the Cosmos SDK supports distrusted packages. In my opinion, it never should have made it in the standard.

Is this a feature that you would need?

kevinji commented 1 year ago

I think I need a little bit more context around what an "IBC app" means here. Is it the case that any app that wishes to send messages through an IBC connection must be vetted by the chain developers right now, even if the connection has already been established?

What I was imagining is that the chain devs could help establish IBC connections with other chains, and then untrusted apps could register as modules to send and receive messages. Or would these apps need to split their apps into a "trusted" component that is vetted by the chain devs, and then an "untrusted" component that can't interact directly with the IBC implementation?

plafer commented 1 year ago

I think I need a little bit more context around what an "IBC app" means here.

The term is unfortunately overloaded. An "app" is the same as an "IBC module" (both not great names), or concretely in ibc-rs, the thing that implements Module. Examples are token transfer (ICS 20), interchain accounts (ICS 27), etc.

Is it the case that any app that wishes to send messages through an IBC connection must be vetted by the chain developers right now, even if the connection has already been established?

Yes. To be more precise, apps send packets over channels. A channel can only be established to an app that is bound to a port on the router, and so the channel can't "already be established". The general flow I see is:

  1. chain developer vets app X implementation
  2. chain developer binds app X to port P. This currently requires a hard fork of the chain.
  3. After the hard fork, app X is available at port P
  4. user U opens a channel to app X, connected to app X on some other chain

Specifically what we mean by "needs to be vetted" is: don't just pick an app implementation on some github repo and run it. The app can theoretically be malware; it does not run in a sandbox, and has access to the file system, network, etc. When developers incorporate apps in their chains, it is their responsibility to ensure that the app works as intended.

Let me know if there is still something that is not clear.

kevinji commented 1 year ago

Apologies for missing this earlier. What you're saying makes sense. I had two follow-up questions:

  1. Does the ibc-rs library need to be protected against reentrancy attacks? e.g. suppose that a vetted app has a bug in it in a smart contract environment. Do we need to add reentrancy guards around any parts of the ibc-rs API to try to mitigate this possibility?
  2. Is there some way to expose a generic interface that any user / smart contract developer can use to send messages to another chain? I'm imagining that contract A on chain 1 sends a message destined for contract B on chain 2, intermediated through an IBC module on both chains that simply dumps each message into storage on the destination chain, and maybe notifies the destination contract. Could this be implemented as an IBC module on both chains?
plafer commented 1 year ago

Does the ibc-rs library need to be protected against reentrancy attacks?

That is currently an open question for me, and I currently don't have enough "concrete data" to respond. For one, it depends a lot on the smart contract platform: the EVM architecture allows for reentrancy attacks, but Move-based chains don't. There are other smart contract platforms in Cosmos (Cosmwasm, Agoric, etc), but at this moment none have expressed interest in integrating with ibc-rs, so my specific knowledge about how they work is limited.

TL;DR: we currently design the system around the assumption that IBC apps are "static" SDK-like modules (i.e. present at compile-time, and vetted by the chain developers). Reentrancy attacks thus currently fall outside the scope of ibc-rs, as they would occur in the app code, and depend on how that app code is architected. Let me know if you had a specific smart contract platform in mind.

Is there some way to expose a generic interface that any user / smart contract developer can use to send messages to another chain?

Not sure if I fully understand the question, but hopefully this is useful. Basically if somehow you implement the Module interface for both contracts, and bind them statically to a port (using the Router), then you can obviously simply create a channel between the 2 modules and send packets over it. Again, this requires that your contracts are present at compile-time (i.e. not uploaded by a user after the chain is launched). For contracts uploaded at runtime by any user, then I'd look into how cosmwasm does it. Note though that cosmwasm though is built on top of ibc-go.