Resources

People often ask me "How did you learn how to hack?" The answer: by reading. This page is a collection of the blog posts and other articles that I have accumulated over the years of my journey. Enjoy!

Web3 Ping of Death: Finding and Fixing a Chain-Halting Vulnerability in NEAR- 1510

Faith - ZellicPosted 1 Year Ago
  • Rust is perfectly safe and we never have to worry again, right? In Rust, error handling is tedious and most be specifically handled. Because of this, many denial of service (DoS) vectors revolve around handling errors in Rust.
  • In P2P networking, you are communicating with other computers which in turn communicate with other computers. So, this is a necessity of communicating in a blockchain network and must be externally exposed in some way.
  • The author of this post found two locations where errors were not being handled correctly. First, when verifying a public key the from_slice() function requires that it must be 32 bytes in length. When processing this in the handshake code of P2P, expect(), a nice wrapper for unwrap() is called. If the public key isn't 32 bytes, then a panic is triggered.
  • The second vulnerability has to do with signature parsing. The ECDSA code from_i32() converts the recovery ID value from a single byte to an i32. When doing this, the value is required to be between 0-3 but it can in reality be 0-255. Later on, unwrap() is called, causing a panic upon the error path being taken.
  • Both of these vulnerabilities cause a panic that crashes the node. To me, it's weird that a small parsing issues crashes the node and there is no recovery that happens on the node, similarly to how Golang can. Between the two vulnerabilities, they got 150K in bug bounties, which is awesome! It's fascinating how such little functions in error handling can have catastrophic consequences on the uptime of the software.