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!

Nonce Upon a Time, or a Total Loss of Funds - Exploring Solana Core Part 3 - 1392

NeodymePosted 1 Year Ago
  • Preventing the replay of previous transactions is important for the security of Solana and most blockchain systems. The obvious way would be to check if a signature had already been seen. However, this runs into scaling issues with over 150B transactions and signature malleability issues. So, something else needs to be done.
  • The initial solution was to just not allow transactions that are too old. In particular, if the signature contains an out of date blockhash, then it can be safely ignored. This strategy doesn't work with offline signing though. If the transaction is signed offline then the blockhash may have expired. Since some users want to do things offline with their key, there needs to be another way.
  • Durable Transaction Nonces are a number used once (nonce) stored on chain ahead of time. Instead of putting the blockhash, the nonce is used. After the nonce is used, a new value is generated and stored on chain for the account. Of course, this must be done in both failed and successful calls in order to prevent unintentional execution of the transaction later. This functionality is complicated and very nuanced.
  • Most of the time, the Solana core expects all state to rollback for failure. For instance, writing to an account that you don't own will result in failure. The author points out that "Special cases lead to complexity, and complexity leads to bugs." which I couldn't agree with more! This is a little thing that if not done correctly could cause major havoc.
  • There is a match expression written in Rust that checks three cases - tx succeeded with nonce, tx succeeded with hash and whether an error occurred. The success case for the nonce case actually takes in both succeeded and failed transactions with state writes! What does this mean? Even illegal state writes, such as cross account, can persist. It seems like illegal is different than a regular failure in this context - so, errors get funky leading to the bug.
  • This completely breaks the entire security model of the system. One account can write to another account with arbitrary value. This is an absolute 100% game over, as far as Solana bugs go. At the point this bug was found, $10B was on Solana. I hope they got a huge bug bounty for this find!
  • This is a crazy bug that destroys the entire run time. I think the authors make a really good point that sticks with me - "As a rule of thumb, we recommend that you double-check special cases and complex code". If there is interwoven logic with weird case statements, it's a great place to look for bugs. Subtle calling patterns and unexpected errors can break this code very quickly.