Full Report
In both EVM and Solana programs, a common security issue is not validating external calls properly. This can led to DOS issues, reentrancy or loss of funds bugs. This article has a list of 7 issues to consider. There are many ways that calls can fail. "If you don't know how it can fail, you don't know enough" is a great title for this section. In EVM, contracts without receive() cannot receive ETH. In Solana, there are multiple ways this can happen that was already documented in another post. Apparently, ATA creation in Solana fails if the address has already been created. In EVM, gas griefing can be used to make the main function work but have external calls fail. If the errors are not handled correctly then partial state updates can occur. This isn't possible in Solana because it will always completely rollback on errors. In EVM, reentrancy is really the output of bad validation of the state and the caller. Sometimes, you do need to make calls to an arbitrary callee though. Solana doesn't have this specifically but it DOES have issues with account reloading. In Solana, once a runtime account has been loaded in an instruction, they are not automatically reloaded after making a CPI. So, if the CPI changes the data you will be left with accounts with stale data. The final bug is the dreaded arbitrary CPI in Solana. This is when the address of a program being used for a CPI is not properly validated. I've talked a lot about this here already. This can be used to skip function calls, such as token transfers or be used to abuse permissions. Regardless, they can be very bad. Overall, an interesting piece of literature. Most posts are very focused on one specific set of technology; I enjoy the back and forth between EVM and Solana. It's good to have this stuff documented!
Analysis Summary
# Vulnerability: External Call Improper Validation (EVM & Solana)
## CVE Details
- **CVE ID:** N/A (General vulnerability class/Architectural flaw)
- **CVSS Score:** 7.5 - 9.1 (Estimated: High to Critical)
- **CWE:** CWE-706 (Use of Incorrectly-Resolved Name or Reference), CWE-670 (Always-Incorrect Control Flow Implementation), CWE-841 (Improper Enforcement of Behavioral Workflow)
## Affected Systems
- **Products:** Smart Contracts (Ethereum/EVM) and Programs (Solana/SVM).
- **Versions:** All development versions using manual account validation or non-standard CPI (Cross-Program Invocation) calls.
- **Configurations:**
- **Solana:** Programs using `UncheckedAccount` or `AccountInfo` without manual ID verification; programs performing CPIs without reloading account data.
- **EVM:** Contracts facilitating "Push" payment patterns or lacking reentrancy guards.
## Vulnerability Description
This vulnerability class encompasses multiple flaws arising from how smart contracts interact with external entities:
1. **Denial of Service (DoS):** Malicious callees can trap execution (e.g., a contract without a `receive()` function in EVM) to prevent the caller from completing a transaction.
2. **State Inconsistency (Solana Stale Data):** Solana accounts are not automatically reloaded after a CPI. If the CPI modifies account data, the calling program continues using "stale" in-memory data, leading to logic errors.
3. **Arbitrary CPI:** In Solana, failing to validate the `program_id` of a target account allows an attacker to substitute a malicious program. This can be used to bypass token transfers or spoof authorization.
4. **Gas Griefing (EVM):** Sub-calls can fail due to insufficient gas, but if the parent call doesn't revert, it may result in partial state updates.
## Exploitation
- **Status:** PoC available (well-documented in security literature).
- **Complexity:** Medium
- **Attack Vector:** Network (Blockchain Transaction)
## Impact
- **Confidentiality:** Low (Generally focused on state/funds).
- **Integrity:** High (Unauthorized state changes, salt data usage, bypassed permissions).
- **Availability:** High (Persistent DoS of contract functions).
## Remediation
### Patches
- **Solana/Anchor:** Use the `Program` type instead of `AccountInfo` to benefit from Anchor's automatic ID validation.
- **EVM:** Use OpenZeppelin’s `ReentrancyGuard` and follow the Checks-Effects-Interactions pattern.
### Workarounds
- **Pull over Push:** Implement a withdrawal pattern where users claim funds individually, ensuring one failure does not block the system.
- **Manual Reloading (Solana):** Always call `.reload()` on accounts after a CPI if the underlying data has been modified.
- **Explicit Returns (EVM):** Always check the boolean return value of `address.call()`.
## Detection
- **Indicators of Compromise:** High frequency of failed transactions to specific addresses; unexpected state discrepancies between internal logs and account balances.
- **Detection Methods and Tools:**
- **Static Analysis:** Slither (EVM), SOTER/Anchor-lint (Solana).
- **Fuzzing:** Echidna or Trident to test for unexpected state reverts.
## References
- Alex's Accounts: [https://newsletter.alexlazar.dev/p/external-calls-are-dangerous]
- OtterSec Blog: [https://osec.io/blog/2025-05-14-king-of-the-sol]
- Solana Developer Docs: [https://solana.com/developers/courses/program-security/arbitrary-cpi]