Full Report
Stacks is a Bitcoin L2 blockchain. It uses the Clarity (Cl) language, which has a LISP-like syntax, for executing smart contracts. For some reason, the article says that it's more secure to use an interpreted language vs a compiled language, which makes zero sense to me. Neither of these is more or less secure, as shown by the bug. The vulnerability is a really simple denial of service vulnerability found by bad error handling. When calling ft-get-supply with a non-existent address the Rust error handling doesn't consider the case where nothing is returned. So, the Clarity VM crashes in this case. Fixing this is trivial; just make a call to Some/None in Rust. Overall, a really simple bug that paid out quite a bit. The more esoteric stuff you look, the lower the bugs will be on the tree.
Analysis Summary
# Vulnerability: Stacks Clarity VM Denial of Service via Unhandled Exception
## CVE Details
- **CVE ID:** Not explicitly cited (Internal Ref: Reported via Immunefi)
- **CVSS Score:** Critical (Per Immunefi classification)
- **CWE:** CWE-248: Uncaught Exception / CWE-754: Improper Check for Unusual or Exceptional Conditions
## Affected Systems
- **Products:** Stacks Network Nodes
- **Versions:** Versions prior to the November 2023 patch
- **Configurations:** Nodes executing the Clarity Virtual Machine (VM)
## Vulnerability Description
The vulnerability exists within the Rust implementation of the Clarity Virtual Machine, the execution engine for the Stacks L2 blockchain. Specifically, the flaw relates to how the VM handles calls to functions like `ft-get-supply` when targeting a non-existent contract address.
In Rust, the `.expect()` method is often used to unwrap `Option` or `Result` types, causing the entire program to "panic" (crash) if the value is `None` or an `Err`. The Clarity VM used `.expect()` on a lookup that failed when a contract was absent. Because this exception was not gracefully handled within the VM's logic, a malicious transaction calling this function could trigger a node-wide crash, leading to a Denial of Service (DoS).
## Exploitation
- **Status:** PoC available (Reported by researcher "Catchme")
- **Complexity:** Low
- **Attack Vector:** Network (Remote via malicious smart contract transaction)
## Impact
- **Confidentiality:** None
- **Integrity:** None
- **Availability:** High (Can trigger a crash of Stacks nodes, halting block processing)
## Remediation
### Patches
- The Stacks team has issued a fix that replaces the `.expect()` call with proper error handling. The function now returns a handled error (using `Some`/`None` or `Result` patterns) when a contract is not found, allowing the VM to continue execution without crashing the node. Users should ensure they are running the latest version of the `stacks-node`.
### Workarounds
- No known functional workarounds other than updating node software to a patched version.
## Detection
- **Indicators of Compromise:** Unusual node crashes preceded by the processing of a transaction calling `ft-get-supply` or similar contract-state functions on non-existent addresses.
- **Detection Methods:** Monitoring node logs for Rust "panic" messages associated with the Clarity VM execution stack.
## References
- **Immunefi Article:** hxxps[://]medium[.]com/immunefi/stacks-dos-bugfix-review-dc0f2a75b276
- **Stacks Documentation:** hxxps[://]docs[.]stacks[.]co/clarity/overview
- **Stacks Official Site:** hxxps[://]www[.]stacks[.]co/