You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hex string pre-parsing without considering position adjustments may result in mismatched offsets, and eventually cause compiler failure or type confusions.
Vulnerability Details
Vyper supports several custom syntax, and one of those are HexString, written in the x'01234' syntax, and treated as Bytes[] literal values. Since HexString is not legal python syntax, a pre-parsing pass must be made to "fix" the code before passing it to python.ast module for parsing. The fixing rule is relatively simple, it just strips the leading x, and track occurances in hex_string_locations.
classHexStringParser:
def__init__(self):
self.locations= []
self._current_x=Noneself._state=ParserState.NOT_RUNNINGdefconsume(self, token, result):
# prepare to check if the next token is a STRINGiftoken.type==NAMEandtoken.string=="x":
self._state=ParserState.RUNNINGself._current_x=tokenreturnTrueifself._state==ParserState.NOT_RUNNING:
returnFalseifself._state==ParserState.RUNNING:
current_x=self._current_xself._current_x=Noneself._state=ParserState.NOT_RUNNINGtoks= [current_x]
# drop the leading x token if the next token is a STRING to avoid a python# parser erroriftoken.type==STRING:
self.locations.append(current_x.start)
toks= [TokenInfo(STRING, token.string, current_x.start, token.end, token.line)]
result.extend(toks)
returnTrueresult.extend(toks)
returnFalse
Later when visiting ast nodes, the hex_string_locations are looked up and used to annotate ast nodes as Bytes type instead of Str type.
defvisit_Constant(self, node):
...
elifisinstance(node.value, str):
key= (node.lineno, node.col_offset)
ifkeyinself._pre_parser.hex_string_locations:
iflen(node.value) %2!=0:
raiseSyntaxException(
"Hex string must have an even number of characters",
self._source_code,
node.lineno,
node.col_offset,
)
node.ast_type="HexBytes"else:
node.ast_type="Str"
...
```pythonHowever, itisoverlookedthepre-parsingofHexStringmayGetplacedinalocationwheretherewerepriorcodeadjustmentsthatchanges"fixed"occurancelocationsHexStringconsumesleadingxandmaychange"fixed"codelocationsitself.
Thishasseveralimplications. Theimmediateconsequenceiscompilationfailure. Forexample, thefollowingcodefailstocompilewhileitshould```vypereventX:
a: Bytes[2]
@deploydef__init__():
logX(a=x"6161") #log changes offset of HexString, and the hex_string_locations tracked location is incorrect when visiting ast
Slightly more consequential, code that should fail to compile can now compile fine, and suffer a type confusion + incorrect value interpretation at the same time. For example, the following code shouldn't compile, but it does, and it incorrectly passes "6161" as second argument to FooBar.test instead of b"\x61\x61".
credits: @anatomist (Whitehat) for Attackathon | Ethereum Protocol
Hex string pre-parsing without considering position adjustments may result in mismatched offsets, and eventually cause compiler failure or type confusions.
Vulnerability Details
Vyper supports several custom syntax, and one of those are HexString, written in the x'01234' syntax, and treated as Bytes[] literal values. Since HexString is not legal python syntax, a pre-parsing pass must be made to "fix" the code before passing it to python.ast module for parsing. The fixing rule is relatively simple, it just strips the leading x, and track occurances in hex_string_locations.
Later when visiting ast nodes, the hex_string_locations are looked up and used to annotate ast nodes as Bytes type instead of Str type.
Slightly more consequential, code that should fail to compile can now compile fine, and suffer a type confusion + incorrect value interpretation at the same time. For example, the following code shouldn't compile, but it does, and it incorrectly passes "6161" as second argument to FooBar.test instead of b"\x61\x61".
Additionally, the state machine of HexString pre-parser is also slightly flawed, and allows code such as the following to compile.
Impact Details
The text was updated successfully, but these errors were encountered: