White hat hacker samczsun: attacks on NFT assets will become more frequent

Note: The author of the original text is the white hat hacker samczsun known as the “audit god”, and he is also the research partner of Paradigm. He recently rescued the $350 million assets in the BitDAO MISO Dutch auction fund pool, and in this article In, he reminded the potential security risks of the NFT token standard. He also predicted that as the ERC-721 and ERC-1155 token standards become more popular, attacks against NFTs are likely to become more frequent. .

If you work in software engineering, chances are you have heard of at least one software engineering principle. Although I do not advocate strict observance of every principle, some are indeed worthy of attention.

What I want to talk about today is the principle of least astonishment. It has a peculiar name, but it is a very simple idea. What it says is that when presenting code that claims to do something, most users will assume how it did it. Therefore, as a developer, your job is to write code that meets these assumptions so that your users will not be surprised.

This is a good principle, because developers like to make assumptions about things. If you export a function called calculateScore(GameState), many people will assume that the function will only read from the game state. If you also change the game state, you will cause a lot of people to face a confused state, and they try to figure out why their game state is randomly destroyed. Even if you put it in the documentation, there is still no guarantee that people will see it, so it’s best to first make sure that your code won’t be surprising.

White hat hacker samczsun: attacks on NFT assets will become more frequent

“Six hours of debugging work can save you 5 minutes of document reading time.”

The safer the better, right?

As early as 2018, when the ERC-721 standard was drafted, someone proposed to implement transfer security to ensure that the tokens would not be stuck in the recipient contract that was not used to process the tokens. For this reason, the author of the proposal modified the behavior of the transfer function to check whether the receiver can support token transfer. They also introduced the unsafeTransfer function, which will bypass this check if the sender wishes.

However, due to concerns about backward compatibility, this function was renamed in subsequent commits. This makes the transfer function of ERC-20 and ERC-721 tokens behave the same. However, now the receiver check needs to be transferred elsewhere. Therefore, the standard author introduced safe functions: safeTransfer and safeTransferFrom.

This is a solution to the issue of legitimacy, because there are many examples of ERC-20 tokens being accidentally transferred to contracts that never expect to receive tokens (a particularly common mistake is to transfer tokens to a token contract To lock it permanently). When drafting the ERC-1155 standard, the author of the proposal drew inspiration from the ERC-721 standard, not only in the transfer, but also in the mint (mint) also included receiver inspection, this is not surprising.

In the next few years, most of these standards are dormant, and the ERC-20 token standard has maintained its popularity. The recent surge in gas costs and the increase in community interest in NFTs have naturally led to more and more developers. The more ERC-721 and ERC-1155 token standards are used. With these new interests, we should be thankful that these standards are designed with safety in mind, right?

The safer the better, really?

Ok, but what does security mean for money transfer and casting? Different parties have different interpretations of security. For developers, a security function may mean that it does not contain any bugs or introduce additional security issues. For users, this may mean that it contains additional guardrails to protect them from accidental shots in their feet.

It turns out that in this case, these functions are more of the latter and less of the former. This is particularly regrettable, because when choosing between transfer and safeTransfer functions, why don’t you choose the safe function? The name is reflected!

Well, one of the reasons may be our old friend reentrancy (reentrancy), or I have been trying to rename it: unsafe external calls. Recall that if the receiver is controlled by an attacker, any external calls may be insecure, because the attacker may cause your contract to transition to an undefined state. By design, these “safe” functions perform external calls to the token receiver, usually controlled by the sender during minting or transfer. In other words, this is actually a textbook example of unsafe external calls.

However, you may ask yourself, if the recipient contract is allowed to reject transfers that they cannot handle, what is the worst consequence? Well, let me answer this question through two case studies.

Example 1: Hashmasks

Hashmasks is a NFT avatar project with limited supply. Users can purchase up to 20 mask NFTs per transaction (although they have been sold out for several months). The following is the function of buying mask:

White hat hacker samczsun: attacks on NFT assets will become more frequent

You might think this function looks very reasonable. However, as you might have expected, there is something sinister hidden in the _safeMint call. let’s see.

White hat hacker samczsun: attacks on NFT assets will become more frequent

For security, this function performs a callback to the recipient of the token to check whether they are willing to accept the transfer. However, we are the recipient of the token, which means that we have just received a callback, at this point we can do whatever we want, including calling the mintNFT function again. If we do this, we will call the function again after only one mask has been cast, which means we can request another 19 masks to be cast. This led to the final casting of 39 mask NFTs, although the maximum number allowed by the rules was only 20.

Example 2: ENS domain name wrapper

Recently, Nick Johnson from ENS contacted me and he wanted to show me their ongoing work on the ENS domain name wrapper. This domain name wrapper allows users to tokenize their ENS domain names with the new ERC-1155 token, which provides support for fine-grained permissions and a more consistent API.

In a nutshell, in order to encapsulate any ENS domain name (more specifically, all ENS domain names except 2LD.eth), you must first approve the domain name wrapper to access your ENS domain name. Then, you call wrap(bytes,address,uint96,address), which not only mints an ERC-1155 token for you, but also manages the underlying ENS domain name.

The following is the wrap function, it is quite simple. First, we call _wrap, which performs some logic and returns the hashed domain name. Then, we make sure that the sender of the transaction is indeed the owner of the ENS domain name, and then take over the domain name. Please note that if the sender does not own the underlying ENS domain name, the entire transaction should be reverted and any changes made in _wrap should be undone.

White hat hacker samczsun: attacks on NFT assets will become more frequent

Below is the _wrap function itself, there is nothing special here.

White hat hacker samczsun: attacks on NFT assets will become more frequent

Unfortunately, it is this _mint function that can bring terrible surprises to unsuspecting developers. The ERC-1155 specification stipulates that when casting a token, the recipient should be consulted whether it is willing to accept the token. After in-depth study of the library code (the code library was slightly modified based on OpenZeppelin’s foundation), we found that this is indeed the case.

White hat hacker samczsun: attacks on NFT assets will become more frequent

But what good is this for us? Okay, once again we saw an insecure external call, which we can use to perform a reentrancy attack. Specifically, please note that during the callback period, we have the ERC-1155 token of the token ENS domain name, but the domain name wrapper has not verified that we own the basic ENS domain name itself. This allows us to operate on the ENS domain name without actually owning it. For example, we can ask the domain name wrapper to unlock our domain name, burn the token we just minted, and obtain the underlying ENS domain name.

White hat hacker samczsun: attacks on NFT assets will become more frequent

Now that we have the underlying ENS domain name, we can use it to do whatever we want, such as registering a new subdomain name or setting up a resolver. After completion, we only need to exit the callback callback. The domain name wrapper will interact with the current owner of the underlying ENS domain name (ie us) and complete the transaction. Just like that, we have taken the temporary ownership of any ENS domain name for which the domain name wrapper is approved for use, and made arbitrary changes to it.

in conclusion

Surprising code can destroy things in catastrophic ways. In the two cases in this article, the developers reasonably assumed that the safe function class can be used safely, but inadvertently increased their attack surface. As the ERC-721 and ERC-1155 token standards become more popular and widespread, such attacks are likely to become more frequent. Developers need to consider the risks of using safe functions and determine how external calls interact with the code they write.


Posted by:CoinYuppie,Reprinted with attribution to:https://coinyuppie.com/white-hat-hacker-samczsun-attacks-on-nft-assets-will-become-more-frequent/
Coinyuppie is an open information publishing platform, all information provided is not related to the views and positions of coinyuppie, and does not constitute any investment and financial advice. Users are expected to carefully screen and prevent risks.

Like (0)
Donate Buy me a coffee Buy me a coffee
Previous 2021-08-18 12:31
Next 2021-08-18 12:32

Related articles