Approval of Transfer or Approval of “Robbery”
— A deeper analysis of recent phishing attacks on applications deployed on Solana by Fairyproof
— A deeper analysis of recent phishing attacks on applications deployed on Solana by Fairyproof
In early March, security phishing attacks happened consecutively on applications deployed on the Solana blockchain. Various articles analyzed the root causes of these incidents from a technical point of view.
One article mentioned that a website named “https://officialsolanarares.net/mint/” could transfer the SOLs held in a user account right after the user account “approved” the website’s token transfer request.
Here is a section from this article: after a Solana smart contract gets a user account’s approval, it could transfer Solana’s native cryptocurrency(i.e. SOL) held in that account. This is technically impossible on Ethereum because an “approve” function in an Ethereum smart contract can only approve the transfer of Ethereum’s non-native cryptocurrencies such as ERC-20 tokens, ERC-721 tokens, etc. This would lead users who have established a deep understanding of Ethereum smart contracts while are not that familiar with Solana smart contracts to overlook the difference between the two blockchain smart contracts when they interact with an unidentified application deployed on Solana and may be exploited by a malicious smart contract deployed on Solana.
However, the description in this section about “approve” is confusing. It doesn’t clarify the difference between an “approve” operation on Ethereum and an “approve” operation on Solana.
In these phishing attacks, the SOLs held in a user account were transferred but this was not caused by “approving the spending of a token”.
In order to clarify the difference, let’s review some concepts one by one:
1 “Approve” in Ethereum Smart Contracts (i.e. Smart Contracts Implemented in Solidity)
In Solidity, “approve” means to approve or allow a specified address to transfer a specified number of tokens. After “approve” is done, the tokens are still in the holder’s account. It only means the specified address can spend the specified number of tokens from the holder’s account.
For instance, when an external address interacts with a smart contract and that smart contract needs to spend a number of tokens held in that external address, the smart contract should have the approval of spending the token before it can actually spend. After that external address has approved the smart contract to do so, then the interaction would proceed successfully otherwise the interaction wouldn’t be able to continue. Therefore this “approve” is a must-have step for the interaction to proceed.
However, this “approve” would introduce risks. For instance, if an external address carelessly approves a malicious smart contract to spend a type of token in it, the tokens held in that external address might be spent any time by that malicious contract. This would expose the address’ tokens to huge risks.
2 “Approve” in Solana Smart Contracts
In Solana, a fungible token is generally implemented based on the SPL-token contract template. This template mimics the functions and behavior of a standard ERC-20 token, therefore a fungible token in Solana has “approve” and the “approve” has a similar behavior as an ERC-20 token. A Solana’s fungible token and an Ethereum’s ERC-20 token share this commonality.
3. A Deeper Understanding of “Approve”
For some users, when they interact with smart contracts in either Ethereum or Solana they are used to thinking of “approve” as approving the spending of a token. When a user interacts with an Ethereum’s smart contract and uses MetaMask, if that contract requires the user to approve spending of a token, MetaMask will pop up a message with the details of the “approve” operation. When a user interacts with a Solana’s smart contract and uses Phantom (a Solana-based wallet), Phantom will pop up an Approve button and this would easily make the user think that this is to approve spending of a token as well. However, the reality is to approve a transaction which could be of any operation.
Therefore, in these phishing attacks, the root cause was not these users approved the spending of a token but was these users approved an unidentified operation which eventually resulted in the SOLs being taken away from their wallets.
4. A Transaction That Spends Native Cryptocurrencies
There are methods that allow native cryptocurrencies to be spent in both Ethereum and Solana. In an Ethereum’s smart contract, calling a “payable” function would spend the ETHs in an account. In a Solana’s smart contract calling a “transfer” function would spend the SOLs in an account. Neither of these two operations is the “approve” operation we discussed above.
The difference between an Ethereum’s smart contract and a Solana’s smart contract is: in an Ethereum’s smart contract implemented in Solidity, ETHs may be spent only when a smart contract is called, and if ETHs are to be spent the spent amount will be displayed on a wallet in advance, while in Solana, a transfer of SOLs may happen internally in a contract and the transferred amount cannot be displayed on a wallet in advance. Therefore, when a user interacts with a Solana’s smart contract and signs a transaction of transferring some SOLs, the SOLs in the user’s account will be transferred.
Let’s take a look at the following code sample:
The code here transfers SOLs internally in a contract.
5. Application of Signatures in Solana
The application of signatures in Solana is different from that of Ethereum. For instance, if there are two smart contracts A and B deployed on Solana and If a user signs a transaction with contract A and contract A calls contract B, this signature will be valid in contract B as well after contract A calls contract B. Therefore, if a user signs a transaction with a malicious contract, this contract will get that user’s valid signature and this signature can be used to sign a subsequent transaction.
In the phishing attacks, the users interacted with a malicious contract deployed at 3VtjHnDuDD1QreJiYNziDsdkeALMT6b2F9j3AXdL4q8v, this contract then used the users’ signatures to sign transactions to transfer the SOLs held in their accounts.
6. Details of the Phishing Attacks
Let’s take a look at one of the phishing attacks at:
The input account of this transaction was
Here a user account was 4XF4wyjein7ZN4RPM6YK2mC2mC6T41cZAoKjJqpP19fR.
An unidentified Solana account was BepccLHDcXqqHi6MfpTDo9Sfc5tmRjmSC1XY48Tb8HuY.
And the malicious contract was deployed at 3VtjHnDuDD1QreJiYNziDsdkeALMT6b2F9j3AXdL4q8v
From the screenshot, we can see that after the user account called the contract, 1.2545 SOLs were transferred to the unidentified Solana account. The whole transaction process didn’t invoke any interaction with an SPL-token contract and didn’t invoke any “approve” operation either.
Here is a screenshot of the log:
From the log, we can see that the contract called a system contract to transfer the user’s SOLs. This was all because the user’s signature was used by the malicious contract which later on called the system contract.
7. Conclusion
A best practice from Fairyproof: when you interact with a smart contract deployed on Solana, you shouldn’t approve a suspicious transaction since your signature might be exploited to do unexpected things if you approve it.