A major focus for IPFS in 2020 is improving content routing as the network continues to scale. While we have made significant improvements to request speeds on the DHT, another key focus of ours is the security of the network. As we were working on the release of go-ipfs 0.5, Bernd Prünster and Alexander Marsalek of A-SIT and Graz University of Technology contacted us to let us know that they had discovered an attack during their research on Go-IPFS 0.4.23 that allows an attacker to eclipse any node on the public distributed hash table with minimal resources. We have been working closely with Bernd and Alexander over the past 3 go-ipfs minor releases (0.5, 0.6, and 0.7), which has enabled us to release incremental improvements that mitigate their initial attack and increase the cost and difficulty of such attacks by several orders of magnitude. Today we will dive deeper into the attack and the various mitigations we have released. An Eclipse attack is the ability for an attacker to isolate a peer from the rest of the network so that the targeted peer communicates only with peers controlled by the attacker. The goal of this attack is to pollute the targeted peer's DHT routing table so that only peers controlled by the attacker appear. In the attack discovered by Bernd and Alexander, they used libp2p and a large number of pre-generated peer id lists (29TB of data in total) to create a Sybil attack that gamed the reputation system in libp2p to take over the routing table. If you are not familiar with Sybil attacks, they are where a single peer with an ID is used to subvert the reputation system in order to increase influence over the network. In the context of this attack, the fake ID ends up replacing the honest peer's position in the affected peer's routing table. In order for this attack to succeed, a number of vulnerabilities in libp2p were exposed, which ultimately led to this attack being very effective in go-ipfs 0.4.23. At the time this attack was discovered, a major issue with libp2p was that the DHT did not support long-lived peers, and it did not protect peers in its lower buckets. This issue allowed an attacker to quickly evict honest peers from a target's routing table in favor of dishonest peers. As part of the work to overhaul the DHT in go-ipfs 0.5, we changed the way entries in the routing table are managed. One of the major changes affecting this operation is that we will no longer evict peers from routing tables that are still available. This, combined with other improvements we made to the DHT in go-ipfs 0.5, makes this attack several orders of magnitude harder to perform. You can read about the detailed changes to the DHT in the IPFS 0.5 Content Routing Deep Dive. In addition to the changes in go-ipfs 0.5, we have also addressed several issues that further increased the difficulty and cost of the attack. This attack was successful in part because a Sybil node was able to deceive the reputation system of valuable connections by abusing a flaw in the scoring of nodes that act as relays. The flaw could allow a Sybil node to act as a relay for subsequent Sybil nodes, which would continue to improve the relay's score. This can be accomplished by using nested Sybils for a single peer. To address this, we applied an immutable score to relays, which allows us to still value them but avoids them being able to inflate their reputation. By improving the integrity of our internal reputation system, we have reduced the effectiveness of Sybil attacks. Another major change we made to increase the cost of this class of attacks was the introduction of an IP diversity requirement in the routing table. The original attack on go-ipfs 0.4.23 was able to run on a single machine and was relatively cheap, since the routing table could only contain peers from a single host. The IP diversity requirement now limits the number of peers from any given host, making it infeasible to perform eclipse attacks from a single machine, further increasing the cost of the attack by two orders of magnitude over go-ipfs 0.5. Verify mitigation measures As part of our collaboration with Bernd and Alexander, we wanted to ensure that we could properly test and validate our fixes, and we took two approaches: Live testing. With our permission, they performed a controlled attack on a hosted bootnode on the public network. This allowed us to collect real-time metrics and logs to observe the effectiveness of the attack from both our visibility and their external observations. Controlled attacks were performed on every version of IPFS prior to the release of IPFS starting with go-ipfs 0.5, which allowed us to validate the fix in a production environment. Testground Replication. Thanks to the development and release of Testground, where Bernd and Alexander shared their attack code, we were able to create test plans to replicate parts of the attack. This allowed us to test changes at scale in a controlled test environment to verify that the attack was possible and validate our mitigations. The benefit of having these test plans is that we can continue to run them on IPFS and libp2p versions to ensure that no regressions are introduced. Additionally, this ensures that we can run the attack for longer periods of time in a controlled environment, allowing us to further analyze the efficiency and cost of the attack. Over the past year, we have made significant improvements to the performance and security of both IPFS and libp2p, and collaboration has been an important factor in the success of this work. The research that Bernd and Alexander have done and their willingness to work so closely with us have been invaluable in helping us improve the stability of the network. We are grateful for the opportunity to work together. With the release of go-ipfs 0.7 this September, we increased the difficulty and cost of performing eclipse and Sybil attacks against IPFS and libp2p by several orders of magnitude from its 0.4.23 release. If you haven’t updated to go-ipfs 0.7 yet, we recommend that you do so as soon as possible to take advantage of these improvements. |