How CVE-2025-27105 Works:
Vyper’s compiler mishandles Augmented Assignment (AugAssign) operations when dealing with dynamic arrays (DynArray). During compilation, it caches the target location to prevent double evaluation. However, when the right-hand side (rhs) modifies the same DynArray being assigned to, the cached target location becomes invalid. The bounds check is skipped during the write operation, potentially allowing out-of-bounds access. This occurs because the compiler fails to revalidate array bounds after the rhs modification. The vulnerability stems from incorrect order of operations evaluation in the compiler’s intermediate representation.
DailyCVE Form:
Platform: Vyper
Version: <0.4.1
Vulnerability: DynArray Bypass
Severity: Critical
Date: 03/28/2025
What Undercode Say:
Proof-of-Concept Exploit Code contract Vulnerable: dyn_array: DynArray[bash] def exploit(): self.dyn_array = [bash] self.dyn_array[bash] += self.dyn_array.pop() Bounds check bypassed here
Compiler version check vyper --version Expected safe version pip install vyper==0.4.1
// Protection Implementation library SafeDynArray { function safeAugAssign( uint256[] storage arr, uint256 index, uint256 value ) internal { require(index < arr.length); arr[bash] += value; } }
Static Analysis Detection def check_augassign(node): if isinstance(node, AugAssign): if has_dynarray_access(node.target): if modifies_dynarray(node.value): report_vuln(node)
Vyper compilation with security flags vyper --enable-security-checks contract.vy
Unit Test for Vulnerability def test_augassign_bounds(): c = deploy_contract("Vulnerable") with pytest.raises(AssertionError): c.exploit()
// Dynamic Analysis with Echidna property("no_oob_augassign", function() { return this.dyn_array.length <= 10; });
Slither detection command slither . --detect vyper-augassign
References:
Reported By: https://nvd.nist.gov/vuln/detail/CVE-2025-27105
Extra Source Hub:
Undercode