The Stacks signer lacks connection rate limiting, maximum concurrent connection checks, and restrictions on peer connection requests, making it vulnerable to potential libp2p Denial-of-Service (DoS) attacks from a malicious signer.
Vulnerability Details
Currently, the Stacks signer does not have any specific rate or concurrent network connection limit logic. However, it connects to other signer nodes according to the connection diagram using the libp2p library. In the default implementation, libp2p does not enforce rate limiting or concurrent network connection restrictions. As a result, a malicious signer can easily compromise the system by establishing numerous connections via libp2p, ultimately causing the signer process to crash due to file descriptor exhaustion, as each established connection consumes a file descriptor.
Impact Details
A malicious signer can attack as many signer nodes as possible by exploiting this vulnerability. This will cause the signer’s main processes to cease, including signing and validating Stacks blocks produced by Stacks miners, signing and validating sBTC mint and redeem transactions, and securing BTC rewards for their work. Eventually, it may cause the unintended chain split (network partition).
Attacking Scenario
Malicious attacker node(s) (known signer) increase their file descriptors to the maximum possible value to prevent themselves from stalling.
Reference:Baeldung - Limit File Descriptors
Malicious attacker node(s) (known signer) launch an attack by simultaneously increasing the libp2p swarm process, which in turn increases connections to all known public victim signer nodes, reaching the maximum number of established connections (default: 1024) and exhausting the available file descriptors on each victim signer node.
As a result, all victim signer nodes become unable to process computations and stall due to file descriptor exhaustion.
Reference: See the attachment of this attacking diagram
This Proof of Concept (PoC) demonstrates that an attacker node can establish an excessive number of connections with the libp2p swarm to a victim node (Port: 19999) due to the lack of connection mitigation implementation. Eventually, this leads to file descriptor exhaustion, causing the application to stall with the error message "too many open files" (as shown in poc_diagram.png).
Reference:
PoC Code
Setting Up the PoC
Clone the sbtc repository:
Append the PoC code to the swarm.rs file:
Running the PoC
Observing the Vulnerability
During the execution of this test, you will see many established connections between the attacker node (port: N) and the victim node (port: 19999).
The ss command output shows that the victim node (port: 19999) has many established connections, using file descriptors.
Reference:
The screenshot shows the process being stalled with the "too many open files" error message.