Medium Risk
https://github.com/vyperlang/vyper/blob/0b740280c1e3c5528a20d47b29831948ddcc6d83/vyper/cli/vyper_compile.py#L279-L287
https://github.com/vyperlang/vyper/blob/0b740280c1e3c5528a20d47b29831948ddcc6d83/vyper/cli/vyper_serve.py#L85-L97
In vyper's version 0.3.10 vyper-serve is unable to compile bytecode HTTP requests due to changes made on cli/vyper_compile.py's compile_files function parameters definitions as shown below.
This made unable to use vyper-serve to compile contracts via HTTP
On vyper's 0.3.9 version the cli/vyper_compile.py's compiles_files function declaration is the following:
# cli/vyper_compile.py version 0.3.9
def compile_files(
input_files: Iterable[str],
output_formats: OutputFormats,
root_folder: str = ".",
show_gas_estimates: bool = False,
evm_version: str = DEFAULT_EVM_VERSION,
no_optimize: bool = False,
storage_layout: Iterable[str] = None,
no_bytecode_metadata: bool = False,
) -> OrderedDict:
# ...
However, vyper's cli/vyper_compile.py's compile_files 0.3.10rc3 version removes EVM_VERSION_FIELD paramater:
# cli/vyper_compile.py version 0.3.10rc3
def compile_files(
input_files: Iterable[str],
output_formats: OutputFormats,
root_folder: str = ".",
show_gas_estimates: bool = False,
settings: Optional[Settings] = None,
storage_layout: Optional[Iterable[str]] = None,
no_bytecode_metadata: bool = False,
) -> OrderedDict:
# ...
compile_files is called on vyper_serve.py with evm_version as an argument:
# vyper_serve.py
def _compile(self, data):
code = data.get("code")
# ...
try:
code = data["code"]
out_dict = vyper.compile_codes(
{"": code},
list(vyper.compiler.OUTPUT_FORMATS.keys()),
evm_version=data.get("evm_version", DEFAULT_EVM_VERSION), # <<== EVM_VERSION
)[""]
So, now the arguments passed to cli/vyper_compile.py aren't valid and vyper_serve.py is not able to produce bytecode anymore.
An easy way to comprobe this vulnerability is installing both versions (0.3.9 and 0.3.10rc3) as shown next:
cd /tmp/
virtualenv vyper_venv9
source vyper_venv9/bin/activate
pip install vyper==0.3.9
vyper --version
Start vyper-serve:
vyper-serve
Using an http request compile a contract:
curl -X POST localhost:8000/compile -H "Content-Type: application/json" -d '{"code": "\n\n# @version ^0.3.7\n\n@external\ndef foo():\n pass\n"}'
Observe the successful response:
{
"ast_dict": {
"contract_name": "",
"ast": {
"ast_type": "Module",
"src": "0:50:0",
"end_col_offset": 8,
"doc_string": null,
"node_id": 0,
"lineno": 1,
"body": [
{
"args": {
"args": ...
}
...
}
Stop the vyper-serve using Ctrl-C
cd /tmp/
virtualenv vyper_venv10
source vyper_venv10/bin/activate
pip install vyper==0.3.10rc3
vyper --version
Start vyper-serve:
vyper-serve
Using an http request try to compile the same contract:
curl -X POST localhost:8000/compile -H "Content-Type: application/json" -d '{"code": "\n\n# @version ^0.3.7\n\n@external\ndef foo():\n pass\n"}'
Observe the response:
curl: (52) Empty reply from server
And the stack trace from vyper-serve console:
----------------------------------------
Exception occurred during processing of request from ('127.0.0.1', 44642)
Traceback (most recent call last):
File "/usr/lib/python3.10/socketserver.py", line 683, in process_request_thread
self.finish_request(request, client_address)
File "/usr/lib/python3.10/socketserver.py", line 360, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/usr/lib/python3.10/socketserver.py", line 747, in __init__
self.handle()
File "/usr/lib/python3.10/http/server.py", line 433, in handle
self.handle_one_request()
File "/usr/lib/python3.10/http/server.py", line 421, in handle_one_request
method()
File "/tmp/vyper_venv10/lib/python3.10/site-packages/vyper/cli/vyper_serve.py", line 72, in do_POST
response, status_code = self._compile(data)
File "/tmp/vyper_venv10/lib/python3.10/site-packages/vyper/cli/vyper_serve.py", line 94, in _compile
out_dict = vyper.compile_codes(
TypeError: compile_codes() got an unexpected keyword argument 'evm_version'
----------------------------------------
This is due to the change made on compile_files explained above.
Users can't use vyper-serve to compile bytecode leading to a loss of functionality / denial of service
Impact: Low
Likehood: High
CVSS Medium - 4.3
AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:L
Manual analysis
Change cli/vyper_compile.py compile_files function definition to take into account the evm_version argument from vyper_serve.py@_compile
function (for example in version 0.3.9)