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!

A critical bug that AI misses- 2207

AccretionPosted 5 Days Ago
  • Last year, the company reviewed an upgrade of an implementation of the Light Protocol that was turning it from an Anchor project to a Pinocchio project. This is likely a change from React to Angular: it's a huge change, and there are bound to be subtle differences.
  • Light has a compression layer on Solana, that allows state to be spread across a Merkle tree instead of storing individual records in each account. Tokens can be represented in two ways: compressed and regular. The compressed token program (cToken) has operations such as minting, transferring, and burning compressed tokens. You should be able to move between these two token types. While doing this, it MUST preserve value and not create new balance out of thin air.
  • When you call initialize_ctoken_account(), it fills its mint, sets its spending authority, and gives it a zero balance. Before doing this, it must allocate the storage. There are multiple handlers to initialize this, and this is where the bug is.
  • The code for setting the new token information in Pinachio only sets mint, owner, and state. Why didn't it set the amount? The code has a comment for this: "Account is already zeroed, only need to set these 3 fields" This makes the assumption that the account is freshly allocated but it may not be! It does check for a field marker that has an uninitialized value, and a specific size but nothing more.
  • So, the goal is to get an account that has the uninitialized marker in the proper spot and is the exact size of the token account. If this happens, the amount will contain leftover values when we initialize the token account. To do this, they used the hidden IDL instructions on all Anchor programs that they had noticed in the past.
  • What's funny about this is that this couldn't be pulled off at the same time. The IDL functions would only exist in the Anchor version. The Pinocchio version had the bad initialization. So, this would have to be a pre-planned exploit. What an amazing type confusion bug! This gives you a much larger balance than what should have been allowed.
  • A big claim for this post was that AI kept missing it. So, why? The AI reviews the new code at hand without considering previous code. Accounts created before an upgrade aren't magically deleted just because an upgrade happened. This timeline is hard to visualize mentally. I like this the most... it gives humans a future where esoteric knowledge and 3D thinking can still find bugs. Overall, an amazing blog post!