DDoS on the Interledger

plugins
payment-channels
security
#1

I wanted to synthesize some of the interesting events that took place on the public network and in the Interledger gitter last week. Over the past while, several users have been reporting errors connecting to the network. Some of this was due to individual nodes being out of date - in fact, nearly every public XRP-enabled connector was not functional (public defined by inclusion in connector_list.json).

Strata’s connector was working however, but after some debugging I discovered that the their XRP wallet had very little unlocked liquidity - which had interesting consequences for the network. As the only functional connector, the fact that no new channels could be opened meant that the Interledger was effectively “down.”

Modern problems require modern solutions, however. This being 2019 and blockchains being public, I realized that there was a way to prove liquidity was the issue and bring the network back online - I simply located and (lightly) funded Strata’s XRP liquidity pool myself. Immediately, basic network functionality resumed.

This is not a permanent solution however, and I believe the underlying problem presents an attack vector on the network. If I were a bad actor, I could run a zero-cost (but not zero capital) “DDoS” by eating up every connector’s liquidity. This weekend, I could’ve taken down the Interledger (for new connections) with ~$50 and a shell script. And even if the price was much higher, the fact that I can recover almost 100% of funds dedicated to such an attack by closing channels after the desired damage is done dramatically increases the set of actors with such capabilities in practice.

Arriving at the point - while IP does not attempt to prevent DDoS and my intuition is that ILP wont/shouldn’t either, I think last week’s learning shows that there is definitely room for discussion as to how such attacks can be prevented in practice. Currently, ILP documentation (RFC 0018) suggests the below:

Connectors should monitor the percentage of their total liquidity that is on hold at any given time for a given peer, customer, or destination prefix and may reject incoming payment requests if that party exceeds their allocated “payment bandwidth”. Connectors may allocate less bandwidth to unknown or untrustworthy senders or receivers.

However, because the underlying ledgers are unprivileged there is no easy way to distinguish attacker channel creation requests from honest ones. The basic solution is to restrict new connections, but that effectively brings us back to the original problem - new users can’t connect to the Interledger.

Would love to continue the discussion.

3 Likes
#2

Yeah, at present, it’s trivial to DoS the open Interledger network.

Ultimately, the solution will likely involve clients “purchasing” incoming capacity (e.g. by amount and/or time) through prefunding the server, and paying for the server’s transaction fees to open and close a channel back to the client. In this model, servers would not automatically open outgoing channels back to the client. With the XRP client & server, where the defaults are “if you open a channel with > 10 XRP, then I’ll open a channel back to you for 1 XRP,” it’s still pretty easy to tie up a connector’s liquidity, and–as you noted–you can get most of the money back. If servers charged a fee for outgoing channels, even if an attacker tried to tie up their liquidity, it could be priced such that they’d still be making money.

Earlier iterations of the Ethereum plugin attempted to solve this through (1) charging transaction fees to the client, and (2) charging a one-time fee before accepting a new incoming channel from a client (clients would have to front that amount to the server beforehand). However, this made accounting nearly impossible from the client’s perspective: it was opaque, and there was no negotiation. The balances of the two peers would quickly get out of sync. We’ve punted that temporarily, since it will require a more complex negotiation and fee logic that’s nontrivial to implement. (Although, once it’s implemented once, it could be applied to most plugins that use payment channels).

I’d also note that the Lightning plugin doesn’t have these issues, since payment channel management is outside the scope of the plugin, and it’s probably the most secure with respect to denial of service attacks.

4 Likes
#3

Payment channels are really expensive. You could trivially prevent this attack by not using payment channels, and just settling to a peer once the amount becomes high enough to justify making an on-ledger payment. That means no money is locked up, so peering a bunch of times to the connector isn’t a problem.

If you’re OK with the counterparty risk with the connector being a little bit higher (because the frequency of on-ledger payments is lower than signing claims) then this system is pretty good. Otherwise a system like what @kincaid proposed is probably the way to go.

4 Likes
#4

This gets at the question: Should the main Interledger UX use payment channels, on-ledger settlement, or hosted accounts?

What if we went with:

  • XRP: Payment channel from user to connector and on-ledger transfer from connector to user triggered either when a) the user requests it or b) when the buffered amount exceeds a connector limit
  • ETH and ERC-20: Same as XRP (as far as I can tell, the transaction cost is around $0.02 right now, which doesn’t sound too bad)
  • BTC: Lightning for both ways

Update: Lightning also has the channel lockup issue (as described by one frustrated user here) so we could also consider the same model as XRP and ETH for BTC. The fees are higher (currently around $0.50) so you would want to be a little more judicious about on-ledger transfers and setting up the payment channels. However, when you run a Lightning node, it automatically connects to multiple other nodes and pays the transaction fees for that, so opening a channel to a single Interledger connector wouldn’t be any more expensive. The confirmation time is also slower but a receiver could be configured with how many blocks it wants to wait before crediting the connector for the settlement. It could be shipped with a 6-block default but users who trust the connector a little more could configure it lower.

(Technically, we don’t need one decision on this because it is a bilateral concern but we should build the implementations with sensible defaults. The widely varying ways of using Interledger also make it difficult to explain the security model to newcomers, so it would be nice to have a recommended way of using it, even if power users and such may differ from that way.)

1 Like
#5

To clarify, payment channels are expensive from a liquidity perspective, not a cost of creation perspective (except perhaps on BTC/LN, although you can argue that having networked payment channels amortizes the creation of one channel to effectively give you many channels via routing). However, not using payment channels changes the problem from “it’s easy to DDoS connectors on the open interledger” to “it’s easy for connectors to steal on the open interledger”. Large counterparty risk creates its own problems and probably has a nearly disjoint set of use cases to minimized counterparty risk. It’s never going to be either/or and so I don’t think we will resolve the question of “main UX for Interledger” until there is a greater product-market fit for some project using ILP.

2 Likes
#6

Lightning has so far mostly landed on paying for incoming capacity as the solution to this problem (see https://www.bitrefill.com/thor-lightning-network-channels/?hl=en). And I think hubs requiring that users either pay a fee or do some Sybil-resistant self-identification (connect a GitHub account with >15 followers?) is not an unreasonable option.

This sounds mostly reasonable to me. I’ll note that if you have bidirectional top-up-able channels, then this can look like: “Payment channel initially funded 100% by user, topped up by connector when connector balance goes too far negative”, which is somewhat more powerful (although there’s probably a better way to frame it). I know the XRP channels don’t currently support that, but that kind of channel should be possible on Ethereum.

3 Likes