Skip to content

AugAssign evaluation order causing OOB write within the object in Vyper

Low severity GitHub Reviewed Published Feb 21, 2025 in vyperlang/vyper • Updated Feb 21, 2025

Package

pip vyper (pip)

Affected versions

<= 0.4.0

Patched versions

0.4.1

Description

Vyper handles AugAssign statements by first caching the target location to avoid double evaluation. However, in the case when target is an access to a DynArray and the rhs modifies the array, the cached target will evaluate first, and the bounds check will not be re-evaluated during the write portion of the statement. In other words, the following code

def poc():
    a: DynArray[uint256, 2] = [1, 2]
    a[1] += a.pop()

is equivalent to:

def poc():
    a: DynArray[uint256, 2] = [1, 2]
    a[1] += a[len(a) - 1]
    a.pop()

rather than:

def poc():
    a: DynArray[uint256, 2] = [1, 2]
    s: uint256 = a[1]
    t: uint256 = a.pop()
    a[1] = s + t  # reverts due to oob access

References

@charles-cooper charles-cooper published to vyperlang/vyper Feb 21, 2025
Published to the GitHub Advisory Database Feb 21, 2025
Reviewed Feb 21, 2025
Last updated Feb 21, 2025

Severity

Low

EPSS score

Exploit Prediction Scoring System (EPSS)

This score estimates the probability of this vulnerability being exploited within the next 30 days. Data provided by FIRST.
(12th percentile)

Weaknesses

No CWEs

CVE ID

CVE-2025-27105

GHSA ID

GHSA-4w26-8p97-f4jp

Source code

Loading Checking history
See something to contribute? Suggest improvements for this vulnerability.