GHSA-vg88-3v92-rjx2: Pip/vyper vulnerability
VVE-2020-0002 Earlier today, we received a responsible disclosure of a potential issue from @michwill (developer of @curvefi) for Vyper users who use return statements inside for loops of nested internal calls. Returning inside a for loop causes an invalid jump dest, reverting the transaction unnecessarily.
MWE: python @internal def baz(): for i in range(1): return # Stack underflow happens here
@internal def bar(): self.baz()
@external def foo(): self.bar()
Impact Impact is minor, it is unlikely a user would encounter this problem unless they were working with nested calls, and return statements inside calls. Even in that scenario, you would encounter a revert which should be noticeable with adequate testing. In limited circumstances, this could cause a DoS attack for public contracts under certain conditions.
Patches Fixed in https://github.com/vyperlang/vyper/pull/2110. Please upgrade to Vyper 0.2.3
Workarounds Not returning inside a for loop nested 2+ internal calls deep works as is: python @internal def baz(): for i in range(1): pass return # This works fine
@internal def bar(): self.baz()
@external def foo(): self.bar()
For more information If you have any questions or comments about this advisory: Chat with us in our gitter Open an issue in https://github.com/vyperlang/vyper Email us at security@vyperlang.org
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
pip/vyperto a version that resolves this vulnerability.Fixed in 0.2.3 - Upgrade
Upgrade
Vyperto a version that resolves this vulnerability.Fixed in 0.2.3
Event History
Frequently Asked Questions
Which contracts are most likely to be affected?
Contracts that use a return statement inside a for loop in an internal function reached through two or more nested internal calls are affected. The issue is unlikely to be encountered outside that call pattern.
What happens when the affected code path executes?
The generated code reaches an invalid jump destination and the transaction reverts unnecessarily due to a stack underflow. For public contracts, this can create a denial-of-service condition in limited circumstances.
What can be done if upgrading is not immediately possible?
Avoid returning from inside a for loop when the function is nested two or more internal calls deep. Moving the return outside the loop, such as allowing the loop to complete and returning afterward, avoids the issue.
What version includes the fix?
Upgrade to Vyper 0.2.3. The fix was made in the referenced pull request 2110.